Menu

#134 In double-page, let CTRL+switching page always forward one page

Git
open
nobody
None
5
2024-02-22
2024-02-01
aasa
No

According to wiki:

When changing pages in double-page mode, MComix will automatically forward or backward two pages at once. To forward only one page, hold the CTRL key while switching pages.

But actually, only CTRL + PageUp/PageDown forward one page.
It would be more convenient if this behavior is extended to any way of switching pages.

For example, if there is nothing to scroll, Arrow keys can forward/backward pages.
However in double-page mode, CTRL + Arrow keys does not forward any page. It had better forward one page in this case.

Discussion

  • Ark

    Ark - 2024-02-02

    @aasa: Thank you for pointing out an inconsistency in the wiki. It certainly needs an update.

    Apart from the wiki, the main issue here is how the proposed change fits into MComix the way it currently works. I am currently thinking about it.

     
  • Ark

    Ark - 2024-02-04

    The way I understand it, it will be quite cumbersome to address this issue directly because, given the way MComix currently works, for each page-related navigation action, we would need to ensure that there is a similar action incorporating a single-page variant. Also, modifying shortcuts would become more complicated for the user, and there would be even more possible shortcuts to be wasted, more shortcuts to memorize and more to choose from whenever navigating.

    Therefore, I propose something completely different that, as a by-product, hopefully also addresses the issue at hand by turning it into a non-issue.

    Background: Currently, there are two distinct actions available, dubbed "Next page (always one page)" and "Previous page (always one page)", respectively, in the preferences window, that move everything either forward or backwards, respectively, by exactly one page. Or at least it sounds like it is supposed to do that because, as I just noticed, it only works this way under some but not all circumstances.

    So, there is already a bug that needs fixing. Or, more precisely, I propose a completely different approach that "fixes" that bug by replacing the two actions mentioned above with a new action that roughly works as follows:

    1. Determine the current page. (Smart scrolling already implicitly does this at some point, so that part is easy.)
    2. Stick to that page, but try to rearrange the surrounding pages by shifting everything by one page if applicable.

    There are some symmetries and constraints to consider. The following come to mind:

    • Going backwards (i.e., when being closer to the previous page than the next page) should behave like going forward but mirrored. Ideally, there is no movement at all.
    • Similar symmetry properties must hold for manga mode.
    • The current page now should stay the current page afterwards.
    • If the current page will always be displayed as a single page for other reasons (for example, having landscape orientation or being a title page), there is nothing to rearrange because it will be displayed as a single page anyway. Thus, if the action is applied in this case, nothing should happen.
    • The action should be its own inverse. Thus, applying the action twice in succession should result in no change.
    • Corollarily, in single-page mode, this action is, effectively, a no-op, so it could just as well be disabled.
    • To simplify reasoning, at either end of a book, that is, before the first page and after the last page, we assume there is a page of infinite size in all directions.

    This leaves us with the two non-trivial cases below. Different letters denote different pages. The same letter three times in a row denotes a page that will always be displayed as a single page for other reasons (for example, landscape orientation). The pages currently being displayed are enclosed by [ ], and in case of an actual double-page layout, the individual page considered the current one is additionally enclosed by < >. The new arrangement and new current page after the action is applied is shown at either side of the respective arrow.

    (a)   [ A  <B>]CCC    <--->     A [<B>]CCC 
    (b)   [ A  <B>] C     <--->     A [<B>  C] 
    

    A suitable algorithm can be summarized as follows: Out of all the pages currently being displayed, remove one from the "far" end (i.e., far away from the current page), if possible, and then add a different page at the "near" end, if possible (i.e, if it fits). If only a single page with portrait orientation is being displayed, the "near" end is whichever is possible, as there will only be at most one, given all the constraints.

    The main advantages of the action proposed here:

    • Direction agnostic. No need to decide between directions, thus simpler to use, and probably also resulting in simpler code. Also, fewer actions available, hence, fewer possible shortcuts wasted and fewer shortcuts to memorize.
    • No unnecessary page flips involved. Since page flipping is minimized, it feels similar to switching between manga mode and western mode because the reader can correct the double-page layout without being forced to also flip pages.
    • (Probably) more natural. When only a single page is being displayed, the user will probably be unable to decide whether to go forward by a single page or a double page anyway. Thus, there is no point in offering her that many different ways to flip (single) pages.
    • More consistent. This is actually only a side effect because we would need to make the double-page flipping action more consistent. (See below.)

    In short: If the current double-page layout looks not quite right, apply this new action. Problem solved! No need for special keys, distinct navigation actions or anything like that.

    Caveat: A potential flaw is that the algorithm sketched out above will run into issues if there are more than two pages. Given a sufficiently long but finite sequence of pages, it will get closer to the center of the sequence and then get stuck there. The question is whether this potential flaw is relevant, considering that …

    • … we do not yet support more than two pages at once.
    • … supporting more than two pages at once is probably better implemented using an infinite layout anyway, where such action would probably be disabled.
    • … in the vast majority of cases, we have to deal with either single-page or double-page layouts, so a special action is probably justified.

    Caveat: Currently, the proposed algorithm is biased under various circumstances. Most notably, if a double page is displayed in "Best fit mode", always the left (or right) page will be considered the current one (depending on manga mode). Thus, repeatedly applying this action might result in moving backwards instead of staying on the same page. That bias is a different issue and, therefore, cannot and should not be addressed here. (For a ticket closer to that issue, see [bugs:#123].)

    The good news is that comics are usually read front to back. Thus, if the reader notices that the double-page layout is wrong right when starting reading a double page, and applies the new action right then, it should do just the right thing.

    Caveat: Currently, applying the proposed action might result in implicitly moving the viewport content around, especially in manga mode. (Incidentally, when in manga mode, switching back and forth between single page mode and double page mode exhibits the same bug.) That as well is a different issue and, therefore, cannot and should not be addressed here.

    Caveat: For the new action to work consistently, we need to make sure that "normal" page flips in double page mode work as follows:

    (a)   [AAA]BBB             --->    AAA[BBB]        
    (b)   [AAA] B  CCC         --->    AAA[ B ]CCC     
    (c)   [AAA] B   C          --->    AAA[ B   C ]    
    (d)   [ A ]BBB             --->     A [BBB]        
    (e)   [ A ] B  CCC         --->     A [ B ]CCC     
    (f)   [ A ] B   C          --->     A [ B   C ]    
    (g)   [ A   B ]CCC         --->     A   B [CCC]    
    (h)   [ A   B ] C  DDD     --->     A   B [ C ]DDD 
    (i)   [ A   B ] C   D      --->     A   B [ C   D ]
    

    A suitable algorithm can be summarized as follows: Every page after a (double) page flip is different from the pages previously displayed, and as many pages as possible must be displayed at once.

    From what I have observed, (double) page flipping in double page mode currently works a bit differently.

    Back to the main issue.

    I propose Shift+D as the default key binding for the new action. Also, it should have a menu item in the "Go" menu. What I am not sure about is how to name the action:

    • "Shift by one page" and "Move by one page" raise the question about the direction, therefore unnecessarily confusing.
    • "Fix double page" sounds like there is something inherently broken. Also, it is somewhat ambiguous in English.
    • Something like "Rearrange double page" might sound just right.

    Any comments?

    @aasa: Does it sound like a way to address your issue?

     

    Related

    Bugs: #123

  • aasa

    aasa - 2024-02-06

    Does it sound like a way to address your issue?

    Yes, your proposal surely will solve this issue.

    My other two cents come from how I used mcomix or how I expected a comic reader to work. (I have no knowledge of mcomix codebase)

    Caveat: A potential flaw is that the algorithm sketched out above will run into issues if there are more than two pages. Given a sufficiently long but finite sequence of pages, it will get closer to the center of the sequence and then get stuck there.

    It shouldn't stuck since current pages are changing -- at least one page is removed.

    Determine the current page. (Smart scrolling already implicitly does this at some point, so that part is easy.)

    IMHO "current page" does not make sense, only "current pages" and "current view port" are the actual navigation state.

    A suitable algorithm can be summarized as follows: Out of all the pages currently being displayed, remove one from the "far" end (i.e., far away from the current page), if possible, and then add a different page at the "near" end, if possible (i.e, if it fits). If only a single page with portrait orientation is being displayed, the "near" end is whichever is possible, as there will only be at most one, given all the constraints.

    "Rearrange double page": (slightly different from your algorithm)

    • navigation: remove one from the previous "far" end, and begin at the new "far" end, ensure at most N(=2) pages. then re-layout.
    • layout (common): layout may remove unsuitable pages from "near" end.
    • resolution :
      End-of-folder fallback: default or NOP (remain current navigation state)
      Result test - no new page fallback: "normal page flip" or NOP (remain current navigation state)

    (Here the fallback choices are a matter of taste - should the new operation try to flip or try to stay?)

    For comparison, "normal page flip" (same as your algorithm)

    • navigation: begin at the next page of previous "near" end, ensure at most N(=2) pages. then re-layout.
    • layout (common): layout may remove unsuitable pages from "near" end.
    • resolution:
      End-of-folder fallback: default (NOP or navigate next folder)
      (Result test - no new page: impossible to happen)
     

    Last edit: aasa 2024-02-06
  • FeRD

    FeRD - 2024-02-19

    I didn't follow a LOT of that (and I'm not even going to try), because it feels like you're WAAAAY overthinking it.

    There's nothing to rearrange, there's nothing to mirror.

    Single-page advance means:

    1. Say you're in double-page, non-manga mode and you're viewing a spread of pages [4, 5]
    2. Normally, PgDn, or , or whatever other advancement methods would take you from [4, 5] to [6, 7] (ignoring, for the moment, the existence of automatic single pages, etc.)
    3. Activating single-page advance would instead take you from [4. 5] to [5, 6].
    4. Similarly, activating single-page reverse would take you from [4, 5] to [3, 4].

    The same thing can also be achieved by left-clicking on page 5 (for advance) or page 3 (for reverse) in the thumbnails, since both of those actions will create a spread with a page on the left that would otherwise be a right-hand spread page.

    (That can also happen naturally, of course. If you're in double-page mode and end up at an odd-numbered single page, then backing up will flip through a series of [odd, even] spreads that were previously [even, odd] the first time you went through them in the forward direction.)

    But the single-page advance/reverse shouldn't be thought of as a navigation action at all. Rather, it's a layout-shifting operation that doesn't care about the "current" page because it operates on the entire two-page spread.

    When only one page is displayed, either because 2-page mode is deactivated or because of an automatic one-page layout, then a single-page forward shift will always be the same as normal 2-page advance: it puts the very next page on the LHS of the layout. (Single-page backwards shifting off of a single-page display in 2-page mode, however, can still have different effect than the normal 2-page reverse navigation. It should always put the immediately-previous page on the left side of the layout, whereas a normal 2-page reverse navigation would place it on the RHS.)

    Why?

    There are two reasons the user may need to perform layout shifts, leading to three scenarios where single-page shifting is useful:

    1. "Open With" actions in MComix only operate on the first page in a 2-page spread. (I suspect they always operate on the left page, but I haven't verified that for Manga mode as I don't use it.) So, if you have some "Open With" action defined, and you want to perform that action on the right-hand page of a 2-page spread, you need to shift the layout forward by 1 page to put the target page on the left side.

    2. The other reason is that pagination sometimes gets out of sync with the content's layout. If you have a comic that lacks joined double-page images for 2-page spreads (any PDF comic I've ever seen, for starters, but also many older CBR/CBZ archives), then you may be reading it and realize...

      1. The right-hand page of the current view is actually the left side of a 2-page spread (need to shift the layout forward 1 page)
      2. Or, the left-hand page is the right side of a 2-page spread (need to shift 1 page backward)

    The latter two scenarios have no notion of a "current" page (they're concerned with the entire spread; both pages are "current"), and they can't possibly be direction-agnostic because shifting a layout requires a direction in which to shift it. In the former scenario, I suppose what they indicate is that the left-hand page is always the "current" page, from the perspective of "Open With" actions.

    Existing functionality

    The current "Next page (always one page)" and "Previous page (always one page)" actions operate as I've described above, and work well to cover all three scenarios. They do the right thing in all situations I've encountered. What exactly was the nature of the buggy behavior you mentioned in the current single-page shifting actions. @aaku?

    Also, in terms of the OP's request for additional shortcuts, the user certainly has the option to bind the existing actions to Ctrl-modified versions of additional navigation keyboard shortcuts, if they're so inclined.

    I just experimentally added Ctrl+ and Ctrl+ bindings for single-page forward/reverse shifting (respectively) by going into the Shortcuts tab of the Preferences, double-clicking the still-empty "Key 4" slot in each action's row, then typing the shortcut I wanted to assign.

    Implementing the behavior described in the wiki completely would be impossible, because scroll navigation is one way of switching pages, and Ctrl+scroll is already a well-known binding for zoom in/out so we shouldn't mess with that. (IMHO using scroll movements to perform single-page layout shifts doesn't make sense anyway. Scrolling is fundamentally an act of navigation, and like I said layout shifts aren't really navigation at all. ...Despite being listed in that category in the Shortcuts prefs.)

     
  • Ark

    Ark - 2024-02-22

    Thank you for your feedback, @aasa and @ferd617, it is quite helpful.

    It seems that I need to clarify some terms I used, as they really are ambiguous in this context. There are at least two different notions of current.

    The first one is current as in "currently selected page". The thumbnailer indicates very well which page is the current one according to this first notion. It is (currently) also the one that is used by "Open with", albeit not explicitly indicated as such in the UI. For what we are discussing here, this notion is not really relevant. (If you want to discuss it anyway, please open a new ticket.)

    The second one is current as in "page the reader is currently focusing on". Let me add a bit of history here. Years ago, the smart scrolling feature used to use a hidden state variable to keep track of where the reader left off. However, it was awkward to use if you happened to mix it with other means of scrolling, like the cursor keys or simply panning using the mouse. For example, if you started reading at the beginning of the first page but then used the mouse to manually move the viewport to the second page, and then asked the smart scolling feature to continue, you actually ended up in the middle of the first page again! Why? Because it did not catch up with what you did in the meantime, it did not understand that you already moved to the second page. So, in order to fix that, we removed that hidden internal state and replaced it with that second notion of current. Now, that smart scrolling feature picks up where the reader probably left off, irrespective of how she ended up there.

    By extension (and I am thinking that for quite a while now), any action that does not explicitly say "user panned to a different page or part of a page", like zooming in or out, or changing the size of the main window, should keep the main viewport at where the reader is probably currently focusing on. That should, of course, also include actions like switching between manga and western mode, and switching between double-page mode and single-page mode, and, as in the case we are discussing here, shifting around pages to fix a double-page misarrangement.

    So, the second notion is the one I have in mind when I say "current page" in this context. I am sorry that I did not clarify it earlier.

    It shouldn't stuck since current pages are changing -- at least one page is removed.

    No need to worry. In our particular case (double-page mode with two pages in the viewport), it will oscillate between two arrangements, and at least one of them will be the correct one.

    For the rest of your post, @aasa, I have to admit that I do not really understand what you want to say. Please try to rephrase your ideas if you do not see them properly discussed here and still feel the need to discuss them.

    But the single-page advance/reverse shouldn't be thought of as a navigation action at all. Rather, it's a layout-shifting operation that doesn't care about the "current" page because it operates on the entire two-page spread.

    This is my understanding as well, and it is also one of the many reasons why I want to change it in the first place. One might think of single-page movements as layout shifting, but currently, they are navigation actions, not only in name but in function as well: If you use them often enough, they will eventually navigate you through the entire book.

    However, the new action I have proposed a few posts earlier is not a navigation action, neither in name nor in function. It will not get you through the book in any direction, and it cannot tell the difference between forwards and backwards, which is why I consider it direction agnostic. For it to work, however, it needs the second notion of "current" so cases like

          …  A [ B   C ] D …
    

    are well-defined with respect to what to display to the user after the action is applied. Apart from that, as you said, there is no need to care about the "current" page. (For an in-depth-discussion, see my post above.) So, strictly speaking, that new action should go to the "View" menu instead of the "Go" menu. Thank you for hinting at this flaw in my respective post above.

    Just in case you still think that the proposed action has any preference with respect to direction, consider the diagram above again. You might think that A points towards the beginning of the book and D points towards its end, but what if D were actually closer to the beginning and A were closer to the end? As it turns out, the proposed action would not be influenced by such a change but instead would always do the same thing.

    What exactly was the nature of the buggy behavior you mentioned in the current single-page shifting actions.

    Please have a look at the two archives attached to this post (wrapped in a tar file, please extract them first) and use manga mode and western mode accordingly. Without loss of generality, the following observations can be made in manga mode:

    • (A) From page 3 to 4, it does not matter whether you choose to go forward by only one page or not. Instead, the single "L" page that is supposed to show up as the left page (or as a single page) will be displayed together with the following "R" page (in the wrong order).
    • (B) However, from page 14 to 13, it does matter whether you choose to go backwards by only one page or not.
    • (C) If the double-page layout is corrected, going forward from page 11 to 13 results in page 13 being displayed as a single page.
    • (D) However, if the double-page layout is corrected, going backwards from page 5 to 4 will yield the same result as in (A), even if you choose to go backwards by only one page.
    • (E) The scenario in (D) results in a layout that used to be correct to become incorrect again.

    I consider (A), (D) and (E) bugs. Also, (A) and (D) together result in page 4 always being displayed with the other (wrong) page together, never as a single page. I consider that yet another bug. All in all, the user is given different navigation actions to choose from, some of which are supposed to fix layouting issues along the way, but they work inconsistently or do not seem to make a difference despite being presented as different from their "normal" counterparts.

    The new action I propose, on the other hand, will only be effectively available if using it will make a difference in the first place. Also, once the layout is corrected, it will stick to it. In other words, using it while between page 4 and 13 (inclusive) with the wrong layout

    • will always result in the correct layout even in corner cases and
    • continuing navigating between these pages will not implicitly result in a layout change.

    Visualized, after double-page rearrangement, pages 4 to 13 (inclusive) will then be laid out as follows:

    (4)         [ L1  ]
    (5-6)    [ L2    R2  ]
    (7-8)    [ L3    R3  ]
    (9-10)   [ L4    R4  ]
    (11-12)  [ L5    R5  ]
    (13)        [ R6  ]
    

    I just experimentally added Ctrl+ and Ctrl+ bindings for single-page forward/reverse shifting (respectively) by going into the Shortcuts tab of the Preferences, double-clicking the still-empty "Key 4" slot in each action's row, then typing the shortcut I wanted to assign.

    It works in that particular case, but unfortunately, there are many more actions that explicitly or implicitly navigate the reader to a different page. If we tried to be consistent in that way, we would end up with the following actions:

    (a)    scroll left
    (b)    scroll left (single page)
    (c)    scroll right
    (d)    scroll right (single page)
    (e)    scroll up
    (f)    scroll up (single page)
    (g)    scroll down
    (h)    scroll down (single page)
    (i)    smart scrolling forward
    (j)    smart scrolling forward (single page)
    (k)    smart scrolling backwards
    (l)    smart scrolling backwards (single page)
    (m)    go to next page
    (n)(*) go to next page (single page)
    (o)    go to next page (dynamic)
    (p)    go to next page (dynamic) (single page)
    (q)    go to previous page
    (r)(*) go to previous page (single page)
    (s)    go to previous page (dynamic)
    (t)    go to previous page (dynamic) (single page)
    (u)    go forward 10 pages
    (v)    go forward 10 pages (single page)
    (w)    go forward 10 pages (dynamic)
    (x)    go forward 10 pages (dynamic) (single page)
    (y)    go back 10 pages
    (z)    go back 10 pages (single page)
    (aa)   go back 10 pages (dynamic)
    (ab)   go back 10 pages (dynamic) (single page)
    

    (The "go forward/back 10 pages (dynamic)" actions are not implemented yet, but that is an unrelated issue.)

    I think that are far too many shortcuts to memorize and to choose from for the user. Also, the fewer actions we have to implement and maintain, the better.

    The new action I proposed earlier, on the other hand, would replace all of the actions listed above that are marked with "(single page)" with one single action. Even the ones currently available (marked with an asterisk) could (and probably also should) be removed because they would be unnecessary.

     

Log in to post a comment.

MongoDB Logo MongoDB