[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: UPDATE: command: shift_edge



Hi Tylo,

On Thu, Dec 27, 2012 at 09:54:17PM -0800, Tyler Thomas Hart wrote:
> When focus_follows_shift=0, and shift command is used, would it be
> true that (effectively): the INDEX within the frame of the focused
> window before shifting, is equal to the index of the focused window
> after shifting? (Minus 1, of course, if the window is shifted out of
> the frame in the down or right directions?)

Yes, that's true.

> If so, this should also be the behavior of shift_edge, eg. the focused
> window index AND frame should be the same before and after an edge
> shift.

Yes, exactly.

> >   - Solution A: manually shift the window to the edge instead of
> >     calling the shift command. This also would cause that locking
> >     and unlocking the monitors isn't needed anymore in shift_edge.

That's actually the only implementation I'd accept, because that's
exactly what the documentation describes. All other approaches seem to
be incorrect or hacky:

>  1: A way to produce this behavior would be to increment an integer
>     n each time shift_command() returns success, then call focus_edge
>     in the opposite direction n times (or n+/-1, I'm having trouble
>     visualizing it). This would result in the least amount of code, I
>     think, but wouldn't be most efficient.

This behaviour is incorrect. (And it is still as unefficient as the
current implementation). Consider a frame with the grid layout and 5
clients in it, focus=2:

    +---+---+---+
    | A | B |*C |
    +---+---+---+
    | D |   E   |
    +---+---+---+

After shifting the focused C down and focusing up again, this leads to B
to be focused:

    +---+---+---+
    | A |*B | E |
    +---+---+---+
    | D |   C   |
    +---+---+---+

>  2: An alternative option would to be to calculate the frame/window
>     that would receive focus if focus_follows_shift=0 BEFORE
>     performing the shift() loop, perform the loop, the set focus back
>     to the frame/window. This would result in more code, but would be
>     more efficient.

This sounds hacky but it's not far from the clean solution: Shift the
window till the edge without changing the focus at all.

>  3: [...] (but it'd have undefined behavior when the user DOES
>     do the steps that would reproduce the bug).

Sounds strange.

> A clean way to do 1&2 without this is to separate the shifting routine
> and the frame_move_window_command, and pass the new standalone shift
> function the focus_follows_shift setting; frame_move_window_command
> could pass the global, while edge_shift always passes 1.

Or provide a shift-function that doesn't change the focus at all.

>  4: (About Thorsten's suggestion A) note that if we did separate
>     frame_move_window from the shift routine, the routine would be
>     NEARLY the same as rewriting shift_edge: we would still have to
>     ascend the tree to get to the edge-most frame.
>     The only difference is we would only have to descend once if we
>     rewrote it (at the last frame) versus descending at each frame.
>     This would result in more code, but would be MOST efficient.  But
>     its also not modular and therefore (among other aesthetic
>     reasons), IMO, elegant.
> 
>  5: We could, of course, ignore focus_follows_shift for just shift_edge command.
>     This is equivelent to the quickfix Thorsten implemented.
>     Not very nice to the user IMO, but always an option.
> 
> My vote would be method #1 + the seperation.
> Method #1 because I think it would rarely result in magnitudes more
> clock cycles than #2, its less code, and it's a rare situation anyway
> I'm not much for #4 if you couldn't tell :), but it is of course, a
> very valid option, if the weighted majority picks it.

Constant count clock cycles don't matter for me (except it changes the
theoretical complexity, e.g. from linear vs. quadratic). The bottleneck
is X11-IO.

> If the setting focus_follows_shift ISNT kept, we just have to decide
> between three things: whether we should separate the shift routine
> from the frame_move_window_command (as per note about #1&#2), continue
> calling frame_move_window_command with fake args, or rewrite
> focus_edge.

Yes, that's the question: B vs C.

> My vote would be the separation, as per my reasons about #4 above, and
> because it would make locking/unlocking the monitors unnecessary (as
> per my note about #1|#2.

OK.

Regards,
Thorsten