mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 13:24:09 +00:00
window/x11: Add freeze_commits()/thaw_commits()
Xwayland may post damages for an X11 window as soon as the frame callback is triggered, while the X11 window manager/compositor has not yet finished updating the windows. If Xwayland becomes compliant enough to not permit updates after the buffer has been committed (see [1]), then the partial redraw of the X11 window at the time it was posted will show on screen. To avoid that issue, the X11 window manager can use the X11 property `_XWAYLAND_ALLOW_COMMITS` to control when Xwayland should be allowed to post the pending damages. Add `freeze_commits()` and `thaw_commits()` methods to `MetaWindowX11` which are a no-op on plain X11, but sets `_XWAYLAND_ALLOW_COMMITS` on the toplevel X11 windows running on Xwayland. [1] https://gitlab.freedesktop.org/xorg/xserver/merge_requests/316 See-also: https://gitlab.gnome.org/GNOME/mutter/merge_requests/855 https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
This commit is contained in:
parent
bac188b568
commit
845157c111
@ -18,6 +18,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "core/frame.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/window-x11-private.h"
|
||||
#include "x11/xprops.h"
|
||||
@ -40,6 +42,7 @@ struct _MetaWindowXwayland
|
||||
MetaWindowX11 parent;
|
||||
|
||||
gboolean xwayland_may_grab_keyboard;
|
||||
int freeze_count;
|
||||
};
|
||||
|
||||
struct _MetaWindowXwaylandClass
|
||||
@ -159,6 +162,63 @@ meta_window_xwayland_shortcuts_inhibited (MetaWindow *window,
|
||||
return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_allow_commits_x11_property (MetaWindowXwayland *xwayland_window,
|
||||
gboolean allow_commits)
|
||||
{
|
||||
MetaWindow *window = META_WINDOW (xwayland_window);
|
||||
MetaDisplay *display = window->display;
|
||||
MetaX11Display *x11_display = display->x11_display;
|
||||
Display *xdisplay = x11_display->xdisplay;
|
||||
MetaFrame *frame;
|
||||
Window xwin;
|
||||
guint32 property[1];
|
||||
|
||||
frame = meta_window_get_frame (window);
|
||||
if (!frame)
|
||||
xwin = window->xwindow;
|
||||
else
|
||||
xwin = meta_frame_get_xwindow (frame);
|
||||
|
||||
if (!xwin)
|
||||
return;
|
||||
|
||||
property[0] = !!allow_commits;
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XChangeProperty (xdisplay, xwin,
|
||||
x11_display->atom__XWAYLAND_ALLOW_COMMITS,
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(guchar*) &property, 1);
|
||||
meta_x11_error_trap_pop (x11_display);
|
||||
XFlush (xdisplay);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_xwayland_freeze_commits (MetaWindow *window)
|
||||
{
|
||||
MetaWindowXwayland *xwayland_window = META_WINDOW_XWAYLAND (window);
|
||||
|
||||
if (xwayland_window->freeze_count == 0)
|
||||
apply_allow_commits_x11_property (xwayland_window, FALSE);
|
||||
|
||||
xwayland_window->freeze_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_xwayland_thaw_commits (MetaWindow *window)
|
||||
{
|
||||
MetaWindowXwayland *xwayland_window = META_WINDOW_XWAYLAND (window);
|
||||
|
||||
g_return_if_fail (xwayland_window->freeze_count > 0);
|
||||
|
||||
xwayland_window->freeze_count--;
|
||||
if (xwayland_window->freeze_count > 0)
|
||||
return;
|
||||
|
||||
apply_allow_commits_x11_property (xwayland_window, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_xwayland_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -201,12 +261,16 @@ static void
|
||||
meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass)
|
||||
{
|
||||
MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
|
||||
MetaWindowX11Class *window_x11_class = META_WINDOW_X11_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
window_class->adjust_fullscreen_monitor_rect = meta_window_xwayland_adjust_fullscreen_monitor_rect;
|
||||
window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts;
|
||||
window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited;
|
||||
|
||||
window_x11_class->freeze_commits = meta_window_xwayland_freeze_commits;
|
||||
window_x11_class->thaw_commits = meta_window_xwayland_thaw_commits;
|
||||
|
||||
gobject_class->get_property = meta_window_xwayland_get_property;
|
||||
gobject_class->set_property = meta_window_xwayland_set_property;
|
||||
|
||||
|
@ -82,6 +82,7 @@ item(_XKB_RULES_NAMES)
|
||||
item(WL_SURFACE_ID)
|
||||
item(_XWAYLAND_MAY_GRAB_KEYBOARD)
|
||||
item(_XWAYLAND_RANDR_EMU_MONITOR_RECTS)
|
||||
item(_XWAYLAND_ALLOW_COMMITS)
|
||||
|
||||
/* Oddities: These are used, and we need atoms for them,
|
||||
* but when we need all _NET_WM hints (i.e. when we're making
|
||||
|
@ -33,6 +33,9 @@ typedef struct _MetaWindowX11Private MetaWindowX11Private;
|
||||
struct _MetaWindowX11Class
|
||||
{
|
||||
MetaWindowClass parent_class;
|
||||
|
||||
void (*freeze_commits) (MetaWindow *window);
|
||||
void (*thaw_commits) (MetaWindow *window);
|
||||
};
|
||||
|
||||
struct _MetaWindowX11
|
||||
|
@ -1973,6 +1973,16 @@ meta_window_x11_calculate_layer (MetaWindow *window)
|
||||
return layer;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_x11_impl_freeze_commits (MetaWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_x11_impl_thaw_commits (MetaWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_x11_map (MetaWindow *window)
|
||||
{
|
||||
@ -2024,6 +2034,9 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||
window_class->calculate_layer = meta_window_x11_calculate_layer;
|
||||
window_class->map = meta_window_x11_map;
|
||||
window_class->unmap = meta_window_x11_unmap;
|
||||
|
||||
klass->freeze_commits = meta_window_x11_impl_freeze_commits;
|
||||
klass->thaw_commits = meta_window_x11_impl_thaw_commits;
|
||||
}
|
||||
|
||||
void
|
||||
@ -3995,3 +4008,17 @@ meta_window_x11_get_toplevel_xwindow (MetaWindow *window)
|
||||
{
|
||||
return window->frame ? window->frame->xwindow : window->xwindow;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_x11_freeze_commits (MetaWindow *window)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
META_WINDOW_X11_GET_CLASS (window_x11)->freeze_commits (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_x11_thaw_commits (MetaWindow *window)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
META_WINDOW_X11_GET_CLASS (window_x11)->thaw_commits (window);
|
||||
}
|
||||
|
@ -81,4 +81,7 @@ void meta_window_x11_configure_notify (MetaWindow *window,
|
||||
|
||||
Window meta_window_x11_get_toplevel_xwindow (MetaWindow *window);
|
||||
|
||||
void meta_window_x11_freeze_commits (MetaWindow *window);
|
||||
void meta_window_x11_thaw_commits (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user