material-shell icon indicating copy to clipboard operation
material-shell copied to clipboard

Focus monitor shortcuts doesn't focus windows

Open xendk opened this issue 4 years ago • 28 comments

Describe the bug Using the focus-monitor-(left|right) shortcuts doesn't focus any window on the new monitor, as I would expect. It does move the mouse-pointer to the center of the screen, which I didn't expect. The only way to actually focus a window on the new screen is to immediately use (next|previous)-window/(next|previous)-workspace after focusing the monitor, but this is awkward at best, causing compos like focus-monitor-left, next-window, prev-window just to get focus in the last used window on the monitor.

Expected behavior That focus-monitor-(left|right) puts focus on the last focused window on the monitor, and the mouse pointer stays where it is.

Analysis Looking at the source, I noticed that the monitor focusing uses MsWorkspaceManager.focusWorkspace() which simply moves the mouse to the new monitor and calls MsWorkspace.refreshFocus() on the new Workspace. This actually seems to work if one has set mouse focus to "hover", but I've set it to "on click" because hover messes with moving windows (that's another ticket).

I don't think moving the mouse should be necessary, in regular gnome I can alt-tab to a window on another monitor just fine.

To Reproduce

  • Occurs on:
    • [x] X.Org
    • [ ] Wayland
  • GNOME Shell version: 3.38.2
  • Distro: Debian testing

Current commit Output from git rev-parse --short HEAD: a216007

Log data Output from journalctl /usr/bin/gnome-shell, I switched monitor a couple of times in here:

Feb 28 00:12:05 xiphos gnome-shell[3069]: Focus MsWindow, New Issue · material-shell/material-shell - Mozilla Firefox
Feb 28 00:12:19 xiphos gnome-shell[3069]: Focus MsWindow, vterm: ~/.l/s/g/extensions
Feb 28 00:12:20 xiphos gnome-shell[3069]: Focus MsWindow, vterm: ~/d/c/material-shell<2>
Feb 28 00:12:39 xiphos gnome-shell[3069]: Focus MsWindow, New Issue · material-shell/material-shell - Mozilla Firefox
Feb 28 00:12:44 xiphos gnome-shell[3069]: Focus MsWindow, vterm: ~/d/c/material-shell<2>
Feb 28 00:14:17 xiphos gnome-shell[3069]: Focus MsWindow, Where is the npx central cache located? : node - Vivaldi
Feb 28 00:14:18 xiphos gnome-shell[3069]: Focus MsWindow, New Issue · material-shell/material-shell - Mozilla Firefox
Feb 28 00:14:28 xiphos gnome-shell[3069]: Focus MsWindow, vterm: ~/.l/s/g/extensions
Feb 28 00:14:28 xiphos gnome-shell[3069]: Focus MsWindow, vterm: ~/d/c/material-shell> journalctl /usr/bin/gnome-shell

xendk avatar Feb 28 '21 00:02 xendk

I've been digging around to see if I could fix it myself, which I haven't quite, but I'll add my findings here.

I've realized why the current implementation is moving the mouse. Currently it's relying on checking which monitor has the mouse to determine whether a workspace on an extra monitor (I'll call monitors other than the primary display, the one which plain Gnome Shell would place the top bar, for "extra" here). As there doesn't seem to be any concept of "focused monitor" in Gnome/X11, it has to come up with something.

A side effect of this is that Material Shells "workspace focus" is basically like mouse hover focus for windows.

So, I think a possible fix would be to change that to not use get_current_monitor() to determine which msWorkspace is active, but rather use the msWorkspace of the window that currently has the focus. Then the mouse moving hackery can me removed and the monitor switching hotkeys can simply focus the last active window in the msWorkspace of the monitor being switched to.

A consequence is that workspaces becomes "click to focus". Which will only make a difference in multi-monitor setups, as there's only ever one workspace visible in a single display setup. But as MS seems to be incompatible with "focus follows mouse" at the moment (#611), I think it's a bit inconsistent if MS workspaces are. And if #611 can be fixed, it would fix it for workspaces for free.

Well, that's my current theory, anyway, we'll see if I find the time to try it out.

xendk avatar Mar 01 '21 22:03 xendk

Well, I got somthing somewhat working here: https://github.com/xendk/material-shell/commit/bd3cfd1107659319cb89223ba6d8028bb34532f6

But apparently global.display.get_focus_window() returns null when the app launcher is active (not a real window I suppose), which kills next/prev window as it gets activated. I've kludged around it for the moment being by storing the last seen active workspace, which makes it work again as long as there's only an app launcher on one screen. But if two gets shown one have to back out by reaching for the mouse.

I could use some help in figuring out how to deal with the app launcher.

xendk avatar Mar 02 '21 22:03 xendk

So, been running with this all day, and apart from the mentioned app launcher thing, the only other thing I've noticed is that new windows get added in the workspace where the pointer is, not the workspace of the parent. Haven't looked into it yet, but I wouldn't think it should be that hard to fix.

xendk avatar Mar 03 '21 20:03 xendk

Thanks for digging into this. In the gnome shell world there is always something focused. It's either a window or an Actor. To get the active monitor relative to the current focused element you can do something like this:

let monitorIndex = global.display.get_focus_window() ? global.display.get_focus_window().get_monitor() : Main.layoutManager.findMonitorForActor(global.stage.key_focus).index;

but using this method all the time could be annoying for exemple when you use the hybrid workflow with one hand on the mouse and one hand on the keyboard to navigate and you decide to move the mouse on the other monitor and try to navigate among windows with the keyboard.

Maybe we can defined a better hybrid system depending on the needs

PapyElGringo avatar Mar 03 '21 21:03 PapyElGringo

We should put all the code related to focus inside the MsFocusManager

PapyElGringo avatar Mar 03 '21 21:03 PapyElGringo

Ah, an Actor. I'm not very familiar with the workings of Gnome or the API, so I'm just fumbling along. So, I'll should be able to find the msWorkspace with the whatever-focused, by figuring out the monitor of the thing, and find the msWorkspace for that..

but using this method all the time could be annoying for exemple when you use the hybrid workflow with one hand on the mouse and one hand on the keyboard to navigate and you decide to move the mouse on the other monitor and try to navigate among windows with the keyboard.

Oh, don't I know it, I'm trying to unlearn focus-follows-mouse at the moment (due to #611). :smile: But I think that "focus follows mouse" should go hand in hand for both workspaces and focus? If moving the pointer to another monitor "focuses" the workspace, it should focus windows too. If it weren't for #611, I'd still be using focus follows mouse, and then I would expect workspace focus to follow (which it would with my current branch, moving the pointer to another monitor would focus a window, and that would focus the workspace).

We should put all the code related to focus inside the MsFocusManager

Makes sense. Maybe it should be the one that decides what has focus?

xendk avatar Mar 03 '21 23:03 xendk

Maybe it should be the one that decides what has focus? It's depend what you mean by "decide" since we can't prevent default focus behavior. But yeah most of the focus related code should go there

PapyElGringo avatar Mar 04 '21 08:03 PapyElGringo

It's depend what you mean by "decide"

Well, I was thinking whether it was the workspace under the pointer or the one containing the focused window/actor.. But maybe that's weird.

But as I said, if workspace focus just follows window/actor focus, I think it makes sense.. Having keyboard input go to one window, but workspace shortcuts working on another workspace just seems wrong to me. If we work out the kinks with focus-follows-mouse, those who like "point and type" can just use focus-follows-mouse. Don't you think?

xendk avatar Mar 04 '21 20:03 xendk

I must admit though, there is an inconsistency in click-to-focus in Gnome: Mouse wheel always scroll the window under the pointer, not the focused one. But I still think that Material Shell hotkeys should follow keyboard focus, it's all keyboard, right?

xendk avatar Mar 04 '21 22:03 xendk

Well Material Shell is designed to be optimized for the hybrid uses. But the solution is probably somewhere in the middle ground. But I'm not sure where :)

PapyElGringo avatar Mar 04 '21 22:03 PapyElGringo

But I'm not sure where

No, it's a tad difficult to figure out without some more multi-monitor users weighing in. A couple of points though:

The existing "focus monitor" shortcuts really only worked with focus-follows-mouse. Of course that doesn't tell us how many use a hybrid model where they flick the pointer to a screen and use keyboard to switch windows.

One datapoint: I was a hybrid user in regular Gnome, I would flick the pointer around to focus windows on different monitors, but with MS I like using keyboard shortcuts much better (easier aiming, just need to figure out #611).

We could easily make a switch called "workspace focus follows mouse/keyboard focus" to switch between the current and my behavior, but adding more switches isn't in the Gnome nature. And it's difficult to communicate to users what it does. That's why I think it would be nice to take a queue from the state of focus-follows-mouse.

The question is, how many hybrid users isn't using focus-follows-mouse? (I don't even know what's default in Gnome anymore)

xendk avatar Mar 06 '21 00:03 xendk

Thanks for pointing me to this discussion.

I am a multi monitor user (3) with the primary display in the middle. The current focus monitor solution does not work for me and I also have "click-to-focus".

I think (without having tried it) that making the workspace focus follow window/actors is the correct solution. I use super+r to run and switch to applications. If I were to select some application on a different monitor I would expect to focus to move to that workspace.

HaukurPall avatar Mar 20 '21 21:03 HaukurPall

The question is, how many hybrid users isn't using focus-follows-mouse?

Another hybrid user with click-to-focus here!

I agree that it's really unintuitive that the workspace on the other monitor does not get focused, and found this issue while looking for a solution. It's confusing as well given that there's no indicator showing which monitor currently has focus.

rhoot avatar May 04 '21 08:05 rhoot

I am using multi monitor with focus follows mouse and the focus to another monitor does not work when there is a split window in the monitor I want to focus. The mouse pointer turns into a hand icon and it seems it wants to resize. because it goes to the center of the screen and there is a division of two windows (is this the "actor" case?) but the focus remains in the original monitor. When there is only one window or there is no border in the center of the screen then the focus works, albeit it focuses on the window that is in the center.

99Percent avatar May 10 '21 23:05 99Percent

Hello! I've been digging around the code to see how MS focus a window when you click on a tab and discovered that msWorkspace has a method called refreshFocus that receives a boolean parameter called "force". If you modify the code in this bit to send true to this method call it does seems like it solves the problem without focus-follow-mouse.

image

hope this helps.

kabessao avatar May 21 '21 16:05 kabessao

@99Percent for your problem i've been able to move the mouse to the very top in the same bit of code. That solves the issue of changing monitors when one of them is splitted, but not something like #611. I'm looking at pop shell extension code to see how can we move the mouse to the corner of the window like they do. image

kabessao avatar May 21 '21 16:05 kabessao

I've been running with https://github.com/xendk/material-shell/commit/bd3cfd1107659319cb89223ba6d8028bb34532f6 for some time, and It Works For Me™. It could deal better with actors, but it hasn't irritated me enough.

It basically just makes the "active workspace" always be the workspace which contains the window with the focus (the keyboard focus).

But I discovered that I really missed focus follows mouse, so I ran into #611 and have been trying to figure that one out, as it seems to me that these two issues are intertwined.

#611 is annoying me on a daily basis (whenever I leave the pointer over a window and try moving windows around with the keyboard), but my above branch is working nicely.

xendk avatar May 22 '21 10:05 xendk

A side effect of my code is that since the mouse pointer is moved to the top bar it doesn't interfere with splits, but it will on full screen mode.

But on pop shell when you change window through keybinding it moves the cursor to the top left corner of the window. Maybe we can implement something like that.

kabessao avatar May 23 '21 07:05 kabessao

But on pop shell when you change window through keybinding it moves the cursor to the top left corner of the window.

I don't like that, but I'd better provide some better arguments than personal opinion:

For starters, I, for one, seem to have some spacial memory of where my pointer is. When the system starts moving the pointer around, it messes with that. In my mind only one thing should move the pointer and that's the mouse.

I was wondering where this strong opinion came from, and I remembered being highly annoyed back when I was using a regular mouse (I'm using a trackball these days) when apps was messing with the pointer position.

Which makes sense, as when you're using a mouse, you kind of map out your screen real-estate on your desk, and when the mouse pointer jumps it moves the mapping causing you to bump into the keyboard or fall off the desk unless you lift and reposition the mouse.

It's a problem that doesn't exist for trackball or trackpad users, but I would guess there's still a significant proportion of mouse users in Material Shell users.

That being said, Pop Shell does look interesting.

xendk avatar May 23 '21 19:05 xendk

Yes, I can see that being a problem for some people. So maybe we can think of some way to make this an option that you can opt in or out, since in this case the mouse relocation is purely cosmetic.

kabessao avatar May 24 '21 12:05 kabessao

Indeed. It could be an option, but then the easiest way to implement it would still be by fixing keyboard focusing and implement mouse-follows-focus on top of that. Maybe it's as simple as having refreshFocus() move the pointer to the newly focused window when an option is set.

If anyone feels like grabbing my changes in https://github.com/xendk/material-shell/commit/bd3cfd1107659319cb89223ba6d8028bb34532f6 and fixing it to deal properly with actors and make a pull request, feel free. My free time to time-needed-to-fiddle-with-all-the-things-I'd-like-to-fiddle-with ratio is pretty lousy at the moment.

xendk avatar May 24 '21 18:05 xendk

Yeah, this issue is not as easy to fix as i thought it would be. I've just closed my pull request because it seems that when you set 'refreshFocus' as true when you change workspaces it moves you to the first workspace in the main monitor whenever you have another workspace selected in it.

kabessao avatar May 24 '21 19:05 kabessao

@kabessao I think that's fixed in my version by activating the workspace before refreshing focus: https://github.com/xendk/material-shell/commit/bd3cfd1107659319cb89223ba6d8028bb34532f6#diff-6493a2213dd79237ede9869ba204221b6d693b1979ea503e4a9b86fa70ebadbeR786

xendk avatar May 25 '21 21:05 xendk

@xendk Nice, I'm gonna apply this on mine as well. Thanks !

kabessao avatar May 26 '21 20:05 kabessao

:+1: and if you could fix the actor thing, we could turn it into a pull request. :wink:

xendk avatar May 26 '21 20:05 xendk

Did this issue ever get solved? I'm finding this to be quite the pain when it comes to using Material Shell.

mattrbrousseau avatar Dec 07 '21 10:12 mattrbrousseau

Following up on this issue. Is there currently a fix to this?

leoqiao18 avatar Mar 13 '22 03:03 leoqiao18

Same question here. :-)

lgvld avatar Apr 28 '22 10:04 lgvld