Merge branch 'fix-stacking' into clutter
This commit is contained in:
commit
3211fb04d3
@ -79,8 +79,14 @@ struct _MetaCompositor
|
|||||||
MetaWorkspace *to,
|
MetaWorkspace *to,
|
||||||
MetaMotionDirection direction);
|
MetaMotionDirection direction);
|
||||||
|
|
||||||
void (*ensure_stack_order) (MetaCompositor *compositor,
|
void (*sync_stack) (MetaCompositor *compositor,
|
||||||
MetaScreen *screen);
|
MetaScreen *screen,
|
||||||
|
GList *stack);
|
||||||
|
|
||||||
|
void (*set_window_hidden) (MetaCompositor *compositor,
|
||||||
|
MetaScreen *screen,
|
||||||
|
MetaWindow *window,
|
||||||
|
gboolean hidden);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -243,11 +243,25 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_compositor_ensure_stack_order (MetaCompositor *compositor,
|
meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||||
MetaScreen *screen)
|
MetaScreen *screen,
|
||||||
|
GList *stack)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
if (compositor && compositor->ensure_stack_order)
|
if (compositor && compositor->sync_stack)
|
||||||
compositor->ensure_stack_order (compositor, screen);
|
compositor->sync_stack (compositor, screen, stack);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_compositor_set_window_hidden (MetaCompositor *compositor,
|
||||||
|
MetaScreen *screen,
|
||||||
|
MetaWindow *window,
|
||||||
|
gboolean hidden)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
if (compositor && compositor->set_window_hidden)
|
||||||
|
compositor->set_window_hidden (compositor, screen, window, hidden);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -142,6 +142,7 @@ typedef struct _MetaCompScreen
|
|||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
|
|
||||||
ClutterActor *stage, *window_group, *overlay_group;
|
ClutterActor *stage, *window_group, *overlay_group;
|
||||||
|
ClutterActor *hidden_group;
|
||||||
GList *windows;
|
GList *windows;
|
||||||
GHashTable *windows_by_xid;
|
GHashTable *windows_by_xid;
|
||||||
MetaWindow *focus_window;
|
MetaWindow *focus_window;
|
||||||
@ -474,6 +475,13 @@ static MutterWindow *
|
|||||||
find_window_in_display (MetaDisplay *display, Window xwindow)
|
find_window_in_display (MetaDisplay *display, Window xwindow)
|
||||||
{
|
{
|
||||||
GSList *index;
|
GSList *index;
|
||||||
|
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
if (window->compositor_private)
|
||||||
|
return window->compositor_private;
|
||||||
|
}
|
||||||
|
|
||||||
for (index = meta_display_get_screens (display);
|
for (index = meta_display_get_screens (display);
|
||||||
index;
|
index;
|
||||||
@ -777,22 +785,18 @@ mutter_window_get_workspace (MutterWindow *mcw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mutter_window_is_hidden (MutterWindow *mcw)
|
mutter_window_showing_on_its_workspace (MutterWindow *mcw)
|
||||||
{
|
{
|
||||||
MutterWindowPrivate *priv;
|
|
||||||
|
|
||||||
if (!mcw)
|
if (!mcw)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* If override redirect: */
|
||||||
|
if (!mcw->priv->window)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
priv = mcw->priv;
|
return meta_window_showing_on_its_workspace (mcw->priv->window);
|
||||||
|
|
||||||
if (!priv->window)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return meta_window_is_hidden (priv->window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void repair_win (MutterWindow *cw);
|
static void repair_win (MutterWindow *cw);
|
||||||
static void map_win (MutterWindow *cw);
|
static void map_win (MutterWindow *cw);
|
||||||
static void unmap_win (MutterWindow *cw);
|
static void unmap_win (MutterWindow *cw);
|
||||||
@ -831,7 +835,8 @@ mutter_finish_workspace_switch (MetaCompScreen *info)
|
|||||||
l = l->prev;
|
l = l->prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Fix up stacking order in case the plugin messed it up.
|
* Fix up stacking order in case the plugin messed it up.
|
||||||
*/
|
*/
|
||||||
@ -871,6 +876,7 @@ mutter_finish_workspace_switch (MetaCompScreen *info)
|
|||||||
|
|
||||||
l = l->prev;
|
l = l->prev;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* printf ("... FINISHED DESKTOP SWITCH\n"); */
|
/* printf ("... FINISHED DESKTOP SWITCH\n"); */
|
||||||
|
|
||||||
@ -1028,6 +1034,7 @@ mutter_window_detach (MutterWindow *self)
|
|||||||
static void
|
static void
|
||||||
destroy_win (MutterWindow *cw, gboolean no_effect)
|
destroy_win (MutterWindow *cw, gboolean no_effect)
|
||||||
{
|
{
|
||||||
|
MetaWindow *window;
|
||||||
MetaCompScreen *info;
|
MetaCompScreen *info;
|
||||||
MutterWindowPrivate *priv;
|
MutterWindowPrivate *priv;
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
@ -1037,6 +1044,14 @@ destroy_win (MutterWindow *cw, gboolean no_effect)
|
|||||||
|
|
||||||
priv = cw->priv;
|
priv = cw->priv;
|
||||||
|
|
||||||
|
window = meta_display_lookup_x_window (priv->screen->display, priv->xwindow);
|
||||||
|
if (window)
|
||||||
|
window->compositor_private = NULL;
|
||||||
|
|
||||||
|
/* If not override redirect */
|
||||||
|
if (window)
|
||||||
|
window->compositor_private = NULL;
|
||||||
|
|
||||||
screen = priv->screen;
|
screen = priv->screen;
|
||||||
info = meta_screen_get_compositor_data (screen);
|
info = meta_screen_get_compositor_data (screen);
|
||||||
|
|
||||||
@ -1073,157 +1088,6 @@ destroy_win (MutterWindow *cw, gboolean no_effect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
restack_win (MutterWindow *cw, Window above)
|
|
||||||
{
|
|
||||||
MutterWindowPrivate *priv = cw->priv;
|
|
||||||
MetaScreen *screen = priv->screen;
|
|
||||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
|
||||||
Window previous_above;
|
|
||||||
GList *sibling, *next;
|
|
||||||
gboolean hide = FALSE;
|
|
||||||
gboolean live_mode;
|
|
||||||
|
|
||||||
live_mode = meta_prefs_get_live_hidden_windows ();
|
|
||||||
|
|
||||||
if (priv->window && meta_window_is_hidden (priv->window))
|
|
||||||
hide = TRUE;
|
|
||||||
|
|
||||||
sibling = g_list_find (info->windows, (gconstpointer) cw);
|
|
||||||
next = g_list_next (sibling);
|
|
||||||
previous_above = None;
|
|
||||||
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
MutterWindow *ncw = next->data;
|
|
||||||
previous_above = ncw->priv->xwindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If above is set to None, the window whose state was changed is on
|
|
||||||
* the bottom of the stack with respect to sibling.
|
|
||||||
*/
|
|
||||||
if (above == None)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
printf ("Raising to top %p [0x%x] (%s)\n",
|
|
||||||
cw, (guint) priv->xwindow,
|
|
||||||
priv->window ? priv->window->desc : "unknown");
|
|
||||||
#endif
|
|
||||||
/* Insert at bottom of window stack */
|
|
||||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
|
||||||
info->windows = g_list_delete_link (info->windows, sibling);
|
|
||||||
info->windows = g_list_append (info->windows, cw);
|
|
||||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
|
||||||
|
|
||||||
if (!info->switch_workspace_in_progress)
|
|
||||||
{
|
|
||||||
clutter_actor_raise_top (CLUTTER_ACTOR (cw));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (previous_above != above)
|
|
||||||
{
|
|
||||||
GList *index;
|
|
||||||
|
|
||||||
/* Find the window that matches 'above'; if the window is hidden (i.e.,
|
|
||||||
* minimized, on a different desktop) find the first window above it tha
|
|
||||||
* is not and use it instead; if we cannot find any such window then
|
|
||||||
* fallback to raise to top (without this, we end up stacking up the act
|
|
||||||
* in the wrong place, and it probably will not be visible at all).
|
|
||||||
*/
|
|
||||||
for (index = info->windows; index; index = index->next)
|
|
||||||
{
|
|
||||||
MutterWindow *cw2 = (MutterWindow *) index->data;
|
|
||||||
if (cw2->priv->xwindow == above)
|
|
||||||
{
|
|
||||||
if (live_mode && !hide && cw2->priv->window &&
|
|
||||||
meta_window_is_hidden (cw2->priv->window))
|
|
||||||
{
|
|
||||||
index = index->prev;
|
|
||||||
|
|
||||||
while (index)
|
|
||||||
{
|
|
||||||
MutterWindow *prev = index->data;
|
|
||||||
|
|
||||||
if (!prev->priv->window ||
|
|
||||||
!meta_window_is_hidden (prev->priv->window))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = index->prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index != NULL)
|
|
||||||
{
|
|
||||||
if (index != sibling)
|
|
||||||
{
|
|
||||||
ClutterActor *above_win = index->data;
|
|
||||||
|
|
||||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
|
||||||
info->windows = g_list_delete_link (info->windows, sibling);
|
|
||||||
|
|
||||||
info->windows = g_list_insert_before (info->windows, index, cw);
|
|
||||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf ("Raising %p [0x%x] (%s) hidden %d, above %p [0x%x] (%s)\n",
|
|
||||||
cw, (guint) priv->xwindow,
|
|
||||||
priv->window ? priv->window->desc : "unknown", hide,
|
|
||||||
cw2, (guint) cw2->priv->xwindow,
|
|
||||||
cw2->priv->window ? cw2->priv->window->desc : "unknown");
|
|
||||||
#endif
|
|
||||||
if (!info->switch_workspace_in_progress)
|
|
||||||
{
|
|
||||||
clutter_actor_raise (CLUTTER_ACTOR (cw), above_win);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (live_mode)
|
|
||||||
{
|
|
||||||
if (!hide)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
printf ("Raising to top as fallback %p [0x%x] (%s)\n",
|
|
||||||
cw, (guint) priv->xwindow,
|
|
||||||
priv->window ? priv->window->desc : "unknown");
|
|
||||||
#endif
|
|
||||||
/* Insert at bottom of window stack */
|
|
||||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
|
||||||
info->windows = g_list_delete_link (info->windows, sibling);
|
|
||||||
info->windows = g_list_append (info->windows, cw);
|
|
||||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
|
||||||
|
|
||||||
if (!info->switch_workspace_in_progress)
|
|
||||||
{
|
|
||||||
clutter_actor_raise_top (CLUTTER_ACTOR (cw));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
printf ("Lowering to bottom as fallback %p [0x%x] (%s)\n",
|
|
||||||
cw, (guint) priv->xwindow,
|
|
||||||
priv->window ? priv->window->desc : "unknown");
|
|
||||||
#endif
|
|
||||||
/* Insert at bottom of window stack */
|
|
||||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
|
||||||
info->windows = g_list_delete_link (info->windows, sibling);
|
|
||||||
info->windows = g_list_prepend (info->windows, cw);
|
|
||||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
|
||||||
|
|
||||||
if (!info->switch_workspace_in_progress)
|
|
||||||
{
|
|
||||||
clutter_actor_lower_bottom (CLUTTER_ACTOR (cw));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resize_win (MutterWindow *cw,
|
resize_win (MutterWindow *cw,
|
||||||
int x,
|
int x,
|
||||||
@ -1361,6 +1225,20 @@ add_win (MetaScreen *screen, MetaWindow *window, Window xwindow)
|
|||||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||||
XWindowAttributes attrs;
|
XWindowAttributes attrs;
|
||||||
gulong events_needed;
|
gulong events_needed;
|
||||||
|
|
||||||
|
/* Note: this blacklist internal windows is copied from screen.c
|
||||||
|
* Ideally add_win shouldn't be driven by CreateNotify events and
|
||||||
|
* should instead be an event directly from metacity core. */
|
||||||
|
if (xwindow == screen->no_focus_window ||
|
||||||
|
xwindow == screen->flash_window ||
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
xwindow == screen->wm_cm_selection_window ||
|
||||||
|
xwindow == screen->guard_window ||
|
||||||
|
#endif
|
||||||
|
xwindow == screen->wm_sn_selection_window) {
|
||||||
|
meta_verbose ("Not managing our own windows\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (info == NULL)
|
if (info == NULL)
|
||||||
return;
|
return;
|
||||||
@ -1446,6 +1324,11 @@ add_win (MetaScreen *screen, MetaWindow *window, Window xwindow)
|
|||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Hang our compositor window state off the MetaWindow for fast retrieval
|
||||||
|
* if we have one */
|
||||||
|
if (window)
|
||||||
|
window->compositor_private = cw;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add this to the list at the top of the stack before it is mapped so that
|
* Add this to the list at the top of the stack before it is mapped so that
|
||||||
@ -1530,7 +1413,7 @@ repair_win (MutterWindow *cw)
|
|||||||
full = TRUE;
|
full = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO -- on some gfx hardware updating the whole texture instead of
|
* TODO -- on some gfx hardware updating the whole texture instead of
|
||||||
* the individual rectangles is actually quicker, so we might want to
|
* the individual rectangles is actually quicker, so we might want to
|
||||||
* make this a configurable option (on desktop HW with multiple pipelines
|
* make this a configurable option (on desktop HW with multiple pipelines
|
||||||
@ -1601,7 +1484,7 @@ process_create (Mutter *compositor,
|
|||||||
{
|
{
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
Window xwindow = event->window;
|
Window xwindow = event->window;
|
||||||
MutterWindow *mw;
|
MutterWindow *cw;
|
||||||
|
|
||||||
screen = meta_display_screen_for_root (compositor->display, event->parent);
|
screen = meta_display_screen_for_root (compositor->display, event->parent);
|
||||||
|
|
||||||
@ -1612,18 +1495,18 @@ process_create (Mutter *compositor,
|
|||||||
* This is quite silly as we end up creating windows as then immediatly
|
* This is quite silly as we end up creating windows as then immediatly
|
||||||
* destroying them as they (likely) become framed and thus reparented.
|
* destroying them as they (likely) become framed and thus reparented.
|
||||||
*/
|
*/
|
||||||
mw = find_window_for_screen (screen, xwindow);
|
cw = find_window_for_screen (screen, xwindow);
|
||||||
|
|
||||||
if (!mw && window)
|
if (!cw && window)
|
||||||
{
|
{
|
||||||
xwindow = meta_window_get_xwindow (window);
|
xwindow = meta_window_get_xwindow (window);
|
||||||
|
|
||||||
mw = find_window_for_screen (screen, xwindow);
|
cw = find_window_for_screen (screen, xwindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mw)
|
if (cw)
|
||||||
{
|
{
|
||||||
destroy_win (mw, TRUE);
|
destroy_win (cw, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_win (screen, window, event->window);
|
add_win (screen, window, event->window);
|
||||||
@ -1635,7 +1518,7 @@ process_reparent (Mutter *compositor,
|
|||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
MutterWindow *mw;
|
MutterWindow *cw;
|
||||||
Window xwindow = event->window;
|
Window xwindow = event->window;
|
||||||
gboolean viewable = FALSE;
|
gboolean viewable = FALSE;
|
||||||
|
|
||||||
@ -1643,28 +1526,16 @@ process_reparent (Mutter *compositor,
|
|||||||
|
|
||||||
if (!screen)
|
if (!screen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
cw = window->compositor_private;
|
||||||
|
else
|
||||||
|
cw = find_window_for_screen (screen, xwindow);
|
||||||
|
|
||||||
mw = find_window_for_screen (screen, xwindow);
|
if (cw)
|
||||||
|
|
||||||
if (!mw && window)
|
|
||||||
{
|
{
|
||||||
xwindow = meta_window_get_xwindow (window);
|
viewable = (cw->priv->attrs.map_state == IsViewable);
|
||||||
|
destroy_win (cw, TRUE);
|
||||||
mw = find_window_for_screen (screen, xwindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mw && window)
|
|
||||||
{
|
|
||||||
xwindow = meta_window_get_xwindow (window);
|
|
||||||
|
|
||||||
mw = find_window_for_screen (screen, xwindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (mw)
|
|
||||||
{
|
|
||||||
viewable = (mw->priv->attrs.map_state == IsViewable);
|
|
||||||
destroy_win (mw, TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_win (screen, window, event->window);
|
add_win (screen, window, event->window);
|
||||||
@ -1755,11 +1626,11 @@ update_shape (Mutter *compositor,
|
|||||||
|
|
||||||
#ifdef HAVE_SHAPE
|
#ifdef HAVE_SHAPE
|
||||||
static void
|
static void
|
||||||
process_shape (Mutter *compositor,
|
process_shape (Mutter *compositor,
|
||||||
XShapeEvent *event)
|
XShapeEvent *event)
|
||||||
{
|
{
|
||||||
MutterWindow *cw = find_window_in_display (compositor->display,
|
MutterWindow *cw = find_window_in_display (compositor->display,
|
||||||
event->window);
|
event->window);
|
||||||
MutterWindowPrivate *priv = cw->priv;
|
MutterWindowPrivate *priv = cw->priv;
|
||||||
|
|
||||||
if (cw == NULL)
|
if (cw == NULL)
|
||||||
@ -1793,7 +1664,6 @@ process_configure_notify (Mutter *compositor,
|
|||||||
|
|
||||||
if (cw)
|
if (cw)
|
||||||
{
|
{
|
||||||
restack_win (cw, event->above);
|
|
||||||
resize_win (cw,
|
resize_win (cw,
|
||||||
event->x, event->y, event->width, event->height,
|
event->x, event->y, event->width, event->height,
|
||||||
event->border_width, event->override_redirect);
|
event->border_width, event->override_redirect);
|
||||||
@ -1831,47 +1701,20 @@ process_configure_notify (Mutter *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_circulate_notify (Mutter *compositor,
|
process_unmap (Mutter *compositor,
|
||||||
XCirculateEvent *event)
|
XUnmapEvent *event)
|
||||||
{
|
{
|
||||||
MutterWindow *cw = find_window_in_display (compositor->display,
|
MutterWindow *cw;
|
||||||
event->window);
|
Window xwin = event->window;
|
||||||
MutterWindow *top;
|
Display *dpy = event->display;
|
||||||
MetaCompScreen *info;
|
|
||||||
Window above;
|
|
||||||
MutterWindowPrivate *priv;
|
|
||||||
|
|
||||||
if (!cw)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv = cw->priv;
|
|
||||||
|
|
||||||
info = meta_screen_get_compositor_data (priv->screen);
|
|
||||||
top = info->windows->data;
|
|
||||||
|
|
||||||
if ((event->place == PlaceOnTop) && top)
|
|
||||||
above = top->priv->xwindow;
|
|
||||||
else
|
|
||||||
above = None;
|
|
||||||
|
|
||||||
restack_win (cw, above);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
process_unmap (Mutter *compositor,
|
|
||||||
XUnmapEvent *event)
|
|
||||||
{
|
|
||||||
MutterWindow *cw;
|
|
||||||
Window xwin = event->window;
|
|
||||||
Display *dpy = event->display;
|
|
||||||
|
|
||||||
if (event->from_configure)
|
if (event->from_configure)
|
||||||
{
|
{
|
||||||
/* Ignore unmap caused by parent's resize */
|
/* Ignore unmap caused by parent's resize */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw = find_window_in_display (compositor->display, xwin);
|
cw = find_window_in_display (compositor->display, event->window);
|
||||||
|
|
||||||
if (cw)
|
if (cw)
|
||||||
{
|
{
|
||||||
@ -1899,8 +1742,11 @@ process_map (Mutter *compositor,
|
|||||||
{
|
{
|
||||||
MutterWindow *cw;
|
MutterWindow *cw;
|
||||||
Window xwindow = event->window;
|
Window xwindow = event->window;
|
||||||
|
|
||||||
cw = find_window_in_display (compositor->display, xwindow);
|
if (window)
|
||||||
|
cw = window->compositor_private;
|
||||||
|
else
|
||||||
|
cw = find_window_in_display (compositor->display, xwindow);
|
||||||
|
|
||||||
if (cw)
|
if (cw)
|
||||||
{
|
{
|
||||||
@ -1909,8 +1755,8 @@ process_map (Mutter *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_property_notify (Mutter *compositor,
|
process_property_notify (Mutter *compositor,
|
||||||
XPropertyEvent *event)
|
XPropertyEvent *event)
|
||||||
{
|
{
|
||||||
MetaDisplay *display = compositor->display;
|
MetaDisplay *display = compositor->display;
|
||||||
|
|
||||||
@ -1918,7 +1764,7 @@ process_property_notify (Mutter *compositor,
|
|||||||
if (event->atom == compositor->atom_net_wm_window_opacity)
|
if (event->atom == compositor->atom_net_wm_window_opacity)
|
||||||
{
|
{
|
||||||
MutterWindow *cw = find_window_in_display (display, event->window);
|
MutterWindow *cw = find_window_in_display (display, event->window);
|
||||||
gulong value;
|
gulong value;
|
||||||
|
|
||||||
if (!cw)
|
if (!cw)
|
||||||
{
|
{
|
||||||
@ -2103,13 +1949,18 @@ clutter_cmp_manage_screen (MetaCompositor *compositor,
|
|||||||
KeyPressMask | KeyReleaseMask);
|
KeyPressMask | KeyReleaseMask);
|
||||||
|
|
||||||
info->window_group = clutter_group_new ();
|
info->window_group = clutter_group_new ();
|
||||||
|
g_object_set_property (G_OBJECT (info->window_group),
|
||||||
|
"show-on-set-parent", FALSE);
|
||||||
info->overlay_group = clutter_group_new ();
|
info->overlay_group = clutter_group_new ();
|
||||||
|
info->hidden_group = clutter_group_new ();
|
||||||
|
|
||||||
clutter_container_add (CLUTTER_CONTAINER (info->stage),
|
clutter_container_add (CLUTTER_CONTAINER (info->stage),
|
||||||
info->window_group,
|
info->window_group,
|
||||||
info->overlay_group,
|
info->overlay_group,
|
||||||
|
info->hidden_group,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
clutter_actor_hide (info->hidden_group);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must do this *before* creating the plugin manager, in case any of the
|
* Must do this *before* creating the plugin manager, in case any of the
|
||||||
@ -2224,10 +2075,6 @@ clutter_cmp_process_event (MetaCompositor *compositor,
|
|||||||
meta_error_trap_push (xrc->display);
|
meta_error_trap_push (xrc->display);
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case CirculateNotify:
|
|
||||||
process_circulate_notify (xrc, (XCirculateEvent *) event);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
process_configure_notify (xrc, (XConfigureEvent *) event);
|
process_configure_notify (xrc, (XConfigureEvent *) event);
|
||||||
break;
|
break;
|
||||||
@ -2460,9 +2307,11 @@ clutter_cmp_switch_workspace (MetaCompositor *compositor,
|
|||||||
info = meta_screen_get_compositor_data (screen);
|
info = meta_screen_get_compositor_data (screen);
|
||||||
to_indx = meta_workspace_index (to);
|
to_indx = meta_workspace_index (to);
|
||||||
from_indx = meta_workspace_index (from);
|
from_indx = meta_workspace_index (from);
|
||||||
|
|
||||||
if (!meta_prefs_get_live_hidden_windows ())
|
if (!meta_prefs_get_live_hidden_windows ())
|
||||||
{
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We are in the traditional mode where hidden windows get unmapped,
|
* We are in the traditional mode where hidden windows get unmapped,
|
||||||
* we need to pre-calculate the map status of each window so that once
|
* we need to pre-calculate the map status of each window so that once
|
||||||
@ -2470,14 +2319,12 @@ clutter_cmp_switch_workspace (MetaCompositor *compositor,
|
|||||||
* (we need to ignore the map notifications during the effect so that
|
* (we need to ignore the map notifications during the effect so that
|
||||||
* actors do not just disappear while the effect is running).
|
* actors do not just disappear while the effect is running).
|
||||||
*/
|
*/
|
||||||
GList *l = info->windows;
|
for (l = info->windows; l != NULL; l = l->next)
|
||||||
|
|
||||||
while (l)
|
|
||||||
{
|
{
|
||||||
MutterWindow *cw = l->data;
|
MutterWindow *cw = l->data;
|
||||||
MetaWindow *mw = cw->priv->window;
|
MetaWindow *mw = cw->priv->window;
|
||||||
gboolean sticky;
|
gboolean sticky;
|
||||||
gint workspace = -1;
|
gint workspace = -1;
|
||||||
|
|
||||||
sticky = (!mw || meta_window_is_on_all_workspaces (mw));
|
sticky = (!mw || meta_window_is_on_all_workspaces (mw));
|
||||||
|
|
||||||
@ -2502,8 +2349,6 @@ clutter_cmp_switch_workspace (MetaCompositor *compositor,
|
|||||||
cw->priv->needs_unmap = FALSE;
|
cw->priv->needs_unmap = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l = l->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2529,33 +2374,58 @@ clutter_cmp_switch_workspace (MetaCompositor *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_cmp_ensure_stack_order (MetaCompositor *compositor,
|
clutter_cmp_sync_stack (MetaCompositor *compositor,
|
||||||
MetaScreen *screen)
|
MetaScreen *screen,
|
||||||
|
GList *stack)
|
||||||
{
|
{
|
||||||
|
GList *tmp;
|
||||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||||
GList *l = g_list_last (info->windows);
|
|
||||||
|
for (tmp = stack; tmp != NULL; tmp = tmp->next)
|
||||||
while (l)
|
|
||||||
{
|
{
|
||||||
ClutterActor *a = l->data;
|
MetaWindow *window = tmp->data;
|
||||||
MutterWindow *mw = l->data;
|
MutterWindow *cw = window->compositor_private;
|
||||||
MetaWindow *window = mw->priv->window;
|
GList *link;
|
||||||
|
|
||||||
/*
|
if (!cw)
|
||||||
* If this window is not marked as hidden, we raise it.
|
|
||||||
* If it has no MetaWindow associated (i.e., override redirect), we
|
|
||||||
* raise it too. Everything else we push to the bottom.
|
|
||||||
*/
|
|
||||||
if (!window || !meta_window_is_hidden (window))
|
|
||||||
{
|
{
|
||||||
clutter_actor_raise_top (a);
|
meta_verbose ("Failed to find corresponding MutterWindow "
|
||||||
}
|
"for window %p\n", window);
|
||||||
else
|
continue;
|
||||||
{
|
|
||||||
clutter_actor_lower_bottom (a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clutter_actor_lower_bottom (CLUTTER_ACTOR (cw));
|
||||||
|
|
||||||
l = l->prev;
|
/* Also maintain the order of info->windows */
|
||||||
|
info->windows = g_list_remove (info->windows, (gconstpointer)cw);
|
||||||
|
info->windows = g_list_prepend (info->windows, cw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cmp_set_window_hidden (MetaCompositor *compositor,
|
||||||
|
MetaScreen *screen,
|
||||||
|
MetaWindow *window,
|
||||||
|
gboolean hidden)
|
||||||
|
{
|
||||||
|
MutterWindow *cw = window->compositor_private;
|
||||||
|
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||||
|
|
||||||
|
g_return_if_fail (cw);
|
||||||
|
|
||||||
|
if (hidden)
|
||||||
|
{
|
||||||
|
/* FIXME: There needs to be a way to queue this if there is an effect
|
||||||
|
* in progress for this window */
|
||||||
|
if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group)
|
||||||
|
clutter_actor_reparent (CLUTTER_ACTOR (cw),
|
||||||
|
info->hidden_group);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->window_group)
|
||||||
|
clutter_actor_reparent (CLUTTER_ACTOR (cw),
|
||||||
|
info->window_group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2575,7 +2445,8 @@ static MetaCompositor comp_info = {
|
|||||||
clutter_cmp_unmaximize_window,
|
clutter_cmp_unmaximize_window,
|
||||||
clutter_cmp_update_workspace_geometry,
|
clutter_cmp_update_workspace_geometry,
|
||||||
clutter_cmp_switch_workspace,
|
clutter_cmp_switch_workspace,
|
||||||
clutter_cmp_ensure_stack_order,
|
clutter_cmp_sync_stack,
|
||||||
|
clutter_cmp_set_window_hidden
|
||||||
};
|
};
|
||||||
|
|
||||||
MetaCompositor *
|
MetaCompositor *
|
||||||
|
@ -132,6 +132,11 @@ struct _MetaScreen
|
|||||||
|
|
||||||
/* Managed by compositor.c */
|
/* Managed by compositor.c */
|
||||||
gpointer compositor_data;
|
gpointer compositor_data;
|
||||||
|
|
||||||
|
/* Instead of unmapping withdrawn windows we can leave them mapped
|
||||||
|
* and restack them below a guard window. When using a compositor
|
||||||
|
* this allows us to provide live previews of unmapped windows */
|
||||||
|
Window guard_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
MetaScreen* meta_screen_new (MetaDisplay *display,
|
MetaScreen* meta_screen_new (MetaDisplay *display,
|
||||||
|
@ -311,6 +311,38 @@ reload_xinerama_infos (MetaScreen *screen)
|
|||||||
g_assert (screen->xinerama_infos != NULL);
|
g_assert (screen->xinerama_infos != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The guard window allows us to leave minimized windows mapped so
|
||||||
|
* that compositor code may provide live previews of them.
|
||||||
|
* Instead of being unmapped/withdrawn, they get pushed underneath
|
||||||
|
* the guard window. */
|
||||||
|
static Window
|
||||||
|
create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||||
|
{
|
||||||
|
XSetWindowAttributes attributes;
|
||||||
|
Window guard_window;
|
||||||
|
|
||||||
|
attributes.event_mask = NoEventMask;
|
||||||
|
attributes.override_redirect = True;
|
||||||
|
attributes.background_pixel = BlackPixel (xdisplay, screen->number);
|
||||||
|
|
||||||
|
guard_window =
|
||||||
|
XCreateWindow (xdisplay,
|
||||||
|
screen->xroot,
|
||||||
|
0, /* x */
|
||||||
|
0, /* y */
|
||||||
|
screen->rect.width,
|
||||||
|
screen->rect.height,
|
||||||
|
0, /* border width */
|
||||||
|
CopyFromParent, /* depth */
|
||||||
|
CopyFromParent, /* class */
|
||||||
|
CopyFromParent, /* visual */
|
||||||
|
CWEventMask|CWOverrideRedirect|CWBackPixel,
|
||||||
|
&attributes);
|
||||||
|
XLowerWindow (xdisplay, guard_window);
|
||||||
|
XMapWindow (xdisplay, guard_window);
|
||||||
|
return guard_window;
|
||||||
|
}
|
||||||
|
|
||||||
MetaScreen*
|
MetaScreen*
|
||||||
meta_screen_new (MetaDisplay *display,
|
meta_screen_new (MetaDisplay *display,
|
||||||
int number,
|
int number,
|
||||||
@ -490,6 +522,8 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
screen->vertical_workspaces = FALSE;
|
screen->vertical_workspaces = FALSE;
|
||||||
screen->starting_corner = META_SCREEN_TOPLEFT;
|
screen->starting_corner = META_SCREEN_TOPLEFT;
|
||||||
screen->compositor_data = NULL;
|
screen->compositor_data = NULL;
|
||||||
|
|
||||||
|
screen->guard_window = create_guard_window (xdisplay, screen);
|
||||||
|
|
||||||
{
|
{
|
||||||
XFontStruct *font_info;
|
XFontStruct *font_info;
|
||||||
@ -760,6 +794,7 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
|||||||
info->xwindow == screen->flash_window ||
|
info->xwindow == screen->flash_window ||
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
info->xwindow == screen->wm_cm_selection_window ||
|
info->xwindow == screen->wm_cm_selection_window ||
|
||||||
|
info->xwindow == screen->guard_window ||
|
||||||
#endif
|
#endif
|
||||||
info->xwindow == screen->wm_sn_selection_window) {
|
info->xwindow == screen->wm_sn_selection_window) {
|
||||||
meta_verbose ("Not managing our own windows\n");
|
meta_verbose ("Not managing our own windows\n");
|
||||||
@ -772,17 +807,6 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
|||||||
}
|
}
|
||||||
meta_stack_thaw (screen->stack);
|
meta_stack_thaw (screen->stack);
|
||||||
|
|
||||||
/*
|
|
||||||
* Because the windows have already been created/mapped/etc, if the compositor
|
|
||||||
* maintains a separate stack based on ConfigureNotify restack messages, it
|
|
||||||
* will not necessarily get what it needs; we explicitely notify the
|
|
||||||
* compositor to fix up its stacking order.
|
|
||||||
*
|
|
||||||
* For more on this issue, see comments in meta_window_hide().
|
|
||||||
*/
|
|
||||||
if (screen->display->compositor)
|
|
||||||
meta_compositor_ensure_stack_order (screen->display->compositor, screen);
|
|
||||||
|
|
||||||
g_list_foreach (windows, (GFunc)g_free, NULL);
|
g_list_foreach (windows, (GFunc)g_free, NULL);
|
||||||
g_list_free (windows);
|
g_list_free (windows);
|
||||||
|
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
#include "compositor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
|
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
|
||||||
@ -1057,6 +1061,7 @@ stack_sync_to_server (MetaStack *stack)
|
|||||||
GArray *stacked;
|
GArray *stacked;
|
||||||
GArray *root_children_stacked;
|
GArray *root_children_stacked;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
GArray *all_hidden;
|
||||||
|
|
||||||
/* Bail out if frozen */
|
/* Bail out if frozen */
|
||||||
if (stack->freeze_count > 0)
|
if (stack->freeze_count > 0)
|
||||||
@ -1065,6 +1070,10 @@ stack_sync_to_server (MetaStack *stack)
|
|||||||
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
||||||
|
|
||||||
stack_ensure_sorted (stack);
|
stack_ensure_sorted (stack);
|
||||||
|
|
||||||
|
meta_compositor_sync_stack (stack->screen->display->compositor,
|
||||||
|
stack->screen,
|
||||||
|
stack->sorted);
|
||||||
|
|
||||||
/* Create stacked xwindow arrays.
|
/* Create stacked xwindow arrays.
|
||||||
* Painfully, "stacked" is in bottom-to-top order for the
|
* Painfully, "stacked" is in bottom-to-top order for the
|
||||||
@ -1073,29 +1082,42 @@ stack_sync_to_server (MetaStack *stack)
|
|||||||
*/
|
*/
|
||||||
stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||||
root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||||
|
all_hidden = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||||
|
|
||||||
|
/* The screen guard window sits above all hidden windows and acts as
|
||||||
|
* a barrier to input reaching these windows. */
|
||||||
|
g_array_append_val (all_hidden, stack->screen->guard_window);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
||||||
meta_push_no_msg_prefix ();
|
meta_push_no_msg_prefix ();
|
||||||
|
|
||||||
tmp = stack->sorted;
|
for (tmp = stack->sorted; tmp != NULL; tmp = tmp->next)
|
||||||
while (tmp != NULL)
|
|
||||||
{
|
{
|
||||||
MetaWindow *w;
|
MetaWindow *w = tmp->data;
|
||||||
|
Window top_level_window;
|
||||||
w = tmp->data;
|
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
||||||
|
w->layer, w->stack_position, w->desc);
|
||||||
|
|
||||||
/* remember, stacked is in reverse order (bottom to top) */
|
/* remember, stacked is in reverse order (bottom to top) */
|
||||||
g_array_prepend_val (stacked, w->xwindow);
|
g_array_prepend_val (stacked, w->xwindow);
|
||||||
|
|
||||||
/* build XRestackWindows() array from top to bottom */
|
|
||||||
if (w->frame)
|
if (w->frame)
|
||||||
g_array_append_val (root_children_stacked, w->frame->xwindow);
|
top_level_window = w->frame->xwindow;
|
||||||
else
|
else
|
||||||
g_array_append_val (root_children_stacked, w->xwindow);
|
top_level_window = w->xwindow;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "%u:%d - %s ", w->layer, w->stack_position, w->desc);
|
/* We don't restack hidden windows along with the rest, though they are
|
||||||
|
* reflected in the _NET hints. Hidden windows all get pushed below
|
||||||
tmp = tmp->next;
|
* the screens fullscreen guard_window. */
|
||||||
|
if (w->hidden)
|
||||||
|
{
|
||||||
|
g_array_append_val (all_hidden, top_level_window);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build XRestackWindows() array from top to bottom */
|
||||||
|
g_array_append_val (root_children_stacked, top_level_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "\n");
|
meta_topic (META_DEBUG_STACK, "\n");
|
||||||
@ -1213,6 +1235,13 @@ stack_sync_to_server (MetaStack *stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Push hidden windows to the bottom of the stack under the guard window */
|
||||||
|
XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window);
|
||||||
|
XRestackWindows (stack->screen->display->xdisplay,
|
||||||
|
(Window *)all_hidden->data,
|
||||||
|
all_hidden->len);
|
||||||
|
g_array_free (all_hidden, TRUE);
|
||||||
|
|
||||||
meta_error_trap_pop (stack->screen->display, FALSE);
|
meta_error_trap_pop (stack->screen->display, FALSE);
|
||||||
/* on error, a window was destroyed; it should eventually
|
/* on error, a window was destroyed; it should eventually
|
||||||
* get removed from the stacking list when we unmanage it
|
* get removed from the stacking list when we unmanage it
|
||||||
|
@ -348,6 +348,10 @@ struct _MetaWindow
|
|||||||
|
|
||||||
/* maintained by group.c */
|
/* maintained by group.c */
|
||||||
MetaGroup *group;
|
MetaGroup *group;
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
void *compositor_private;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These differ from window->has_foo_func in that they consider
|
/* These differ from window->has_foo_func in that they consider
|
||||||
@ -424,9 +428,6 @@ void meta_window_resize_with_gravity (MetaWindow *window,
|
|||||||
int gravity);
|
int gravity);
|
||||||
|
|
||||||
|
|
||||||
/* Return whether the window would be showing if we were on its workspace */
|
|
||||||
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
|
|
||||||
|
|
||||||
/* Return whether the window should be currently mapped */
|
/* Return whether the window should be currently mapped */
|
||||||
gboolean meta_window_should_be_showing (MetaWindow *window);
|
gboolean meta_window_should_be_showing (MetaWindow *window);
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
/* if already mapped, no need to worry about focus-on-first-time-showing */
|
/* if already mapped, no need to worry about focus-on-first-time-showing */
|
||||||
window->showing_for_first_time = !window->mapped;
|
window->showing_for_first_time = !window->mapped;
|
||||||
/* if already mapped we don't want to do the placement thing */
|
/* if already mapped we don't want to do the placement thing */
|
||||||
window->placed = window->mapped;
|
window->placed = (window->mapped && !window->hidden);
|
||||||
if (window->placed)
|
if (window->placed)
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Not placing window 0x%lx since it's already mapped\n",
|
"Not placing window 0x%lx since it's already mapped\n",
|
||||||
@ -558,6 +558,8 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
window->stack_position = -1;
|
window->stack_position = -1;
|
||||||
window->initial_workspace = 0; /* not used */
|
window->initial_workspace = 0; /* not used */
|
||||||
window->initial_timestamp = 0; /* not used */
|
window->initial_timestamp = 0; /* not used */
|
||||||
|
|
||||||
|
window->compositor_private = NULL;
|
||||||
|
|
||||||
meta_display_register_x_window (display, &window->xwindow, window);
|
meta_display_register_x_window (display, &window->xwindow, window);
|
||||||
|
|
||||||
@ -1459,7 +1461,7 @@ implement_showing (MetaWindow *window,
|
|||||||
* be minimized, and we are on the current workspace.
|
* be minimized, and we are on the current workspace.
|
||||||
*/
|
*/
|
||||||
if (on_workspace && window->minimized && window->mapped &&
|
if (on_workspace && window->minimized && window->mapped &&
|
||||||
!meta_prefs_get_reduced_resources ())
|
!window->hidden && !meta_prefs_get_reduced_resources ())
|
||||||
{
|
{
|
||||||
MetaRectangle icon_rect, window_rect;
|
MetaRectangle icon_rect, window_rect;
|
||||||
gboolean result;
|
gboolean result;
|
||||||
@ -2244,38 +2246,41 @@ meta_window_show (MetaWindow *window)
|
|||||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||||
meta_error_trap_pop (window->display, FALSE);
|
meta_error_trap_pop (window->display, FALSE);
|
||||||
did_show = TRUE;
|
did_show = TRUE;
|
||||||
window->hidden = FALSE;
|
|
||||||
}
|
}
|
||||||
else if (meta_prefs_get_live_hidden_windows ())
|
|
||||||
|
if (meta_prefs_get_live_hidden_windows ())
|
||||||
{
|
{
|
||||||
if (window->hidden && window->type != META_WINDOW_DESKTOP)
|
if (window->hidden)
|
||||||
{
|
{
|
||||||
window->hidden = FALSE;
|
|
||||||
meta_stack_freeze (window->screen->stack);
|
meta_stack_freeze (window->screen->stack);
|
||||||
meta_window_update_layer (window);
|
window->hidden = FALSE;
|
||||||
meta_window_raise (window);
|
/* Inform the compositor that the window isn't hidden */
|
||||||
|
meta_compositor_set_window_hidden (window->display->compositor,
|
||||||
|
window->screen,
|
||||||
|
window,
|
||||||
|
window->hidden);
|
||||||
meta_stack_thaw (window->screen->stack);
|
meta_stack_thaw (window->screen->stack);
|
||||||
did_show = TRUE;
|
did_show = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (did_show && window->was_minimized)
|
if (did_show && window->was_minimized)
|
||||||
{
|
{
|
||||||
MetaRectangle window_rect;
|
MetaRectangle window_rect;
|
||||||
MetaRectangle icon_rect;
|
MetaRectangle icon_rect;
|
||||||
|
|
||||||
window->was_minimized = FALSE;
|
window->was_minimized = FALSE;
|
||||||
|
|
||||||
if (meta_window_get_icon_geometry (window, &icon_rect))
|
if (meta_window_get_icon_geometry (window, &icon_rect))
|
||||||
{
|
{
|
||||||
meta_window_get_outer_rect (window, &window_rect);
|
meta_window_get_outer_rect (window, &window_rect);
|
||||||
|
|
||||||
meta_effect_run_unminimize (window,
|
meta_effect_run_unminimize (window,
|
||||||
&window_rect,
|
&window_rect,
|
||||||
&icon_rect,
|
&icon_rect,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->iconic)
|
if (window->iconic)
|
||||||
{
|
{
|
||||||
@ -2331,50 +2336,34 @@ meta_window_hide (MetaWindow *window)
|
|||||||
|
|
||||||
if (meta_prefs_get_live_hidden_windows ())
|
if (meta_prefs_get_live_hidden_windows ())
|
||||||
{
|
{
|
||||||
gboolean was_mapped;
|
|
||||||
|
|
||||||
if (window->hidden)
|
if (window->hidden)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
was_mapped = window->mapped;
|
if (!window->mapped)
|
||||||
|
{
|
||||||
if (!was_mapped)
|
Window top_level_window;
|
||||||
meta_window_show (window);
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||||
|
"%s actually needs map\n", window->desc);
|
||||||
window->hidden = TRUE;
|
window->mapped = TRUE;
|
||||||
did_hide = TRUE;
|
meta_error_trap_push (window->display);
|
||||||
|
if (window->frame)
|
||||||
|
top_level_window = window->frame->xwindow;
|
||||||
|
else
|
||||||
|
top_level_window = window->xwindow;
|
||||||
|
XMapWindow (window->display->xdisplay, top_level_window);
|
||||||
|
meta_error_trap_pop (window->display, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
meta_stack_freeze (window->screen->stack);
|
meta_stack_freeze (window->screen->stack);
|
||||||
meta_window_update_layer (window);
|
window->hidden = TRUE;
|
||||||
meta_window_lower (window);
|
/* Tell the compositor this window is now hidden */
|
||||||
|
meta_compositor_set_window_hidden (window->display->compositor,
|
||||||
|
window->screen,
|
||||||
|
window,
|
||||||
|
window->hidden);
|
||||||
meta_stack_thaw (window->screen->stack);
|
meta_stack_thaw (window->screen->stack);
|
||||||
|
|
||||||
/*
|
did_hide = TRUE;
|
||||||
* The X server does not implement lower-below semantics for restacking
|
|
||||||
* windows, only raise-above; consequently each single lower-bottom call
|
|
||||||
* gets translated to a bunch of raise-above moves, and often there will
|
|
||||||
* be no ConfigureNotify at all for the window we are lowering (only for
|
|
||||||
* its siblings). If we mix the lower-bottom sequence of calls with
|
|
||||||
* mapping of windows, the batch of ConfigureNotify events that is
|
|
||||||
* generated does not correctly reflect the stack order, and if the
|
|
||||||
* Compositor relies on these for its own internal stack, it will
|
|
||||||
* invariably end up with wrong stacking order.
|
|
||||||
*
|
|
||||||
* I have not been able to find a way to get this just work so that the
|
|
||||||
* resulting ConfigureNotify messages would reflect the actual state of
|
|
||||||
* the stack, so in the special case we map a window while hiding it, we
|
|
||||||
* explitely notify the compositor that it should ensure its stacking
|
|
||||||
* matches the cannonical stack of the WM.
|
|
||||||
*
|
|
||||||
* NB: this is uncommon, and generally only happens on the WM start up,
|
|
||||||
* when we are taking over pre-existing windows, so this brute-force
|
|
||||||
* fix is OK performance wise.
|
|
||||||
*/
|
|
||||||
if (!was_mapped && window->display->compositor)
|
|
||||||
{
|
|
||||||
meta_compositor_ensure_stack_order (window->display->compositor,
|
|
||||||
window->screen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4149,7 +4138,7 @@ meta_window_focus (MetaWindow *window,
|
|||||||
|
|
||||||
meta_window_flush_calc_showing (window);
|
meta_window_flush_calc_showing (window);
|
||||||
|
|
||||||
if (!window->mapped && !window->shaded)
|
if ((!window->mapped || window->hidden) && !window->shaded)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Window %s is not showing, not focusing after all\n",
|
"Window %s is not showing, not focusing after all\n",
|
||||||
@ -8038,7 +8027,7 @@ meta_window_update_layer (MetaWindow *window)
|
|||||||
|
|
||||||
meta_stack_freeze (window->screen->stack);
|
meta_stack_freeze (window->screen->stack);
|
||||||
group = meta_window_get_group (window);
|
group = meta_window_get_group (window);
|
||||||
if (!window->hidden && group)
|
if (group)
|
||||||
meta_group_update_layers (group);
|
meta_group_update_layers (group);
|
||||||
else
|
else
|
||||||
meta_stack_update_layer (window->screen->stack, window);
|
meta_stack_update_layer (window->screen->stack, window);
|
||||||
|
@ -65,6 +65,7 @@ MetaWindow * mutter_window_get_meta_window (MutterWindow *mcw);
|
|||||||
ClutterActor * mutter_window_get_texture (MutterWindow *mcw);
|
ClutterActor * mutter_window_get_texture (MutterWindow *mcw);
|
||||||
gboolean mutter_window_is_override_redirect (MutterWindow *mcw);
|
gboolean mutter_window_is_override_redirect (MutterWindow *mcw);
|
||||||
const char * mutter_window_get_description (MutterWindow *mcw);
|
const char * mutter_window_get_description (MutterWindow *mcw);
|
||||||
|
gboolean mutter_window_showing_on_its_workspace (MutterWindow *mcw);
|
||||||
|
|
||||||
/* Compositor API */
|
/* Compositor API */
|
||||||
MetaCompositor *mutter_new (MetaDisplay *display);
|
MetaCompositor *mutter_new (MetaDisplay *display);
|
||||||
|
@ -129,9 +129,9 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
|||||||
MetaMotionDirection direction);
|
MetaMotionDirection direction);
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_compositor_ensure_stack_order (MetaCompositor *compositor,
|
meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||||
MetaScreen *screen);
|
MetaScreen *screen,
|
||||||
|
GList *stack);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,5 +64,8 @@ void meta_window_activate_with_workspace (MetaWindow *window,
|
|||||||
guint32 current_time,
|
guint32 current_time,
|
||||||
MetaWorkspace *workspace);
|
MetaWorkspace *workspace);
|
||||||
const char * meta_window_get_description (MetaWindow *window);
|
const char * meta_window_get_description (MetaWindow *window);
|
||||||
|
/* Return whether the window would be showing if we were on its workspace */
|
||||||
|
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user