x11: Add frame synchronization to window frames

There's two meanings of "frame" there! Since SSD frames are now
rendered by an external client, and there are no actual mechanism
that ensures the frame did already get painted when the client did
respond to its NET_WM_FRAME_SYNC_REQUEST request, there may be
artifacts when resizing windows.

In order to get always the best visual result, we should actually
synchronize rendering with both the client window and the window
frame window.

This commit adds these mechanisms, so a sync alarm update is
expected on both windows until further resizes are allowed, this
ensures window and frame stay in sync, even after moving rendering
elsewhere.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
This commit is contained in:
Carlos Garnacho
2022-09-09 15:54:28 +02:00
committed by Marge Bot
parent 782d200d6c
commit f2237fa0c8
6 changed files with 109 additions and 16 deletions

View File

@ -30,6 +30,7 @@
#include "core/keybindings-private.h"
#include "meta/meta-x11-errors.h"
#include "x11/meta-x11-display-private.h"
#include "x11/window-props.h"
#include <X11/Xatom.h>
@ -69,7 +70,7 @@ meta_window_set_frame_xwindow (MetaWindow *window,
frame = g_new0 (MetaFrame, 1);
frame->window = window;
frame->xwindow = None;
frame->xwindow = xframe;
frame->rect = window->rect;
frame->child_x = 0;
@ -79,6 +80,8 @@ meta_window_set_frame_xwindow (MetaWindow *window,
frame->borders_cached = FALSE;
meta_sync_counter_init (&frame->sync_counter, window, frame->xwindow);
window->frame = frame;
meta_verbose ("Frame geometry %d,%d %dx%d",
@ -91,8 +94,6 @@ meta_window_set_frame_xwindow (MetaWindow *window,
frame->rect.x, frame->rect.y,
frame->rect.width, frame->rect.height);
frame->xwindow = xframe;
meta_stack_tracker_record_add (window->display->stack_tracker,
frame->xwindow,
create_serial);
@ -136,6 +137,10 @@ meta_window_set_frame_xwindow (MetaWindow *window,
/* stick frame to the window */
window->frame = frame;
meta_window_reload_property_from_xwindow (window, frame->xwindow,
x11_display->atom__NET_WM_SYNC_REQUEST_COUNTER,
TRUE);
XMapWindow (x11_display->xdisplay, frame->xwindow);
/* Move keybindings to frame instead of window */
@ -222,6 +227,8 @@ meta_window_destroy_frame (MetaWindow *window)
/* Move keybindings to window instead of frame */
meta_window_grab_keys (window);
meta_sync_counter_clear (&frame->sync_counter);
g_free (frame);
/* Put our state back where it should be */
@ -496,6 +503,14 @@ meta_frame_handle_xevent (MetaFrame *frame,
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
return TRUE;
}
else if (xevent->xany.type == PropertyNotify &&
xevent->xproperty.state == PropertyNewValue &&
xevent->xproperty.atom == x11_display->atom__NET_WM_SYNC_REQUEST_COUNTER)
{
meta_window_reload_property_from_xwindow (window, frame->xwindow,
xevent->xproperty.atom, FALSE);
return TRUE;
}
return FALSE;
}
@ -572,3 +587,9 @@ meta_frame_type_to_string (MetaFrameType type)
return "<unknown>";
}
MetaSyncCounter *
meta_frame_get_sync_counter (MetaFrame *frame)
{
return &frame->sync_counter;
}

View File

@ -24,6 +24,8 @@
#include "core/window-private.h"
#include "x11/meta-sync-counter.h"
struct _MetaFrame
{
/* window we frame */
@ -39,6 +41,8 @@ struct _MetaFrame
MetaFrameBorders cached_borders; /* valid if borders_cached is set */
MetaSyncCounter sync_counter;
/* position of client, size of frame */
int child_x;
int child_y;
@ -75,4 +79,6 @@ gboolean meta_frame_handle_xevent (MetaFrame *frame,
GSubprocess * meta_frame_launch_client (MetaX11Display *x11_display,
const char *display_name);
MetaSyncCounter * meta_frame_get_sync_counter (MetaFrame *frame);
#endif