After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 642881 - Multiple monitor hot corner handling
Multiple monitor hot corner handling
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Owen Taylor
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2011-02-21 15:27 UTC by Alexander Larsson
Modified: 2011-03-03 14:57 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Factor out hot corner handling into a class (16.35 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
needs-work Details | Review
No need to Check for grabbed menus on hot corner enter/click (1.19 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
committed Details | Review
Remove not used reference from HotCorner to panel (1.60 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
accepted-commit_now Details | Review
Move HotCorner to chrome instead of in the panel (4.20 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
accepted-commit_now Details | Review
Put a hot corner on each monitor (3.04 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
reviewed Details | Review
Remove unused tracking of visibility in Chrome (1.60 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
committed Details | Review
Track fullscreen status per-monitor in Chrome (7.34 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
needs-work Details | Review
Consider struts top/botton or left/right based on primary monitor size (2.83 KB, patch)
2011-02-21 15:28 UTC, Alexander Larsson
none Details | Review
Factor out hot corner handling into a class (15.41 KB, patch)
2011-02-23 16:11 UTC, Alexander Larsson
committed Details | Review
Move HotCorner to chrome instead of in the panel (3.62 KB, patch)
2011-02-23 16:11 UTC, Alexander Larsson
committed Details | Review
Don't rely on HotCorner method to toggle overview mode in panel (2.87 KB, patch)
2011-02-23 16:12 UTC, Alexander Larsson
reviewed Details | Review
Put a hot corner on each monitor (2.20 KB, patch)
2011-02-23 16:12 UTC, Alexander Larsson
committed Details | Review
Track fullscreen status per-monitor in Chrome (8.36 KB, patch)
2011-02-23 16:12 UTC, Alexander Larsson
committed Details | Review
Consider struts top/botton or left/right based on primary monitor size (2.83 KB, patch)
2011-02-23 16:12 UTC, Alexander Larsson
reviewed Details | Review
Fix positioning of panel on startup (1.67 KB, patch)
2011-02-24 11:12 UTC, Alexander Larsson
accepted-commit_now Details | Review
Consider struts top/botton or left/right based on primary monitor size (4.26 KB, patch)
2011-02-24 11:12 UTC, Alexander Larsson
accepted-commit_now Details | Review
Ensure that all struts we set extends to their boundary (1.58 KB, patch)
2011-02-24 11:12 UTC, Alexander Larsson
accepted-commit_now Details | Review

Description Alexander Larsson 2011-02-21 15:27:10 UTC
In the multiple monitor case the hot corner doesn't work quite right. For instance, I generally have the primary monitor on the right (its larger and physically on the right). This means I can't use the "fitz law" corner for switching to overview mode.

We want to add pointer barriers to X, which will let us handle the hot corner on the activities button a bit better in this case, but even with that it would not work if the mouse is already on the left monitor.

So, the best approach is imho (and I discussed this with owen before) to just add a hot corner in the top left corner on all monitors.
Comment 1 Alexander Larsson 2011-02-21 15:28:05 UTC
Created attachment 181467 [details] [review]
Factor out hot corner handling into a class

This is needed so that we can have several instances, one per
monitor.
Comment 2 Alexander Larsson 2011-02-21 15:28:08 UTC
Created attachment 181468 [details] [review]
No need to Check for grabbed menus on hot corner enter/click

We never get enter events anyway due to the menu code, and if
the user clicks on a non-menu the menu is removed and ungrabbed
before the target actor gets the event anyway.
Comment 3 Alexander Larsson 2011-02-21 15:28:11 UTC
Created attachment 181469 [details] [review]
Remove not used reference from HotCorner to panel
Comment 4 Alexander Larsson 2011-02-21 15:28:15 UTC
Created attachment 181470 [details] [review]
Move HotCorner to chrome instead of in the panel

This prepares for there being multiple hot corners, one per monitor.
Comment 5 Alexander Larsson 2011-02-21 15:28:19 UTC
Created attachment 181471 [details] [review]
Put a hot corner on each monitor
Comment 6 Alexander Larsson 2011-02-21 15:28:23 UTC
Created attachment 181472 [details] [review]
Remove unused tracking of visibility in Chrome
Comment 7 Alexander Larsson 2011-02-21 15:28:27 UTC
Created attachment 181473 [details] [review]
Track fullscreen status per-monitor in Chrome

This is required since we can have chrome on multiple monitors (due to
per-monitor hot-corners).
Comment 8 Alexander Larsson 2011-02-21 15:28:31 UTC
Created attachment 181474 [details] [review]
Consider struts top/botton or left/right based on primary monitor size

Right now we require a strut to be as wide as the full screen to
create a TOP strut. This means that in a multi-monitor scenario (at
least if the primary monitor is leftmost) we will make the panel strut
be Meta.Side.LEFT due to the random side picking for corner objects.

This changes the width/height comparison to the primary monitor rather
than the screen to get this right. Also adds some docs about how
struts work in a multi-monitor situation.
Comment 9 Owen Taylor 2011-02-21 17:35:40 UTC
Review of attachment 181467 [details] [review]:

::: js/ui/panel.js
@@ +507,3 @@
+        // hot corner and has not left both the hot corner and a surrounding
+        // guard area (the "environs"). This avoids triggering the hot corner
+        // multiple times due to an accidental jitter.

Comment got divorced from the variable that it was referring to

@@ +556,3 @@
+    },
+
+    _allocate: function (parentWidth, direction, flags) {

underscore prefix means class-private not module/file-private.

I don't like having part of the allocate() method of the parent coontainer here - we'd generally like have a JS class as corresponding to an actor - not a mishmash of a couple of actors and part of the implementation of the parent container.

The cleanest thing to do would be if you can change thing so this._environs is a container for this._corner and gets renamed to this.actor. For our purposes can just assume St.Widget.get_default_direction() won't change and statically position the._corner with the environs at a fixed location using that knowledge. Then the parent would be responsible for positioning hotCorner.actor in the appropriate corner of the screen.

@@ +660,3 @@
+    // of the hot corner being triggered. This check avoids opening and closing the overview if the user both triggered the hot corner
+    // and clicked the Activities button.
+    _maybeToggleOverviewOnClick: function() {

* No _ prefix, since it's not class private
* I'd rather if the overview.toggle() was in the caller - so maybe something like:

 if (!this._hotCorner.recentlyActivated())
   Main.overview.toggle();
 this._hotCorner.resetActivationTime(); // always activate on a second click

I don't think logic for handling clicks on the Activities button should be in the hot corner class.
Comment 10 Owen Taylor 2011-02-21 17:44:53 UTC
Review of attachment 181468 [details] [review]:

Looks OK - menu handling has changed a lot since that check was added.
Comment 11 Owen Taylor 2011-02-21 17:47:57 UTC
Review of attachment 181469 [details] [review]:

Fine
Comment 12 Alexander Larsson 2011-02-21 17:49:24 UTC
Re _allocate: The first patch mainly splits out the current code thats in
Panel, later commits starts changing the behaviour, including making it not be
allocated as a child of the panel.

Such mini-commits is the style i'm used to, but maybe thats not ideal for
reviewing like this?

Anyway, the containment and actor rename change makes sense too, I'll have more
feedback tomorrow.
Comment 13 Owen Taylor 2011-02-21 19:24:14 UTC
Review of attachment 181470 [details] [review]:

OK

::: js/ui/panel.js
@@ +555,3 @@
     },
 
+    position: function(parentBox, direction) {

Don't pass in the direction, just use:

 let rtl = St.Widget.get_default_direction().get_direction() == St.TextDirection.RTL;

@@ +560,3 @@
+            x += parentBox.width - this._environs.width;
+        } else {
+        }

Find this empty else weird rather than informative

@@ +771,3 @@
         this._leftBox.add(this.button);
 
+        this._hotCorner = new HotCorner();

I'd probably have moved tihs directly to main.js in this patch - rather than having main.js access a private variable, but an ok micro-commit split.
Comment 14 Owen Taylor 2011-02-21 19:30:09 UTC
Review of attachment 181471 [details] [review]:

Good except for cosmetics

::: js/ui/main.js
@@ +391,3 @@
+        for (let i = 0; i < hotCorners.length; i++) {
+            hotCorners[i].destroy();
+        }

We generally avoid unnecessary {}

@@ +409,3 @@
+        if (is_primary) {
+            panel.setHotCorner(corner);
+        }

More unnecessary {} (saw some in the previous patch too)

::: js/ui/panel.js
@@ +847,3 @@
     },
 
+    setHotCorner: function(corner) {

Would like a little bit of a comment indicating the significance of this - something like

 // While there can be multiple hotcorners (one per monitor), the hot corner
 // that is on top of the Activities button is special since it needs special
 // coordination with clicking on that button
Comment 15 Owen Taylor 2011-02-21 20:22:56 UTC
Review of attachment 181472 [details] [review]:

Dan said that he though this was probably left-over cruft in the patch when initially committed
Comment 16 Owen Taylor 2011-02-21 20:34:35 UTC
Review of attachment 181473 [details] [review]:

General idea looks fine, but reads somewhat messy to me - various comments below.

::: js/ui/chrome.js
@@ +217,3 @@
+        this._monitors = []
+        for (let i = 0; i < monitors.length; i++) {
+            // Create a plain js object so we can extend it nicely

Hmm, I guess it's a style question - there's really no problem with "expando" adding properties to a Meta.Rectangle - whether that's "nice" or not is harder to say. I guess I'd consider it nice enough and just go ahead and do it and skip the 4 lines of code.

@@ +218,3 @@
+        for (let i = 0; i < monitors.length; i++) {
+            // Create a plain js object so we can extend it nicely
+            let monitor = {x: monitors[i].x,

Missing space before 'x' if you stick with creating a pure JS object

@@ +228,3 @@
+                monitor.height == primary.height) {
+                this._primaryMonitor = monitor;
+            }

unnecessary {}

@@ +232,3 @@
+    },
+
+    _findMonitorAt: function(pos) {

Is the duck-typing of having this function take a 'pos' and calling it with a window with x/y properties intentional or accidental? Some people might consider it good weakly typed language practice, but I think it would be less confusing with (x, y) if you don't always want it to take a window. And if it always took a window, findMonitorForWindow() would make more sense.

@@ +234,3 @@
+    _findMonitorAt: function(pos) {
+        let x = Math.max(pos.x, 0);
+        let y = Math.max(pos.y, 0);

unclear why you max() - we still have the possibility that the position isn't on any monitor, right?

@@ +237,3 @@
+        for (let i = 0; i < this._monitors.length; i++) {
+            let monitor = this._monitors[i];
+            // We consider the window origin to define which monitor a window is on

Center would be more robust right? if the center is on a monitor or on the next monitor over by a pixel, it isn't very obvious to the user if we get it wrong. Is there some reason that this works better?

This comment seems misplaced in any case

@@ +241,3 @@
+                y >= monitor.y && y < monitor.y + monitor.height) {
+                return monitor;
+            }

and here

@@ +248,3 @@
+    _findMonitorForActor: function(actor) {
+        let [x, y] = actor.get_transformed_position();
+        return this._findMonitorAt({x: Math.round(x), y: Math.round(y)})

rounding is unclear why - I think it' sbecause if get_transformed_position() returned 1023.999 or something you want that to be on the monitor at position 1024 ... probably could use a comment, and maybe should be inside findMonitorAt?

@@ +272,3 @@
+        for (let i = 0; i < this._monitors.length; i++) {
+            this._monitors[i].inFullscreen = false;
+        }

{}

@@ +300,3 @@
+                let monitor = this._findMonitorAt(windows[i]);
+                if (Math.max(windows[i].x, 0) >= monitor.x && Math.max(windows[i].x, 0) < monitor.x + monitor.width &&
+                    Math.max(windows[i].y, 0) >= monitor.y && Math.max(windows[i].y, 0) < monitor.y + monitor.height) {

this looks like it should be some monitorIsAt() function - it's closely related to _findMonitorAt() so having inlined is weird

@@ +310,1 @@
                     windows[i].y <= primary.y &&

leftover primary? how does this not error?

@@ +321,3 @@
+        for (let i = 0; i < this._monitors.length; i++) {
+            wasInFullscreen[i] = this._monitors[i].inFullscreen;
+        }

More {}
Comment 17 Alexander Larsson 2011-02-23 16:11:54 UTC
Created attachment 181714 [details] [review]
Factor out hot corner handling into a class

This is needed so that we can have several instances, one per
monitor.

This also makes the hot corner environments a container which
contains the corner.
Comment 18 Alexander Larsson 2011-02-23 16:11:59 UTC
Created attachment 181715 [details] [review]
Move HotCorner to chrome instead of in the panel

This prepares for there being multiple hot corners, one per monitor.
Comment 19 Alexander Larsson 2011-02-23 16:12:02 UTC
Created attachment 181716 [details] [review]
Don't rely on HotCorner method to toggle overview mode in panel

Instead of using an internal HotCorner method we expose two new
public methods: recentlyActivated and resetActivationTime so that
the panel can check the state of the hot corner instead of relying
on its code.
Comment 20 Alexander Larsson 2011-02-23 16:12:06 UTC
Created attachment 181717 [details] [review]
Put a hot corner on each monitor
Comment 21 Alexander Larsson 2011-02-23 16:12:09 UTC
Created attachment 181718 [details] [review]
Track fullscreen status per-monitor in Chrome

This is required since we can have chrome on multiple monitors (due to
per-monitor hot-corners).

Windows are primary associated with the monitor that their center is on.
Comment 22 Alexander Larsson 2011-02-23 16:12:13 UTC
Created attachment 181719 [details] [review]
Consider struts top/botton or left/right based on primary monitor size

Right now we require a strut to be as wide as the full screen to
create a TOP strut. This means that in a multi-monitor scenario (at
least if the primary monitor is leftmost) we will make the panel strut
be Meta.Side.LEFT due to the random side picking for corner objects.

This changes the width/height comparison to the primary monitor rather
than the screen to get this right. Also adds some docs about how
struts work in a multi-monitor situation.
Comment 23 Alexander Larsson 2011-02-23 16:15:44 UTC
New series, slightly rearranged, fixes everything pointed out by current reviews.
Comment 24 Owen Taylor 2011-02-23 16:35:02 UTC
Review of attachment 181716 [details] [review]:

::: js/ui/panel.js
@@ +798,1 @@
     _maybeToggleOverviewOnClick: function() {

Hmm, didn't actually notice that this function was used both internally and externally because we had the clicking-on-the-hot-corner issue to deal with. I probably would have just recommended removing the _ if I had - it's better to have a function with weird side effects than to duplicate some rather complex logic. Up to you if you want to go with this patch or revert it and just make the function non-private.
Comment 25 Owen Taylor 2011-02-23 16:35:38 UTC
Review of attachment 181714 [details] [review]:

Looks good
Comment 26 Owen Taylor 2011-02-23 16:35:46 UTC
Review of attachment 181715 [details] [review]:

Looks good
Comment 27 Owen Taylor 2011-02-23 17:01:56 UTC
Review of attachment 181718 [details] [review]:

Looks fine except for one bug. OK to commit with that fixed.

::: js/ui/chrome.js
@@ +196,1 @@
                 this.actor.set_skip_paint(actorData.actor, true);

If we actually had actors on multiple monitors, then this wouldn't really work, but nothing really would - we are trying to get the illusion that the fullscreen window is above the chrome actors by hiding them when there is a fullscreen window. Treating actors and windows seems fine.

@@ +217,3 @@
+        this._monitors = monitors;
+        for (let i = 0; i < monitors.length; i++) {
+            let monitor = monitors[i].x;

Stray .x

@@ +303,3 @@
+                let monitor = this._findMonitorForWindow(window);
+                if (monitor)
+                    monitor.inFullscreen = true;

Hmm, this probably doesn't interact right with the newer net-wm spec ability to fullscreen across multiple monitors (_NET_WM_FULLSCREEN_MONITORS or something), but we'll wait until someone complains; or maybe file a bug about it.
Comment 28 Owen Taylor 2011-02-23 17:03:50 UTC
Review of attachment 181717 [details] [review]:

One style fix, otherwise good to commit

::: js/ui/main.js
@@ +406,3 @@
+        let monitor = monitors[i];
+        let corner = hotCorners[i];
+        let is_primary = (monitor.x == primary.x &&

isPrimary
Comment 29 Owen Taylor 2011-02-23 17:12:53 UTC
Review of attachment 181719 [details] [review]:

::: js/ui/chrome.js
@@ +382,3 @@
             // we don't create a strut for it at all.
             let side;
+            if (w >= this._primaryMonitor.width) {

I think this would be better to make into a "spans primary monitor horizontally" check.

Do you think it make sense to try to handle the case where the primary monitor isn't the full screen height by increasing the height of the strut by screen_height - monitor.height?
Comment 30 Alexander Larsson 2011-02-23 19:02:51 UTC
Review of attachment 181716 [details] [review]:

::: js/ui/panel.js
@@ +798,1 @@
     _maybeToggleOverviewOnClick: function() {

I'll drop it, i made this a separate patch at the end to make that easy to do.
Comment 31 Alexander Larsson 2011-02-23 19:19:02 UTC
Attachment 181714 [details] pushed as 196d104 - Factor out hot corner handling into a class
Attachment 181715 [details] pushed as 259c84e - Move HotCorner to chrome instead of in the panel
Attachment 181717 [details] pushed as 7cf311d - Put a hot corner on each monitor
Attachment 181718 [details] pushed as 885f668 - Track fullscreen status per-monitor in Chrome
Comment 32 Alexander Larsson 2011-02-24 11:12:08 UTC
Created attachment 181815 [details] [review]
Fix positioning of panel on startup

We need to do the initial relayout before we start up the startup
animation, and we the startup animation can't hardcode the position
of the panel to zero.
Comment 33 Alexander Larsson 2011-02-24 11:12:26 UTC
Created attachment 181816 [details] [review]
Consider struts top/botton or left/right based on primary monitor size

Right now we require a strut to be as wide as the full screen to
create a TOP strut. This means that in a multi-monitor scenario (at
least if the primary monitor is leftmost) we will make the panel strut
be Meta.Side.LEFT due to the random side picking for corner objects.

This changes the width/height comparison to the primary monitor rather
than the screen to get this right. Also adds some docs about how
struts work in a multi-monitor situation.
Comment 34 Alexander Larsson 2011-02-24 11:12:32 UTC
Created attachment 181817 [details] [review]
Ensure that all struts we set extends to their boundary

Mutter really expects this, as this is how app-specified struts
happen. For instance, if the primary display is beside a taller
screen and is not positioned at the top, then we extend the struts
for the panel with the size of the unused area above the primary
monitor.
Comment 35 Owen Taylor 2011-03-01 16:21:32 UTC
Review of attachment 181815 [details] [review]:

Typo in the commit message 'and we the startup animation'. Otherwise looks fine. 

(clearly the animation won't work for vertically stacked monitors with the panel not at the top, but that's a tiny tip of the iceberg of problems we have in that scenario.)

Can you close bug 625924 after pushing this?
Comment 36 Owen Taylor 2011-03-01 16:23:32 UTC
Review of attachment 181816 [details] [review]:

Looks good to me
Comment 37 Owen Taylor 2011-03-01 16:29:48 UTC
Review of attachment 181817 [details] [review]:

Good (probably mutter should be doing this itself internally, but not really worth worrying about at the moment.)