diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c index 9967f439a..5b1c4198e 100644 --- a/src/wayland/meta-window-xwayland.c +++ b/src/wayland/meta-window-xwayland.c @@ -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; diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h index 4099d5d31..4c1b49ede 100644 --- a/src/x11/atomnames.h +++ b/src/x11/atomnames.h @@ -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 diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h index c582118c7..a073a5b8a 100644 --- a/src/x11/window-x11-private.h +++ b/src/x11/window-x11-private.h @@ -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 diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 6378111b5..9caf75ad6 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -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); +} diff --git a/src/x11/window-x11.h b/src/x11/window-x11.h index f3f3f1de1..2180ce976 100644 --- a/src/x11/window-x11.h +++ b/src/x11/window-x11.h @@ -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