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 156511 - Fullscreen window on other xinerama monitor doesn't stay on top
Fullscreen window on other xinerama monitor doesn't stay on top
Status: RESOLVED FIXED
Product: metacity
Classification: Other
Component: general
unspecified
Other Linux
: High normal
: ---
Assigned To: Metacity maintainers list
Metacity maintainers list
: 139930 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2004-10-26 19:27 UTC by Havoc Pennington
Modified: 2005-01-28 18:42 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Havoc Pennington 2004-10-26 19:27:23 UTC
If you have a fullscreen window on one monitor, and then start working on the
other monitor, your fullscreen window gets dropped below the panel because it
loses focus.

My thought is something like:

 - fullscreen windows are stacked on top if (they have focus OR 
   the focus window is on another xinerama OR the no-focus window
   is focused)

Will code up the patch here shortly, but please post comments or better
suggestions if you have them...
Comment 1 Elijah Newren 2004-10-26 19:35:52 UTC
Even off-topic comments?  Like "please commit the patch you approved in bug
151245 for me, because I don't have a freedesktop.org cvs account" ?  ;-)
Comment 2 Rob Adams 2004-10-26 19:43:57 UTC
Did we ever make the change in the semantics of the expected focus window that
Elijah suggested before?  Either way, it should involve the expected focus
window, and also they should be on top if any transient descendant of the
fullscreen window is focused.
Comment 3 Havoc Pennington 2004-10-28 17:50:59 UTC
Current test is:

     else if ((window->has_focus || focused_transient ||
                (window == window->display->expected_focus_window)) &&
               (window->fullscreen || window_is_fullscreen_size (window)))
        layer = META_LAYER_FULLSCREEN;

So let's abbreviate "window->has_focus || focused_transient || window ==
expected_focus_window" as HAS_FOCUS (window) and propose:

 if ((HAS_FOCUS (window) || on_other_xinerama (expected_focus_window) ||
     expected_focus_window == NULL) &&
     FULLSCREEN (window))
   layer = META_LAYER_FULLSCREEN;

Is that right?
Comment 4 Elijah Newren 2004-10-28 19:00:05 UTC
We should probably make window==window->display->expected_focus_window be more
robust.  It can be wrong in race-condition like areas because XSetInputFocus
calls are ignored if the timestamp is less than the last time that
XSetInputFocus was called (and this _will_ happen in Metacity in the cases
listed in bug 152000--that's why timestamps fixed those problems).  We currently
always change the expected_focus_window but it'd be better to wrap
XSetInputFocus as we talked about in bug 154598 so that the
expected_focus_window is only changed when the focus is changed.

Also, a much more minor point is that if you use window->has_focus and
window==window->display->expected_focus_window, then you can get multiple
windows having focus at the same time (but only for a short duration between the
XSetInputFocus call and the FocusIn/FocusOut events).  You may want to use only
one or the other.  I know the current code uses both, but I was planning on
fixing that up after doing the XSetInputFocus wrapping.
Comment 5 Elijah Newren 2004-12-20 20:00:58 UTC
*** Bug 139930 has been marked as a duplicate of this bug. ***
Comment 6 Elijah Newren 2004-12-23 23:51:16 UTC
The wrapping of XSetInputFocus in bug 154598 is done now, so I think this can be
applied.  I think your proposal is correct.  There is the possibility for
problems due to the fact that expected_focus_window isn't updated when clients
call XSetInputFocus directly, but I don't think that's a real big deal and we
already have similar problems anyway (we already have the possibility for the
code to think there's multiple focus windows since the value of
window->has_focus and expected_focus_window can be different during the time
between an XSetInpuFocus call and the corresponding FocusIn/FocusOut events). 
We could get rid of the multiple perceived focus windows issue by removing
expected_focus_window everywhere (would that give correct results?), or else by
removing ->has_focus  everywhere (see last comment of 154598 for more about this
choice), but they don't seem to have caused any problems so far.  :-)
Comment 7 Havoc Pennington 2004-12-24 02:22:29 UTC
Hmm, I seem to have this in RHEL-3 but don't see it in CVS/RHEL-4/FC3 - I don't
remember the story here, so maybe there's a reason or maybe I just forgot

--- metacity-2.4.55/src/stack.c.fullscreen-xinerama     2003-03-17
01:36:34.000000000 -0500
+++ metacity-2.4.55/src/stack.c 2004-10-28 18:35:13.954512840 -0400
@@ -217,6 +217,17 @@
   return FALSE;
 }

+static gboolean
+windows_on_different_xinerama (MetaWindow *a,
+                               MetaWindow *b)
+{
+  if (a->screen != b->screen)
+    return TRUE;
+
+  return meta_screen_get_xinerama_for_window (a->screen, a) !=
+    meta_screen_get_xinerama_for_window (b->screen, b);
+}
+
 /* Get layer ignoring any transient or group relationships */
 static MetaStackLayer
 get_standalone_layer (MetaWindow *window)
@@ -249,8 +260,12 @@
         layer = META_LAYER_FOCUSED_WINDOW;
 #endif

-      if (window->has_focus &&
-          (window->fullscreen || window_is_fullscreen_size (window)))
+      if ((window->fullscreen || window_is_fullscreen_size (window)) &&
+          (window->has_focus ||
+           window->display->focus_window == NULL ||
+           (window->display->focus_window != NULL &&
+            windows_on_different_xinerama (window,
+                                           window->display->focus_window))))
         layer = META_LAYER_FULLSCREEN;
       else if (window->wm_state_above)
         layer = META_LAYER_DOCK;
Comment 8 Elijah Newren 2004-12-24 04:20:22 UTC
I don't see any problems with this RHEL3 patch (but I don't have xinerama and
haven't played much with stack.c either...).  Rob, are there any special cases
you know of where the distinction between expected_focus_window and focus_window
is important for this particular chunk of code?
Comment 9 Rob Adams 2004-12-24 16:49:16 UTC
nope; it's only there to prevent the panels from flashing above fullscreen
windows when you close a transient descendant of a fullscreen window.
Comment 10 Havoc Pennington 2005-01-28 16:34:30 UTC
If this looks fine to you guys let's go for it
Comment 11 Elijah Newren 2005-01-28 18:42:25 UTC
committed.

2005-01-28  Elijah Newren  <newren@gmail.com>

	Patch from RHEL-3 (Havoc doesn't remember how it got there) that
	Havoc posted in bug 156511 to fix the problem with fullscreen
	windows on a different xinerama monitor not staying on top.  I
	updated to HEAD.  Should fix #156511.

	* src/stack.c: (windows_on_different_xinerama): new function,
	(get_standalone_layer): let windows on a different screen than the
	one with the focus window stay in the fullscreen layer