diff --git a/lib/Utils.vala b/lib/Utils.vala index 9f4716745..57a719bb6 100644 --- a/lib/Utils.vala +++ b/lib/Utils.vala @@ -404,6 +404,8 @@ namespace Gala { return texture; } + private static HashTable regions = new HashTable (null, null); + public static void x11_set_window_pass_through (Meta.Window window) { unowned var x11_display = window.display.get_x11_display (); @@ -414,6 +416,9 @@ namespace Gala { #endif unowned var xdisplay = x11_display.get_xdisplay (); + int count, ordering; + regions[window] = X.Shape.get_rectangles (xdisplay, x_window, 2, out count, out ordering)[0]; + X.Xrectangle rect = {}; var region = X.Fixes.create_region (xdisplay, {rect}); @@ -422,7 +427,7 @@ namespace Gala { X.Fixes.destroy_region (xdisplay, region); } - public static void x11_unset_window_pass_through (Meta.Window window) { + public static void x11_unset_window_pass_through (Meta.Window window, bool restore_previous_region) { unowned var x11_display = window.display.get_x11_display (); #if HAS_MUTTER46 @@ -432,7 +437,19 @@ namespace Gala { #endif unowned var xdisplay = x11_display.get_xdisplay (); - X.Fixes.set_window_shape_region (xdisplay, x_window, 2, 0, 0, (X.XserverRegion) 0); + if (restore_previous_region) { + var region = regions[window]; + if (region == null) { + debug ("Cannot unset pass through: window not found."); + return; + } + + X.Shape.combine_rectangles (xdisplay, x_window, 2, 0, 0, { region }, 0, 3); + } else { + X.Fixes.set_window_shape_region (xdisplay, x_window, 2, 0, 0, (X.XserverRegion) 0); + } + + regions.remove (window); } /** diff --git a/meson.build b/meson.build index bc9aae643..a6deebded 100644 --- a/meson.build +++ b/meson.build @@ -94,6 +94,7 @@ gnome_desktop_dep = dependency('gnome-desktop-3.0') m_dep = cc.find_library('m', required: false) posix_dep = vala.find_library('posix', required: false) sqlite3_dep = dependency('sqlite3') +xext_dep = cc.find_library('Xext', required: true) if get_option('systemd') systemd_dep = dependency('libsystemd') endif @@ -149,7 +150,7 @@ endif add_project_arguments(vala_flags, language: 'vala') add_project_link_arguments(['-Wl,-rpath,@0@'.format(mutter_typelib_dir)], language: 'c') -gala_base_dep = [atk_bridge_dep, canberra_dep, glib_dep, gobject_dep, gio_dep, gio_unix_dep, gmodule_dep, gee_dep, gtk_dep, mutter_dep, gnome_desktop_dep, m_dep, posix_dep, sqlite3_dep, config_dep] +gala_base_dep = [atk_bridge_dep, canberra_dep, glib_dep, gobject_dep, gio_dep, gio_unix_dep, gmodule_dep, gee_dep, gtk_dep, mutter_dep, gnome_desktop_dep, m_dep, posix_dep, sqlite3_dep, xext_dep, config_dep] if get_option('systemd') gala_base_dep += systemd_dep diff --git a/src/ShellClients/ShellClientsManager.vala b/src/ShellClients/ShellClientsManager.vala index 719ae2a36..ff39deb8a 100644 --- a/src/ShellClients/ShellClientsManager.vala +++ b/src/ShellClients/ShellClientsManager.vala @@ -294,9 +294,19 @@ public class Gala.ShellClientsManager : Object, GestureTarget { make_centered (window); break; + case "restore-previous-region": + set_restore_previous_x11_region (window); + break; + default: break; } } } + + private void set_restore_previous_x11_region (Meta.Window window) + requires (!Meta.Util.is_wayland_compositor ()) + requires (window in panel_windows) { + panel_windows[window].restore_previous_x11_region = true; + } } diff --git a/src/ShellClients/ShellWindow.vala b/src/ShellClients/ShellWindow.vala index 223b8c140..7eba7d952 100644 --- a/src/ShellClients/ShellWindow.vala +++ b/src/ShellClients/ShellWindow.vala @@ -7,6 +7,7 @@ public class Gala.ShellWindow : PositionedWindow, GestureTarget { public Clutter.Actor? actor { get { return window_actor; } } + public bool restore_previous_x11_region { private get; set; default = false; } private Meta.WindowActor window_actor; private double custom_progress = 0; @@ -85,16 +86,16 @@ public class Gala.ShellWindow : PositionedWindow, GestureTarget { var visible = double.max (multitasking_view_progress, custom_progress) < 0.1; var animating = animations_ongoing > 0; + window_actor.visible = animating || visible; + if (!Meta.Util.is_wayland_compositor ()) { - if (!visible) { - Utils.x11_set_window_pass_through (window); + if (window_actor.visible) { + Utils.x11_unset_window_pass_through (window, restore_previous_x11_region); } else { - Utils.x11_unset_window_pass_through (window); + Utils.x11_set_window_pass_through (window); } } - window_actor.visible = animating || visible; - unowned var manager = ShellClientsManager.get_instance (); window.foreach_transient ((transient) => { if (manager.is_itself_positioned (transient)) { diff --git a/vapi/xfixes-4.0.vapi b/vapi/xfixes-4.0.vapi index acd84e05c..6428bfd5a 100644 --- a/vapi/xfixes-4.0.vapi +++ b/vapi/xfixes-4.0.vapi @@ -12,6 +12,12 @@ namespace X { public static void destroy_region (X.Display display, X.XserverRegion region); [CCode (cheader_filename = "X11/extensions/Xfixes.h", cname = "XFixesSetWindowShapeRegion")] public static void set_window_shape_region (X.Display display, X.Window win, int shape_kind, int x_off, int y_off, XserverRegion region); + } + namespace Shape { + [CCode (cheader_filename = "X11/extensions/shape.h", cname = "XShapeGetRectangles")] + public static X.Rectangle* get_rectangles (X.Display display, X.Window win, int kind, out int count, out int ordering); + [CCode (cheader_filename = "X11/extensions/shape.h", cname = "XShapeCombineRectangles")] + public static void combine_rectangles (X.Display display, X.Window win, int kind, int x, int y, [CCode (array_length_cname = "count", type = "XRectangle*")] X.Rectangle[] rectangles, int op, int ordering); } [SimpleType] [CCode (cheader_filename = "X11/extensions/Xfixes.h", cname = "XserverRegion", has_type_id = false)]