window: Always sync window geometry on state change

When a state changed, e.g. a window went from unfullscreen to
fullscreen, always sync the window geometry, otherwise a compositor
application (e.g. gnome-shell) might end up with an unfinished window
state transition effect.

Without always syncing, the compositor plugin will see a 'size-change'
event, as a result of the state change, but if the size didn't change,
it would never see the 'size-changed' event. If an effect, for example
gnome-shell's fullscreen effect, is triggered on 'size-change' it might
rely on the actual size change to not get stuck. This commit allows it
to have this dependency.

This fixes a bug where a fullscreen effect gets "stuck" when a window
goes fullscreen without changing the window geometry.

https://bugzilla.gnome.org/show_bug.cgi?id=780292
This commit is contained in:
Jonas Ådahl 2017-03-20 13:49:34 +08:00
parent 5b378ea648
commit 5d3e7d6ffd

View File

@ -3645,6 +3645,7 @@ meta_window_move_resize_internal (MetaWindow *window,
MetaRectangle unconstrained_rect; MetaRectangle unconstrained_rect;
MetaRectangle constrained_rect; MetaRectangle constrained_rect;
MetaMoveResizeResultFlags result = 0; MetaMoveResizeResultFlags result = 0;
gboolean moved_or_resized = FALSE;
g_return_if_fail (!window->override_redirect); g_return_if_fail (!window->override_redirect);
@ -3720,19 +3721,28 @@ meta_window_move_resize_internal (MetaWindow *window,
META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, unconstrained_rect, constrained_rect, flags, &result); META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, unconstrained_rect, constrained_rect, flags, &result);
if (result & META_MOVE_RESIZE_RESULT_MOVED) if (result & META_MOVE_RESIZE_RESULT_MOVED)
g_signal_emit (window, window_signals[POSITION_CHANGED], 0); {
moved_or_resized = TRUE;
g_signal_emit (window, window_signals[POSITION_CHANGED], 0);
}
if (result & META_MOVE_RESIZE_RESULT_RESIZED) if (result & META_MOVE_RESIZE_RESULT_RESIZED)
g_signal_emit (window, window_signals[SIZE_CHANGED], 0);
if ((result & (META_MOVE_RESIZE_RESULT_MOVED | META_MOVE_RESIZE_RESULT_RESIZED)) != 0 || did_placement)
{ {
window->unconstrained_rect = unconstrained_rect; moved_or_resized = TRUE;
g_signal_emit (window, window_signals[SIZE_CHANGED], 0);
}
if (window->known_to_compositor) if (moved_or_resized || did_placement)
meta_compositor_sync_window_geometry (window->display->compositor, window->unconstrained_rect = unconstrained_rect;
window,
did_placement); if ((moved_or_resized ||
did_placement ||
(flags & META_MOVE_RESIZE_STATE_CHANGED) != 0) &&
window->known_to_compositor)
{
meta_compositor_sync_window_geometry (window->display->compositor,
window,
did_placement);
} }
old_output_winsys_id = window->monitor->winsys_id; old_output_winsys_id = window->monitor->winsys_id;