diff --git a/src/client.c b/src/client.c index 4071e67f..a00df9cd 100644 --- a/src/client.c +++ b/src/client.c @@ -2562,7 +2562,6 @@ void clientActivate (Client *c, guint32 timestamp, gboolean source_is_application) { ScreenInfo *screen_info; - Client *focused; Client *sibling; g_return_if_fail (c != NULL); @@ -2570,15 +2569,9 @@ clientActivate (Client *c, guint32 timestamp, gboolean source_is_application) screen_info = c->screen_info; sibling = clientGetTransientFor(c); - focused = clientGetFocus (); if ((screen_info->current_ws == c->win_workspace) || (screen_info->params->activate_action != ACTIVATE_ACTION_NONE)) { - if ((focused) && (c != focused)) - { - /* We might be able to avoid this if we are about to switch workspace */ - clientAdjustFullscreenLayer (focused, FALSE); - } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN)) { /* We are explicitely activating a window that was shown before show-desktop */ @@ -4084,6 +4077,24 @@ clientGetGtkFrameExtents (Client * c) return value_changed; } +gboolean +clientCheckSameMonitor (Client * c1, Client *c2) +{ + GdkRectangle rect1, rect2; + myScreenFindMonitorAtPoint (c1->screen_info, + frameX (c1) + (frameWidth (c1) / 2), + frameY (c1) + (frameHeight (c1) / 2), &rect1); + + myScreenFindMonitorAtPoint (c2->screen_info, + frameX (c2) + (frameWidth (c2) / 2), + frameY (c2) + (frameHeight (c2) / 2), &rect2); + + + return ((rect1.x == rect2.x) && (rect1.y == rect2.y) + && (rect1.height == rect2.height) && (rect1.width == rect2.width)); + +} + gboolean clientGetGtkHideTitlebar (Client * c) { diff --git a/src/client.h b/src/client.h index 68d7c7bf..089dafc7 100644 --- a/src/client.h +++ b/src/client.h @@ -500,6 +500,9 @@ int clientGetButtonState (Client *, Client *clientGetLeader (Client *); gboolean clientGetGtkFrameExtents (Client *); gboolean clientGetGtkHideTitlebar (Client *); +gboolean clientCheckSameMonitor (Client *, + Client *); + #ifdef HAVE_LIBSTARTUP_NOTIFICATION char *clientGetStartupId (Client *); #endif /* HAVE_LIBSTARTUP_NOTIFICATION */ diff --git a/src/cycle.c b/src/cycle.c index eb32a868..13e145dd 100644 --- a/src/cycle.c +++ b/src/cycle.c @@ -190,7 +190,6 @@ clientCycleActivate (Client *c) { ScreenInfo *screen_info; DisplayInfo *display_info; - Client *focused; guint workspace; if (c == NULL) @@ -201,13 +200,7 @@ clientCycleActivate (Client *c) screen_info = c->screen_info; display_info = screen_info->display_info; workspace = c->win_workspace; - focused = clientGetFocus (); - if ((focused) && (c != focused)) - { - /* We might be able to avoid this if we are about to switch workspace */ - clientAdjustFullscreenLayer (focused, FALSE); - } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN)) { /* We are explicitely activating a window that was shown before show-desktop */ diff --git a/src/focus.c b/src/focus.c index 183f4e8d..e9c76ac4 100644 --- a/src/focus.c +++ b/src/focus.c @@ -208,10 +208,6 @@ clientFocusNew(Client * c) } if (give_focus) { - if (client_focus) - { - clientAdjustFullscreenLayer (client_focus, FALSE); - } clientRaise (c, None); clientShow (c, TRUE); clientSetFocus (screen_info, c, @@ -504,7 +500,6 @@ clientUpdateFocus (ScreenInfo *screen_info, Client * c, unsigned short flags) if (c2) { clientSetNetState (c2); - clientAdjustFullscreenLayer (c2, FALSE); frameQueueDraw (c2, FALSE); clientUpdateOpacity (c2); } @@ -522,7 +517,6 @@ clientUpdateFocus (ScreenInfo *screen_info, Client * c, unsigned short flags) FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); } clientSetNetState (c); - clientAdjustFullscreenLayer (c, TRUE); frameQueueDraw (c, FALSE); clientUpdateOpacity (c); } diff --git a/src/moveresize.c b/src/moveresize.c index f0c1b4cc..64da7f41 100644 --- a/src/moveresize.c +++ b/src/moveresize.c @@ -46,6 +46,7 @@ #include "poswin.h" #include "screen.h" #include "settings.h" +#include "stacking.h" #include "transients.h" #include "event_filter.h" #include "wireframe.h" @@ -1116,6 +1117,8 @@ clientMoveEventFilter (XEvent * xevent, gpointer data) wc.x = c->x; wc.y = c->y; clientConfigure (c, &wc, changes, passdata->configure_flags); + + /* Configure applied, clear the flags */ passdata->configure_flags = NO_CFG_FLAG; } @@ -1296,6 +1299,9 @@ clientMove (Client * c, XEvent * ev) } clientConfigure (c, &wc, changes, passdata.configure_flags); + /* Lower fullscreen clients that overlap with the new position */ + clientLowerFullscreenClients(c, TRUE); + if (passdata.button != AnyButton && !passdata.released) { /* If this is a drag-move, wait for the button to be released. @@ -1694,6 +1700,9 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) gtk_main_quit (); } + /* Lower fullscreen clients that overlap with the new position */ + clientLowerFullscreenClients(c, TRUE); + return status; } @@ -1849,6 +1858,7 @@ clientResize (Client * c, int handle, XEvent * ev) } clientReconfigure (c, NO_CFG_FLAG); + if (passdata.button != AnyButton && !passdata.released) { /* If this is a drag-resize, wait for the button to be released. diff --git a/src/stacking.c b/src/stacking.c index 1d0a59a1..423f0cb6 100644 --- a/src/stacking.c +++ b/src/stacking.c @@ -322,6 +322,16 @@ clientRaise (Client * c, Window wsibling) if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED)) { + clientLowerFullscreenClients(c, FALSE); + + /* Raise fullscreen client if it was lowered before*/ + if (FLAG_TEST(c->flags, CLIENT_FLAG_FULLSCREEN) && c-> win_layer != WIN_LAYER_FULLSCREEN) + { + c->fullscreen_old_layer = c->win_layer; + c->win_layer = WIN_LAYER_FULLSCREEN; + } + + /* Copy the existing window stack temporarily as reference */ windows_stack_copy = g_list_copy (screen_info->windows_stack); /* Search for the window that will be just on top of the raised window */ @@ -529,34 +539,6 @@ clientLower (Client * c, Window wsibling) } } -gboolean -clientAdjustFullscreenLayer (Client *c, gboolean set) -{ - g_return_val_if_fail (c, FALSE); - - TRACE ("entering clientAdjustFullscreenLayer"); - TRACE ("%s fullscreen layer for \"%s\" (0x%lx)", set ? "Setting" : "Unsetting", c->name, c->window); - - if (set) - { - if (FLAG_TEST(c->flags, CLIENT_FLAG_FULLSCREEN)) - { - clientSetLayer (c, WIN_LAYER_FULLSCREEN); - return TRUE; - } - } - else if (c->win_layer == WIN_LAYER_FULLSCREEN) - { - if (FLAG_TEST(c->flags, CLIENT_FLAG_FULLSCREEN)) - { - TRACE ("Moving \"%s\" (0x%lx) to initial layer %d", c->name, c->window, c->fullscreen_old_layer); - clientSetLayer (c, c->fullscreen_old_layer); - return TRUE; - } - } - return FALSE; -} - void clientAddToList (Client * c) { @@ -714,3 +696,53 @@ clientResetDelayedRaise (ScreenInfo *screen_info) NULL, NULL); } +void +clientLowerFullscreenClients (Client *c, gboolean applyStack) +{ + ScreenInfo *screen_info; + DisplayInfo *display_info; + Client *c2; + GList *sibling; + GList *list; + gboolean changed; + + /* Never lower for a dock */ + if(c->win_layer == WIN_LAYER_DOCK) + { + return; + } + + + screen_info = c->screen_info; + display_info = screen_info->display_info; + sibling = NULL; + changed = FALSE; + + + /*Lower any fullscreen windows on the same monitor*/ + for (list = screen_info->windows_stack; list; list = g_list_next (list)) + { + c2 = (Client *) list->data; + if ((c2 != c) && FLAG_TEST(c2->flags, CLIENT_FLAG_FULLSCREEN) + && c2->win_layer == WIN_LAYER_FULLSCREEN + && c2->fullscreen_old_layer <= c->win_layer) + { + if(clientCheckSameMonitor(c, c2)) + { + c2->win_layer = c2->fullscreen_old_layer; + /* If there is one, look for its place in the list */ + sibling = g_list_find (screen_info->windows_stack, (gconstpointer) c); + /* Place the lowered window just before it */ + screen_info->windows_stack = g_list_remove (screen_info->windows_stack, (gconstpointer) c2); + screen_info->windows_stack = g_list_insert_before (screen_info->windows_stack, sibling, c2); + changed = TRUE; + } + } + } + + if(applyStack && changed) + { + clientApplyStackList (screen_info); + clientSetNetClientList (c->screen_info, display_info->atoms[NET_CLIENT_LIST_STACKING], screen_info->windows_stack); + } +} diff --git a/src/stacking.h b/src/stacking.h index cfe4121c..1dd84514 100644 --- a/src/stacking.h +++ b/src/stacking.h @@ -50,8 +50,6 @@ void clientRaise (Client *, Window); void clientLower (Client *, Window); -gboolean clientAdjustFullscreenLayer (Client *, - gboolean); void clientAddToList (Client *); void clientRemoveFromList (Client *); GList *clientGetStackList (ScreenInfo *); @@ -61,4 +59,11 @@ void clientClearLastRaise (ScreenInfo *); void clientClearDelayedRaise (void); void clientResetDelayedRaise (ScreenInfo *); +/** + * Lower fullscreen clients if the supplied client is ontop of the fullscreen clients. + * Apply the stack if set. + */ +void clientLowerFullscreenClients (Client *, + gboolean); + #endif /* INC_STACKING_H */