Always map the client and frame windows
Traditionally, WMs unmap windows when minimizing them, and map them when restoring them or wanting to show them for other reasons, like upon creation. However, as metacity morphed into mutter, we optionally chose to keep windows mapped for the lifetime of the window under the user option "live-window-previews", which makes the code keep windows mapped so it can show window preview for minimized windows in other places, like Alt-Tab and Expose. I removed this preference two years ago mechanically, by removing all the if statements, but never went through and cleaned up the code so that windows are simply mapped for the lifetime of the window -- the "architecture" of the old code that maps and unmaps on show/hide was still there. Remove this now. The one case we still need to be careful of is shaded windows, in which we do still unmap the client window. In the future, we might want to show previews of shaded windows in the overview and Alt-Tab. In that we'd also keep shaded windows mapped, and could remove all unmap logic, but we'd need a more complex method of showing the shaded titlebar, such as using a different actor. At the same time, simplify the compositor interface by removing meta_compositor_window_[un]mapped API, and instead adding/removing the window on-demand. https://bugzilla.gnome.org/show_bug.cgi?id=720631
This commit is contained in:
parent
0c5a6ad775
commit
aec3edb1cc
9 changed files with 54 additions and 257 deletions
|
@ -96,8 +96,6 @@ meta_compositor_hide_window
|
|||
meta_compositor_switch_workspace
|
||||
meta_compositor_maximize_window
|
||||
meta_compositor_unmaximize_window
|
||||
meta_compositor_window_mapped
|
||||
meta_compositor_window_unmapped
|
||||
meta_compositor_sync_window_geometry
|
||||
meta_compositor_set_updates_frozen
|
||||
meta_compositor_queue_frame_drawn
|
||||
|
|
|
@ -42,15 +42,6 @@
|
|||
* the call, so it may be necessary to readjust the display based on the
|
||||
* old_rect to start the animation.
|
||||
*
|
||||
* meta_compositor_window_mapped() and meta_compositor_window_unmapped() are
|
||||
* notifications when the toplevel window (frame or client window) is mapped or
|
||||
* unmapped. That is, when the result of meta_window_toplevel_is_mapped()
|
||||
* changes. The main use of this is to drop resources when a window is unmapped.
|
||||
* A window will always be mapped before meta_compositor_show_window()
|
||||
* is called and will not be unmapped until after meta_compositor_hide_window()
|
||||
* is called. If the live_hidden_windows preference is set, windows will never
|
||||
* be unmapped.
|
||||
*
|
||||
* # Containers #
|
||||
*
|
||||
* There's two containers in the stage that are used to place window actors, here
|
||||
|
@ -1369,30 +1360,6 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
|||
sync_actor_stacking (info);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_window_mapped (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
DEBUG_TRACE ("meta_compositor_window_mapped\n");
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_mapped (window_actor);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_window_unmapped (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
DEBUG_TRACE ("meta_compositor_window_unmapped\n");
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_unmapped (window_actor);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
|
|
|
@ -103,7 +103,6 @@ struct _MetaWindowActorPrivate
|
|||
Damage damage; /* Not used in wayland compositor mode */
|
||||
|
||||
guint visible : 1;
|
||||
guint mapped : 1;
|
||||
guint argb32 : 1;
|
||||
guint disposed : 1;
|
||||
guint redecorating : 1;
|
||||
|
@ -922,7 +921,7 @@ meta_window_actor_damage_all (MetaWindowActor *self)
|
|||
if (!priv->needs_damage_all)
|
||||
return;
|
||||
|
||||
if (!priv->mapped || priv->needs_pixmap)
|
||||
if (priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_surface_actor_damage_all (priv->surface);
|
||||
|
@ -997,7 +996,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
|||
{
|
||||
queue_send_frame_messages_timeout (self);
|
||||
}
|
||||
else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap))
|
||||
else
|
||||
{
|
||||
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip);
|
||||
|
@ -1029,9 +1028,6 @@ meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self)
|
|||
|
||||
priv->needs_pixmap = TRUE;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
if (is_frozen (self))
|
||||
return;
|
||||
|
||||
|
@ -1129,9 +1125,6 @@ meta_window_actor_after_effects (MetaWindowActor *self)
|
|||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
if (!meta_window_is_mapped (priv->window))
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
|
||||
if (priv->needs_pixmap)
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
|
||||
}
|
||||
|
@ -1558,15 +1551,13 @@ meta_window_actor_new (MetaWindow *window)
|
|||
NULL);
|
||||
|
||||
priv = self->priv;
|
||||
priv->mapped = meta_window_toplevel_is_mapped (priv->window);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
priv->last_width = -1;
|
||||
priv->last_height = -1;
|
||||
|
||||
if (priv->mapped)
|
||||
meta_window_actor_queue_create_x11_pixmap (self);
|
||||
meta_window_actor_queue_create_x11_pixmap (self);
|
||||
|
||||
meta_window_actor_set_updates_frozen (self,
|
||||
meta_window_updates_are_frozen (priv->window));
|
||||
|
@ -1602,38 +1593,6 @@ meta_window_actor_new (MetaWindow *window)
|
|||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_mapped (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
g_return_if_fail (!priv->mapped);
|
||||
|
||||
priv->mapped = TRUE;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
meta_window_actor_queue_create_x11_pixmap (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_unmapped (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
g_return_if_fail (priv->mapped);
|
||||
|
||||
priv->mapped = FALSE;
|
||||
|
||||
if (meta_window_actor_effect_in_progress (self))
|
||||
return;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
priv->needs_pixmap = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Print out a region; useful for debugging */
|
||||
static void
|
||||
|
@ -1763,9 +1722,6 @@ check_needs_x11_pixmap (MetaWindowActor *self)
|
|||
if (!priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
if (xwindow == meta_screen_get_xroot (screen) ||
|
||||
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
|
||||
return;
|
||||
|
@ -1839,9 +1795,6 @@ check_needs_shadow (MetaWindowActor *self)
|
|||
gboolean should_have_shadow;
|
||||
gboolean appears_focused;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
/* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap
|
||||
* and avoids the need to explicitly handle window type changes, which
|
||||
* we would do if tried to keep track of when we might be adding or removing
|
||||
|
@ -1945,7 +1898,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!priv->mapped || priv->needs_pixmap)
|
||||
if (priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_surface_actor_damage_area (priv->surface,
|
||||
|
@ -2218,9 +2171,6 @@ check_needs_reshape (MetaWindowActor *self)
|
|||
MetaFrameBorders borders;
|
||||
cairo_rectangle_int_t client_area;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
if (!priv->needs_reshape)
|
||||
return;
|
||||
|
||||
|
|
|
@ -2763,7 +2763,7 @@ handle_other_xevent (MetaDisplay *display,
|
|||
|
||||
if (display->grab_op != META_GRAB_OP_NONE &&
|
||||
display->grab_window == window &&
|
||||
((window->frame == NULL) || !window->frame->mapped))
|
||||
window->frame == NULL)
|
||||
meta_display_end_grab_op (display, timestamp);
|
||||
|
||||
if (!frame_was_receiver)
|
||||
|
|
|
@ -62,7 +62,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||
frame->right_width = 0;
|
||||
frame->current_cursor = 0;
|
||||
|
||||
frame->mapped = FALSE;
|
||||
frame->is_flashing = FALSE;
|
||||
frame->borders_cached = FALSE;
|
||||
|
||||
|
@ -157,6 +156,8 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -47,7 +47,6 @@ struct _MetaFrame
|
|||
int right_width;
|
||||
int bottom_height;
|
||||
|
||||
guint mapped : 1;
|
||||
guint need_reapply_frame_shape : 1;
|
||||
guint is_flashing : 1; /* used by the visual bell flash */
|
||||
guint borders_cached : 1;
|
||||
|
|
|
@ -688,6 +688,35 @@ meta_window_should_attach_to_parent (MetaWindow *window)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
client_window_should_be_mapped (MetaWindow *window)
|
||||
{
|
||||
return !window->shaded;
|
||||
}
|
||||
|
||||
static void
|
||||
sync_client_window_mapped (MetaWindow *window)
|
||||
{
|
||||
gboolean should_be_mapped = client_window_should_be_mapped (window);
|
||||
|
||||
if (window->mapped == should_be_mapped)
|
||||
return;
|
||||
|
||||
window->mapped = should_be_mapped;
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
if (should_be_mapped)
|
||||
{
|
||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||
window->unmaps_pending ++;
|
||||
}
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
_meta_window_shared_new (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
|
@ -1191,6 +1220,8 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||
/* disable show desktop mode unless we're a desktop component */
|
||||
maybe_leave_show_desktop_mode (window);
|
||||
|
||||
sync_client_window_mapped (window);
|
||||
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
|
||||
/* See bug 303284; a transient of the given window can already exist, in which
|
||||
* case we think it should probably be shown.
|
||||
|
@ -1932,6 +1963,8 @@ implement_showing (MetaWindow *window,
|
|||
meta_verbose ("Implement showing = %d for window %s\n",
|
||||
showing, window->desc);
|
||||
|
||||
sync_client_window_mapped (window);
|
||||
|
||||
if (!showing)
|
||||
{
|
||||
/* When we manage a new window, we normally delay placing it
|
||||
|
@ -2520,94 +2553,6 @@ window_would_be_covered (const MetaWindow *newbie)
|
|||
return FALSE; /* none found */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
map_frame (MetaWindow *window)
|
||||
{
|
||||
if (window->frame && !window->frame->mapped)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Frame actually needs map\n");
|
||||
window->frame->mapped = TRUE;
|
||||
meta_ui_map_frame (window->screen->ui, window->frame->xwindow);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
map_client_window (MetaWindow *window)
|
||||
{
|
||||
if (!window->mapped)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"%s actually needs map\n", window->desc);
|
||||
window->mapped = TRUE;
|
||||
meta_error_trap_push (window->display);
|
||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
unmap_client_window (MetaWindow *window,
|
||||
const char *reason)
|
||||
{
|
||||
if (window->mapped)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"%s actually needs unmap%s\n",
|
||||
window->desc, reason);
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Incrementing unmaps_pending on %s%s\n",
|
||||
window->desc, reason);
|
||||
window->mapped = FALSE;
|
||||
window->unmaps_pending += 1;
|
||||
meta_error_trap_push (window->display);
|
||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_is_mapped:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Determines whether the X window for the MetaWindow is mapped.
|
||||
*/
|
||||
gboolean
|
||||
meta_window_is_mapped (MetaWindow *window)
|
||||
{
|
||||
return window->mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_toplevel_is_mapped:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Determines whether the toplevel X window for the MetaWindow is
|
||||
* mapped. (The frame window is mapped even without the client window
|
||||
* when a window is shaded.)
|
||||
*
|
||||
* Return Value: %TRUE if the toplevel is mapped.
|
||||
*/
|
||||
gboolean
|
||||
meta_window_toplevel_is_mapped (MetaWindow *window)
|
||||
{
|
||||
/* The frame is mapped but not the client window when the window
|
||||
* is shaded.
|
||||
*/
|
||||
return window->mapped || (window->frame && window->frame->mapped);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_force_placement (MetaWindow *window)
|
||||
{
|
||||
|
@ -2646,16 +2591,12 @@ meta_window_show (MetaWindow *window)
|
|||
gboolean place_on_top_on_map;
|
||||
gboolean needs_stacking_adjustment;
|
||||
MetaWindow *focus_window;
|
||||
gboolean toplevel_was_mapped;
|
||||
gboolean toplevel_now_mapped;
|
||||
gboolean notify_demands_attention = FALSE;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Showing window %s, shaded: %d iconic: %d placed: %d\n",
|
||||
window->desc, window->shaded, window->iconic, window->placed);
|
||||
|
||||
toplevel_was_mapped = meta_window_toplevel_is_mapped (window);
|
||||
|
||||
focus_window = window->display->focus_window; /* May be NULL! */
|
||||
did_show = FALSE;
|
||||
window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map);
|
||||
|
@ -2782,46 +2723,18 @@ meta_window_show (MetaWindow *window)
|
|||
}
|
||||
}
|
||||
|
||||
/* Shaded means the frame is mapped but the window is not */
|
||||
|
||||
if (map_frame (window))
|
||||
did_show = TRUE;
|
||||
|
||||
if (window->shaded)
|
||||
if (window->hidden)
|
||||
{
|
||||
unmap_client_window (window, " (shading)");
|
||||
|
||||
if (!window->iconic)
|
||||
{
|
||||
window->iconic = TRUE;
|
||||
set_wm_state (window);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (map_client_window (window))
|
||||
did_show = TRUE;
|
||||
|
||||
if (window->hidden)
|
||||
{
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
window->hidden = FALSE;
|
||||
meta_stack_thaw (window->screen->stack);
|
||||
did_show = TRUE;
|
||||
}
|
||||
|
||||
if (window->iconic)
|
||||
{
|
||||
window->iconic = FALSE;
|
||||
set_wm_state (window);
|
||||
}
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
window->hidden = FALSE;
|
||||
meta_stack_thaw (window->screen->stack);
|
||||
did_show = TRUE;
|
||||
}
|
||||
|
||||
toplevel_now_mapped = meta_window_toplevel_is_mapped (window);
|
||||
if (toplevel_now_mapped != toplevel_was_mapped)
|
||||
if (window->iconic)
|
||||
{
|
||||
if (window->display->compositor)
|
||||
meta_compositor_window_mapped (window->display->compositor, window);
|
||||
window->iconic = FALSE;
|
||||
set_wm_state (window);
|
||||
}
|
||||
|
||||
if (!window->visible_to_compositor)
|
||||
|
@ -2913,14 +2826,10 @@ static void
|
|||
meta_window_hide (MetaWindow *window)
|
||||
{
|
||||
gboolean did_hide;
|
||||
gboolean toplevel_was_mapped;
|
||||
gboolean toplevel_now_mapped;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Hiding window %s\n", window->desc);
|
||||
|
||||
toplevel_was_mapped = meta_window_toplevel_is_mapped (window);
|
||||
|
||||
if (window->visible_to_compositor)
|
||||
{
|
||||
window->visible_to_compositor = FALSE;
|
||||
|
@ -2941,19 +2850,12 @@ meta_window_hide (MetaWindow *window)
|
|||
break;
|
||||
}
|
||||
|
||||
meta_compositor_hide_window (window->display->compositor,
|
||||
window, effect);
|
||||
meta_compositor_hide_window (window->display->compositor, window, effect);
|
||||
}
|
||||
}
|
||||
|
||||
did_hide = FALSE;
|
||||
|
||||
/* If this is the first time that we've calculating the showing
|
||||
* state of the window, the frame and client window might not
|
||||
* yet be mapped, so we need to map them now */
|
||||
map_frame (window);
|
||||
map_client_window (window);
|
||||
|
||||
if (!window->hidden)
|
||||
{
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
|
@ -2969,19 +2871,6 @@ meta_window_hide (MetaWindow *window)
|
|||
set_wm_state (window);
|
||||
}
|
||||
|
||||
toplevel_now_mapped = meta_window_toplevel_is_mapped (window);
|
||||
if (toplevel_now_mapped != toplevel_was_mapped)
|
||||
{
|
||||
if (window->display->compositor)
|
||||
{
|
||||
/* As above, we may be *mapping* live hidden windows */
|
||||
if (toplevel_now_mapped)
|
||||
meta_compositor_window_mapped (window->display->compositor, window);
|
||||
else
|
||||
meta_compositor_window_unmapped (window->display->compositor, window);
|
||||
}
|
||||
}
|
||||
|
||||
set_net_wm_state (window);
|
||||
|
||||
if (did_hide && window->struts)
|
||||
|
@ -6813,7 +6702,7 @@ redraw_icon (MetaWindow *window)
|
|||
/* We could probably be smart and just redraw the icon here,
|
||||
* instead of the whole frame.
|
||||
*/
|
||||
if (window->frame && (window->mapped || window->frame->mapped))
|
||||
if (window->frame)
|
||||
meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,11 +75,10 @@ gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
|||
MetaScreen *screen,
|
||||
MetaKeyBinding *binding);
|
||||
|
||||
void meta_compositor_add_window (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_compositor_add_window (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_show_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaCompEffect effect);
|
||||
|
@ -101,10 +100,6 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor,
|
|||
MetaRectangle *old_rect,
|
||||
MetaRectangle *new_rect);
|
||||
|
||||
void meta_compositor_window_mapped (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_window_unmapped (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean did_placement);
|
||||
|
|
|
@ -189,8 +189,6 @@ gboolean meta_window_requested_bypass_compositor (MetaWindow *window);
|
|||
gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window);
|
||||
gint *meta_window_get_all_monitors (MetaWindow *window, gsize *length);
|
||||
|
||||
gboolean meta_window_is_mapped (MetaWindow *window);
|
||||
gboolean meta_window_toplevel_is_mapped (MetaWindow *window);
|
||||
gboolean meta_window_get_icon_geometry (MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
void meta_window_set_icon_geometry (MetaWindow *window,
|
||||
|
|
Loading…
Reference in a new issue