Skip to content

Commit

Permalink
wayland: Implement make_center (#1942)
Browse files Browse the repository at this point in the history
Co-authored-by: Danielle Foré <[email protected]>
  • Loading branch information
leolost2605 and danirabbit authored Jul 12, 2024
1 parent 060deb2 commit f8346f0
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 11 deletions.
16 changes: 16 additions & 0 deletions protocol/pantheon-desktop-shell-v1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,21 @@
Tell the shell to keep the surface above on all workspaces
</description>
</request>

<request name="make_centered">
<description summary="requests to keep the surface centered">
Request to keep the surface centered. This will cause keyboard focus
to not be granted automatically but having to be requested via focus.
</description>
</request>

<request name="focus">
<description summary="request keyboard focus">
Request keyboard focus, taking it away from any other window.
Keyboard focus must always be manually be requested and is
- in contrast to normal windows - never automatically granted
by the compositor.
</description>
</request>
</interface>
</protocol>
4 changes: 4 additions & 0 deletions protocol/pantheon-desktop-shell.vapi
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ namespace Pantheon.Desktop {
public static Wl.Interface iface;
public Destroy destroy;
public SetKeepAbove set_keep_above;
public MakeCentered make_centered;
public Focus focus;
}

[CCode (has_target = false, has_typedef = false)]
Expand All @@ -75,5 +77,7 @@ namespace Pantheon.Desktop {
[CCode (has_target = false, has_typedef = false)]
public delegate void SetKeepAbove (Wl.Client client, Wl.Resource resource);
[CCode (has_target = false, has_typedef = false)]
public delegate void MakeCentered (Wl.Client client, Wl.Resource resource);
[CCode (has_target = false, has_typedef = false)]
public delegate void Destroy (Wl.Client client, Wl.Resource resource);
}
39 changes: 36 additions & 3 deletions src/PantheonShell.vala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace Gala {
wayland_pantheon_panel_interface = {
destroy_panel_surface,
set_anchor,
focus,
focus_panel,
set_size,
set_hide_mode,
};
Expand All @@ -67,9 +67,13 @@ namespace Gala {
wayland_pantheon_extended_behavior_interface = {
destroy_extended_behavior_surface,
set_keep_above,
make_centered,
focus_extended_behavior,
};

PanelSurface.quark = GLib.Quark.from_string ("-gala-wayland-panel-surface-data");
WidgetSurface.quark = GLib.Quark.from_string ("-gala-wayland-widget-surface-data");
ExtendedBehaviorSurface.quark = GLib.Quark.from_string ("-gala-wayland-extended-behavior-surface-data");

shell_global = Wl.Global.create (wl_disp, ref Pantheon.Desktop.ShellInterface.iface, 1, (client, version, id) => {
unowned var resource = client.create_resource (ref Pantheon.Desktop.ShellInterface.iface, (int) version, id);
Expand Down Expand Up @@ -260,15 +264,29 @@ namespace Gala {
ShellClientsManager.get_instance ().set_anchor (window, side);
}

internal static void focus (Wl.Client client, Wl.Resource resource) {
internal static void focus_panel (Wl.Client client, Wl.Resource resource) {
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
if (panel_surface.wayland_surface == null) {
warning ("Window tried to focus but wayland surface is null.");
return;
}

focus (panel_surface.wayland_surface);
}

internal static void focus_extended_behavior (Wl.Client client, Wl.Resource resource) {
unowned ExtendedBehaviorSurface? extended_behavior_surface = resource.get_user_data<ExtendedBehaviorSurface> ();
if (extended_behavior_surface.wayland_surface == null) {
warning ("Window tried to focus but wayland surface is null.");
return;
}

focus (extended_behavior_surface.wayland_surface);
}

internal static void focus (Object wayland_surface) {
Meta.Window? window;
panel_surface.wayland_surface.get ("window", out window, null);
wayland_surface.get ("window", out window, null);
if (window == null) {
warning ("Window tried to focus but wayland surface had no associated window.");
return;
Expand Down Expand Up @@ -326,6 +344,21 @@ namespace Gala {
window.make_above ();
}

internal static void make_centered (Wl.Client client, Wl.Resource resource) {
unowned ExtendedBehaviorSurface? eb_surface = resource.get_user_data<ExtendedBehaviorSurface> ();
if (eb_surface.wayland_surface == null) {
return;
}

Meta.Window? window;
eb_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
return;
}

ShellClientsManager.get_instance ().make_centered (window);
}

internal static void destroy_panel_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}
Expand Down
41 changes: 41 additions & 0 deletions src/ShellClients/CenteredWindow.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authored by: Leonhard Kargl <[email protected]>
*/

public class Gala.CenteredWindow : Object {
public WindowManager wm { get; construct; }
public Meta.Window window { get; construct; }

public CenteredWindow (WindowManager wm, Meta.Window window) {
Object (wm: wm, window: window);
}

construct {
window.size_changed.connect (position_window);
window.stick ();

var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager ();
monitor_manager.monitors_changed.connect (() => position_window ());

position_window ();

window.shown.connect (() => window.focus (wm.get_display ().get_current_time ()));
}

private void position_window () {
var display = wm.get_display ();
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
var window_rect = window.get_frame_rect ();

var x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2;
var y = monitor_geom.y + (monitor_geom.height - window_rect.height) / 2;

Idle.add (() => {
window.move_frame (false, x, y);
return Source.REMOVE;
});
}
}
29 changes: 21 additions & 8 deletions src/ShellClients/ShellClientsManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class Gala.ShellClientsManager : Object {
private ManagedClient[] protocol_clients = {};

private GLib.HashTable<Meta.Window, PanelWindow> windows = new GLib.HashTable<Meta.Window, PanelWindow> (null, null);
private GLib.HashTable<Meta.Window, CenteredWindow> centered_windows = new GLib.HashTable<Meta.Window, CenteredWindow> (null, null);

private ShellClientsManager (WindowManager wm) {
Object (wm: wm);
Expand Down Expand Up @@ -97,20 +98,22 @@ public class Gala.ShellClientsManager : Object {
}
}

public void set_anchor (Meta.Window window, Meta.Side side) {
if (window in windows) {
windows[window].update_anchor (side);
return;
}

#if HAS_MUTTER46
private void make_dock (Meta.Window window) {
foreach (var client in protocol_clients) {
if (client.wayland_client.owns_window (window)) {
client.wayland_client.make_dock (window);
break;
}
}
#endif
}

public void set_anchor (Meta.Window window, Meta.Side side) {
if (window in windows) {
windows[window].update_anchor (side);
return;
}

make_dock (window);
// TODO: Return if requested by window that's not a trusted client?

windows[window] = new PanelWindow (wm, window, side);
Expand Down Expand Up @@ -143,4 +146,14 @@ public class Gala.ShellClientsManager : Object {

windows[window].set_hide_mode (hide_mode);
}

public void make_centered (Meta.Window window) {
if (window in centered_windows) {
return;
}

make_dock (window);

centered_windows[window] = new CenteredWindow (wm, window);
}
}
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ gala_bin_sources = files(
'HotCorners/Barrier.vala',
'HotCorners/HotCorner.vala',
'HotCorners/HotCornerManager.vala',
'ShellClients/CenteredWindow.vala',
'ShellClients/HideTracker.vala',
'ShellClients/ManagedClient.vala',
'ShellClients/NotificationsClient.vala',
Expand Down

0 comments on commit f8346f0

Please sign in to comment.