Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X11: Use window shape to fix input for invisible windows #2142

Merged
merged 2 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions lib/Utils.vala
Original file line number Diff line number Diff line change
Expand Up @@ -400,5 +400,50 @@ namespace Gala {

return texture;
}

private static HashTable<Meta.Window, X.XserverRegion?> regions = new HashTable<Meta.Window, X.XserverRegion?> (null, null);

public static void x11_set_window_pass_through (Meta.Window window) {
unowned var x11_display = window.display.get_x11_display ();

#if HAS_MUTTER46
var x_window = x11_display.lookup_xwindow (window);
#else
var x_window = window.get_xwindow ();
#endif
unowned var xdisplay = x11_display.get_xdisplay ();

regions[window] = X.Fixes.create_region_from_window (xdisplay, x_window, 0);

X.Xrectangle rect = {};

var region = X.Fixes.create_region (xdisplay, {rect});

X.Fixes.set_window_shape_region (xdisplay, x_window, 2, 0, 0, region);

X.Fixes.destroy_region (xdisplay, region);
}

public static void x11_unset_window_pass_through (Meta.Window window) {
unowned var x11_display = window.display.get_x11_display ();

#if HAS_MUTTER46
var x_window = x11_display.lookup_xwindow (window);
#else
var x_window = window.get_xwindow ();
#endif
unowned var xdisplay = x11_display.get_xdisplay ();

var region = regions[window];

if (region == null) {
return;
}

X.Fixes.set_window_shape_region (xdisplay, x_window, 2, 0, 0, region);

regions.remove (window);
X.Fixes.destroy_region (xdisplay, region);
}
}
}
42 changes: 0 additions & 42 deletions src/ShellClients/DelegateActor.vala

This file was deleted.

14 changes: 7 additions & 7 deletions src/ShellClients/PanelClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public class Gala.PanelClone : Object {
actor = (Meta.WindowActor) panel.window.get_compositor_private ();
// WindowActor position and Window position aren't necessarily the same.
// The clone needs the actor position
panel.delegate_actor.notify["x"].connect (update_clone_position);
panel.delegate_actor.notify["y"].connect (update_clone_position);
actor.notify["x"].connect (update_clone_position);
actor.notify["y"].connect (update_clone_position);
// Actor visibility might be changed by something else e.g. workspace switch
// but we want to keep it in sync with us
actor.notify["visible"].connect (update_visible);
Expand Down Expand Up @@ -97,7 +97,7 @@ public class Gala.PanelClone : Object {
switch (panel.anchor) {
case TOP:
case BOTTOM:
return panel.delegate_actor.x;
return actor.x;
default:
return 0;
}
Expand All @@ -106,9 +106,9 @@ public class Gala.PanelClone : Object {
private float calculate_clone_y (bool hidden) {
switch (panel.anchor) {
case TOP:
return hidden ? panel.delegate_actor.y - actor.height : panel.delegate_actor.y;
return hidden ? actor.y - actor.height : actor.y;
case BOTTOM:
return hidden ? panel.delegate_actor.y + actor.height : panel.delegate_actor.y;
return hidden ? actor.y + actor.height : actor.y;
default:
return 0;
}
Expand All @@ -128,7 +128,7 @@ public class Gala.PanelClone : Object {
panel_hidden = true;

if (!Meta.Util.is_wayland_compositor ()) {
panel.window.move_frame (false, DelegateActor.OUT_OF_BOUNDS, DelegateActor.OUT_OF_BOUNDS);
Utils.x11_set_window_pass_through (panel.window);
}

if (panel.anchor != TOP && panel.anchor != BOTTOM) {
Expand All @@ -151,7 +151,7 @@ public class Gala.PanelClone : Object {
}

if (!Meta.Util.is_wayland_compositor ()) {
panel.window.move_frame (false, panel.delegate_actor.actual_x, panel.delegate_actor.actual_y);
Utils.x11_unset_window_pass_through (panel.window);
}

clone.save_easing_state ();
Expand Down
4 changes: 0 additions & 4 deletions src/ShellClients/PanelWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public class Gala.PanelWindow : Object {

public Meta.Side anchor;

public DelegateActor delegate_actor;
private PanelClone clone;

private uint idle_move_id = 0;
Expand Down Expand Up @@ -46,7 +45,6 @@ public class Gala.PanelWindow : Object {

window.stick ();

delegate_actor = new DelegateActor ((Meta.WindowActor) window.get_compositor_private ());
clone = new PanelClone (wm, this);

var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager ();
Expand All @@ -64,8 +62,6 @@ public class Gala.PanelWindow : Object {
public Meta.Rectangle get_custom_window_rect () {
#endif
var window_rect = window.get_frame_rect ();
window_rect.x = delegate_actor.actual_x;
window_rect.y = delegate_actor.actual_y;

if (width > 0) {
window_rect.width = width;
Expand Down
1 change: 0 additions & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ gala_bin_sources = files(
'HotCorners/Barrier.vala',
'HotCorners/HotCorner.vala',
'HotCorners/HotCornerManager.vala',
'ShellClients/DelegateActor.vala',
'ShellClients/HideTracker.vala',
'ShellClients/ManagedClient.vala',
'ShellClients/NotificationsClient.vala',
Expand Down
4 changes: 4 additions & 0 deletions vapi/xfixes-4.0.vapi
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ namespace X {
namespace Fixes {
[CCode (cheader_filename = "X11/extensions/Xfixes.h", cname = "XFixesCreateRegion")]
public static X.XserverRegion create_region (X.Display display, [CCode (array_length = true)] X.Xrectangle[] rectangles);
[CCode (cheader_filename = "X11/extensions/Xfixes.h", cname = "XFixesCreateRegionFromWindow")]
public static X.XserverRegion create_region_from_window (X.Display display, X.Window window, int shape_kind);
[CCode (cheader_filename = "X11/extensions/Xfixes.h", cname = "XFixesDestroyRegion")]
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);
}
[SimpleType]
[CCode (cheader_filename = "X11/extensions/Xfixes.h", cname = "XserverRegion", has_type_id = false)]
Expand Down
Loading