Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dispatcher movewindoworgroup to move into/out-of an unlocked group #2851

Closed
spikespaz opened this issue Jul 31, 2023 · 25 comments
Closed

Dispatcher movewindoworgroup to move into/out-of an unlocked group #2851

spikespaz opened this issue Jul 31, 2023 · 25 comments
Labels
enhancement New feature or request

Comments

@spikespaz
Copy link
Contributor

spikespaz commented Jul 31, 2023

Description

I would like a dispatcher to move windows into/out-of groups when the window is not in a locked group.

This effectively combines moveintogroup and moveoutofgroup, but allows using the same bind for both dispatchers. This would work because groups can be locked, in which case this dispatcher would move the group rather than a window.

bindm = mouse:276, movewindoworgroup
bind = SUPER_SHIFT, left, movewindoworgroup, l
bind = SUPER_SHIFT, right, movewindoworgroup, r
bind = SUPER_SHIFT, up, movewindoworgroup, u
bind = SUPER_SHIFT, down, movewindoworgroup, d

Maybe name it one of these:

  • movewindowmaybegroup
  • moveunlockedwindow (Makes less sense when a window outside of a group)
  • movewindoworgroup (I like this one best)
@spikespaz spikespaz added the enhancement New feature or request label Jul 31, 2023
@spikespaz spikespaz changed the title bindm to movewindow, option to move window (not group) when group is unlocked Dispatcher movesinglewindow to move into/out-of an unlocked group with a bindm Jul 31, 2023
@spikespaz spikespaz changed the title Dispatcher movesinglewindow to move into/out-of an unlocked group with a bindm Dispatcher movesinglewindow to move into/out-of an unlocked group Jul 31, 2023
@spikespaz spikespaz changed the title Dispatcher movesinglewindow to move into/out-of an unlocked group Dispatcher movewindoworgroup to move into/out-of an unlocked group Jul 31, 2023
@spikespaz
Copy link
Contributor Author

This does not work because all dispatchers are triggered, and they conflict.

bindm = , mouse:276, moveintogroup
bindm = , mouse:276, moveoutofgroup
bindm = , mouse:276, movewindow

Is there some magical order in which these work?

@spikespaz
Copy link
Contributor Author

I just realized that when using bindm the movewindow dispatcher can behave like moveintogroup (drop a window into a group), but when used with regular bind a window will swap positions with the entire group instead of joining it.

@memchr
Copy link
Contributor

memchr commented Aug 16, 2023

This does not work because all dispatchers are triggered, and they conflict.

bindm = , mouse:276, moveintogroup
bindm = , mouse:276, moveoutofgroup
bindm = , mouse:276, movewindow

Is there some magical order in which these work?

Doesn't CKeybindManager::mouse only support movewindow' and resizewindow'?

if (ARGS[0] == "movewindow") {

} else if (ARGS[0] == "resizewindow") {

@memchr
Copy link
Contributor

memchr commented Aug 16, 2023

because groups can be locked, in which case this dispatcher would move the group rather than a window

m_sGroupData.locked is currently used to prevent new windows from being added to the group, rather than to prevent dispatchers (esp. moveIntoGroup) from modifying the group, as the default behaviour is not to check this flag (misc:moveintogroup_lock_check).

move the group

Does this mean moving the container like what swapActive or moveActiveTo does?


If the default behaviour of dispatchers ignoring m_sGroupData.locked is to be retained, what do you think about moving the active window outside its group in another direction when the dispatcher is called on a group, and behaving like moveintogroup when called on a window?

active is window/group direction is behaviour
group group behave like moveIntoGroup
group window/null behave like moveOutOfGroup
window group behave like moveIntoGroup
window window/null do nothing
floating group behave like moveOutOfGroup
floating window do nothing

@spikespaz
Copy link
Contributor Author

spikespaz commented Aug 16, 2023

Doesn't CKeybindManager::mouse only support movewindow' and resizewindow'?

It's been a while so I'm not sure how clearly I remember, but I'm quite sure having those three dispatchers made it behave really weirdly. Like it would pick up the window and put it back, for an example of the behavior of one particular order.

I'm trying to remember if that was my testing with the keyboard but I don't think so, because I remember walking away and forgetting about it, then coming back and thinking "what the heck is happening to my mouse 5".

So I'm not sure what that means, but regardless of how the code is written, I'm almost positive those three lines caused funky things.

@spikespaz
Copy link
Contributor Author

spikespaz commented Aug 16, 2023

≥ Does this mean moving the container like what swapActive or moveActiveTo does?

Yes for the former, but what ismoveactiveto again? Not looking at the wiki ATM.

moving the active window outside its group in another direction when the dispatcher is called on a group, and behaving like moveintogroup when called on a window

That sounds exactly like the behavior I'm after.

Your first table row doesn't make sense to me. Oh, I get it. First cell I need to think "window in group".

Row number 4: active is window, direction is window --do nothing. I don't think that's what I want, that should behave as movewindow or swapactive, unless I'm misunderstanding again.

the dispatcher

I assume you're talking about a new one, movewindoworgroup?

@memchr
Copy link
Contributor

memchr commented Aug 16, 2023

I assume you're talking about a new one, movewindoworgroup?

Yes, by the dispatcher I mean the hypothetical new dispatcher who will move the window or group.

Row number 4: active is window, direction is window --do nothing. I don't think that's what I want, that should behave as movewindow or swapactive, unless I'm misunderstanding again.

Having the new dispatcher swap window position movewindow or swapactive would be inconsistent with how the dispatcher it is supposed to combine works.

The existing dispatchers, namely moveintogroup and moveoutofgroup, operate on at least one group by adding or removing window in the group(s). In addition, these dispatchers typically increase or decrease the total number of containers in a workspace, but never swap containers.

This inconsistent behaviour could confuse users who are familiar with the current functionality and defaults.

Therefore, in my opinion, the new dispatcher should not swap container positions by default when both the active and target containers are windows. Instead, it would be better to provide an option to enable container swapping via a configuration flag, for those who want that behavior.

if (!PWINDOWINDIR || !PWINDOWINDIR->m_sGroupData.pNextWindow)
return;

if (!PWINDOW || !PWINDOW->m_sGroupData.pNextWindow)
return;

@memchr
Copy link
Contributor

memchr commented Aug 16, 2023

That sounds exactly like the behavior I'm after

Please note that this hypothetical behaviour ignores m_sGroupData.locked and does not swap group containers like movewindow does, in the same light of maintaining consistency, with the additional reason being that moveintogroup also ignores m_sGroupData.locked by default.

@memchr
Copy link
Contributor

memchr commented Aug 17, 2023

The current onWindowCreatedTiling() methods do not currently allow you to move the window out of a group in a specific direction from any built-in layout. It only respects the mouse position or force_split for dwindle.

@spikespaz
Copy link
Contributor Author

spikespaz commented Aug 17, 2023

My idea for the movewindoworgroup was for it to always have a reasonable behavior (always move) if at all possible.

Having the new dispatcher swap window position movewindow or swapactive would be inconsistent with how the dispatcher it is supposed to combine works.

Two thoughts on this. This is inherently rather complicated, and therefore just calling the functions of other dispatchers or combining them would not be appropriate. For brevity, I use terms like AND and THEN below to describe behaviors; however this is not actually what I think should happen. We need unique code.

This inconsistent behaviour could confuse users who are familiar with the current functionality and defaults.

Because you wish to remain "consistent" with how these work (and this consistency does not adhere to my ideal functionality) I have introduced two behavioral "modes", A and B. Behavior A is essentially "this dispatcher is generic and dispatches other behaviors, and Behavior B is "move the window if it is possible".

Maybe instead of two behaviors (movewindoworgroup,a and movewindoworgroup,b) we should add another dispatcher for Behavior B, perhaps moveorswapwindoworgroup.

Active Tile Direction/Target Tile Behavior A Behavior B Reason
Window in Group Group moveoutofgroup THEN moveintogroup moveoutofgroup May want moveoutofgroup only because it is more versatile. The window can be moved a second time if moveintogroup is desired. Which dispatcher behavior is selected could be a choice.
Window in Group Window moveoutofgroup " Self-evident.
Window in Group null moveoutofgroup " Self-evident.
Window Group moveintogroup " Self-evident.
Window Window Do nothing. swapactive Self-evident.
Window null Do nothing. " Self-evident.
Window in Floating Group null moveoutofgroup moveoutofgroup AND float Which behavior depends on if the user wants a window which is already in a floating group to remain floating, or if it should find a position in the tiled layout. Choice.
Floating Window null Do nothing. " Self-evident.

Now, I would like to see something very similar to work with bindm, because that is how I intend to use it. I will make a new table with my ideas after a short break.

@spikespaz
Copy link
Contributor Author

For another new dispatcher to work with bindm (and probably a control key):

Hovered Tile Behavior A Behavior B Reason
Window in a Group moveoutofgroup THEN movewindow " Self-evident.
Window movewindow " Self-evident.
Window in Floating Group moveoutofgroup THEN movewindow moveoutofgroup AND float THEN movewindow The original movewindow can always move the group itself, so no special behavior (option or C) is necessary.
Floating Window movewindow " Self-evident.

@memchr
Copy link
Contributor

memchr commented Aug 17, 2023

moveoutofgroup THEN moveintogroup

No, moveintogroup doesn't check for PWINDOW->m_sGroupData.pNextWindow.

@spikespaz
Copy link
Contributor Author

moveoutofgroup THEN moveintogroup

No, moveintogroup doesn't check for PWINDOW->m_sGroupData.pNextWindow.

I'm annoyed, because you didn't read the preface.

For brevity, I use terms like AND and THEN below to describe behaviors; however this is not actually what I think should happen. We need unique code.

@memchr
Copy link
Contributor

memchr commented Aug 17, 2023

I'm annoyed, because you didn't read the preface.

I am truly sorry for the frustration or offence, but this is to clear up any confusion about what the dispatcher actually does, so we can collaborate more effectively.

If you prefer, we can stop this conversation.

void CKeybindManager::moveIntoGroup(std::string args) {
char arg = args[0];
static auto* const GROUPLOCKCHECK = &g_pConfigManager->getConfigValuePtr("misc:moveintogroup_lock_check")->intValue;
if (!isDirection(args)) {
Debug::log(ERR, "Cannot move into group in direction %c, unsupported direction. Supported: l,r,u/t,d/b", arg);
return;
}
const auto PWINDOW = g_pCompositor->m_pLastWindow;
if (!PWINDOW || PWINDOW->m_bIsFloating)
return;
const auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, arg);
if (!PWINDOWINDIR || !PWINDOWINDIR->m_sGroupData.pNextWindow)
return;
if (*GROUPLOCKCHECK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || (PWINDOW->m_sGroupData.pNextWindow && PWINDOW->m_sGroupData.locked)))
return;
if (!PWINDOW->m_sGroupData.pNextWindow)
PWINDOW->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(PWINDOW));
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW); // This removes groupped property!
PWINDOWINDIR->insertWindowToGroup(PWINDOW);
PWINDOWINDIR->setGroupCurrent(PWINDOW);
PWINDOW->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(PWINDOW);
g_pCompositor->focusWindow(PWINDOW);
}

NOTE:

     if (!PWINDOW->m_sGroupData.pNextWindow) 
         PWINDOW->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(PWINDOW)); 
  • This line adds a group decoration to the PWINDOW if it was not in a group before.
  • Window in direction is not null implys active window is not floating.

@memchr
Copy link
Contributor

memchr commented Aug 17, 2023

@spikespaz Hi, sorry for the intrusion, would you like to test this PR? #3006

@memchr
Copy link
Contributor

memchr commented Aug 17, 2023

The new dispatcher is currently named movewindoworgroup, a new configuration variable binds:check_group_lock has been added which causes the dispatcher to behave alternatively around locked groups.

The dispatcher accepts any args that moveintogroup accepts.

For example, you can test it like this

bind = , g, togglegroup,
bind = SHIFT, g, moveoutofgroup,
bind = , slash, lockactivegroup, toggle

bind = SHIFT,h, movewindoworgroup, l
bind = SHIFT,l, movewindoworgroup, r
bind = SHIFT,k, movewindoworgroup, u
bind = SHIFT,j, movewindoworgroup, d

bind = , h, movefocus, l
bind = , l, movefocus, r
bind = , k, movefocus, u
bind = , j, movefocus, d

bind = , comma, changegroupactive, b
bind = , period, changegroupactive, f

bind = , t, setgrouplockchecking, toggle

binds {
	check_group_lock = true
}

misc {
	group_focus_removed_window = false
}

@memchr
Copy link
Contributor

memchr commented Aug 17, 2023

Other changes to the behaviour of existing dispersers are

  • moveoutofgroup/movewindoworgroup can be configured to focus and move the cursor to the removed window instead of the previous group.
  • Toggle group lock check using setgrouplockchecking dispatcher

Thank you very much for your time and feedback.

@fleurc
Copy link

fleurc commented Sep 26, 2023

Hi, I have no way to meaningfully make this enhancement any better, but I'd like to enter the discussion by pointing out that I've found this Issue thread when trying to implement a dispatcher of the name "movewindoworgroup" described in Hyprland Wiki

If this is not an implemented feature or a feature in testing only, why have it be described as available to use inside of the Wiki?

@memchr
Copy link
Contributor

memchr commented Sep 27, 2023

If this is not an implemented feature or a feature in testing only, why have it be described as available to use inside of the Wiki

Already implemented and merged: #3006 (with the exception of the mouse bindings), released in v0.30

and the wiki, to my knowledge, always documents the last git main branch.


@vaxerski Should this be closed?

@fleurc
Copy link

fleurc commented Sep 27, 2023

Is it implemented as of version 0.29.1-1?

@fleurc
Copy link

fleurc commented Sep 27, 2023

I ask because in said version, hyprland told me no such dispatcher existed

@memchr
Copy link
Contributor

memchr commented Sep 27, 2023

I ask because in said version, hyprland told me no such dispatcher existed

Already implemented and merged: #3006 (with the exception of the mouse bindings), released in v0.30

released in v0.30

@fleurc
Copy link

fleurc commented Sep 27, 2023

Ah thank you, I hadn't read that, very sorry for the inconvenience.

@spikespaz
Copy link
Contributor Author

@memchr

I'm annoyed

I apologize for this interaction.

@izmyname
Copy link

Wasn't this implemented already, btw? I mean, there's a dispatcher, but the issue is still open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants