diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 371233f45..2c33b2e6a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1193,18 +1193,26 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) int num_monitors = meta_screen_get_n_monitors (screen); int i; - if (!meta_window_is_override_redirect (metaWindow)) + if (meta_window_requested_dont_bypass_compositor (metaWindow)) + return FALSE; + + if (!meta_window_is_override_redirect (metaWindow) && + !meta_window_requested_bypass_compositor (metaWindow)) return FALSE; if (priv->opacity != 0xff) return FALSE; - if (priv->argb32) + if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow)) return FALSE; if (metaWindow->has_shape) return FALSE; + if (meta_window_requested_bypass_compositor (metaWindow) && + meta_window_is_fullscreen (metaWindow)) + return TRUE; + meta_screen_get_size (screen, &screen_width, &screen_height); meta_window_get_outer_rect (metaWindow, &window_rect); diff --git a/src/core/window-private.h b/src/core/window-private.h index 712e0231c..a1cb15dd2 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -413,6 +413,10 @@ struct _MetaWindow /* The currently complementary tiled window, if any */ MetaWindow *tile_match; + + /* Bypass compositor hints */ + guint bypass_compositor : 1; + guint dont_bypass_compositor : 1; }; struct _MetaWindowClass diff --git a/src/core/window-props.c b/src/core/window-props.c index 68e14fd21..744209070 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1584,6 +1584,58 @@ reload_gtk_hide_titlebar_when_maximized (MetaWindow *window, } } +static void +reload_bypass_compositor (MetaWindow *window, + MetaPropValue *value, + gboolean initial) +{ + gboolean requested_value = FALSE; + gboolean current_value = window->bypass_compositor; + + if (value->type != META_PROP_VALUE_INVALID) + { + requested_value = ((int) value->v.cardinal == 1); + meta_verbose ("Request to bypass compositor for window %s.\n", window->desc); + } + + if (requested_value == current_value) + return; + + if (requested_value && window->dont_bypass_compositor) + { + meta_verbose ("Setting bypass and dont compositor for same window (%s) makes no sense, ignoring.\n", window->desc); + return; + } + + window->bypass_compositor = requested_value; +} + +static void +reload_dont_bypass_compositor (MetaWindow *window, + MetaPropValue *value, + gboolean initial) +{ + gboolean requested_value = FALSE; + gboolean current_value = window->dont_bypass_compositor; + + if (value->type != META_PROP_VALUE_INVALID) + { + requested_value = ((int) value->v.cardinal == 1); + meta_verbose ("Request to don't bypass compositor for window %s.\n", window->desc); + } + + if (requested_value == current_value) + return; + + if (requested_value && window->bypass_compositor) + { + meta_verbose ("Setting bypass and dont compositor for same window (%s) makes no sense, ignoring.\n", window->desc); + return; + } + + window->dont_bypass_compositor = requested_value; +} + #define RELOAD_STRING(var_name, propname) \ static void \ reload_ ## var_name (MetaWindow *window, \ @@ -1683,6 +1735,8 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) { display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, FALSE, TRUE }, { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, + { display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE }, + { display->atom__NET_WM_DONT_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_dont_bypass_compositor, FALSE, FALSE }, { 0 }, }; diff --git a/src/core/window.c b/src/core/window.c index a1b846897..75a6ef333 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3640,6 +3640,28 @@ meta_window_is_on_primary_monitor (MetaWindow *window) return window->monitor->is_primary; } +/** + * meta_window_requested_bypass_compositor: + * + * Return value: %TRUE if the window requested to bypass the compositor + */ +gboolean +meta_window_requested_bypass_compositor (MetaWindow *window) +{ + return window->bypass_compositor; +} + +/** + * meta_window_requested_dont_bypass_compositor: + * + * Return value: %TRUE if the window requested to opt out of unredirecting + */ +gboolean +meta_window_requested_dont_bypass_compositor (MetaWindow *window) +{ + return window->dont_bypass_compositor; +} + void meta_window_tile (MetaWindow *window) { diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index 210e5a23d..57ca9bd81 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -172,6 +172,8 @@ item(_NET_WM_ACTION_BELOW) item(_NET_WM_STATE_STICKY) item(_NET_WM_FULLSCREEN_MONITORS) item(_NET_WM_STATE_FOCUSED) +item(_NET_WM_BYPASS_COMPOSITOR) +item(_NET_WM_DONT_BYPASS_COMPOSITOR) #if 0 /* We apparently never use: */ diff --git a/src/meta/window.h b/src/meta/window.h index f36c033ef..c8d49c932 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -140,6 +140,8 @@ void meta_window_foreach_ancestor (MetaWindow *window, MetaMaximizeFlags meta_window_get_maximized (MetaWindow *window); gboolean meta_window_is_fullscreen (MetaWindow *window); gboolean meta_window_is_on_primary_monitor (MetaWindow *window); +gboolean meta_window_requested_bypass_compositor (MetaWindow *window); +gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window); gboolean meta_window_is_mapped (MetaWindow *window); gboolean meta_window_toplevel_is_mapped (MetaWindow *window);