mirror of
https://github.com/elementary/gala.git
synced 2024-09-11 07:05:30 +03:00
wayland: Implement make_center (#1942)
Co-authored-by: Danielle Foré <danielle@elementary.io>
This commit is contained in:
parent
060deb2452
commit
f8346f0d4a
@ -111,5 +111,21 @@
|
|||||||
Tell the shell to keep the surface above on all workspaces
|
Tell the shell to keep the surface above on all workspaces
|
||||||
</description>
|
</description>
|
||||||
</request>
|
</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>
|
</interface>
|
||||||
</protocol>
|
</protocol>
|
||||||
|
@ -56,6 +56,8 @@ namespace Pantheon.Desktop {
|
|||||||
public static Wl.Interface iface;
|
public static Wl.Interface iface;
|
||||||
public Destroy destroy;
|
public Destroy destroy;
|
||||||
public SetKeepAbove set_keep_above;
|
public SetKeepAbove set_keep_above;
|
||||||
|
public MakeCentered make_centered;
|
||||||
|
public Focus focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CCode (has_target = false, has_typedef = false)]
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
@ -75,5 +77,7 @@ namespace Pantheon.Desktop {
|
|||||||
[CCode (has_target = false, has_typedef = false)]
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
public delegate void SetKeepAbove (Wl.Client client, Wl.Resource resource);
|
public delegate void SetKeepAbove (Wl.Client client, Wl.Resource resource);
|
||||||
[CCode (has_target = false, has_typedef = false)]
|
[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);
|
public delegate void Destroy (Wl.Client client, Wl.Resource resource);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace Gala {
|
|||||||
wayland_pantheon_panel_interface = {
|
wayland_pantheon_panel_interface = {
|
||||||
destroy_panel_surface,
|
destroy_panel_surface,
|
||||||
set_anchor,
|
set_anchor,
|
||||||
focus,
|
focus_panel,
|
||||||
set_size,
|
set_size,
|
||||||
set_hide_mode,
|
set_hide_mode,
|
||||||
};
|
};
|
||||||
@ -67,9 +67,13 @@ namespace Gala {
|
|||||||
wayland_pantheon_extended_behavior_interface = {
|
wayland_pantheon_extended_behavior_interface = {
|
||||||
destroy_extended_behavior_surface,
|
destroy_extended_behavior_surface,
|
||||||
set_keep_above,
|
set_keep_above,
|
||||||
|
make_centered,
|
||||||
|
focus_extended_behavior,
|
||||||
};
|
};
|
||||||
|
|
||||||
PanelSurface.quark = GLib.Quark.from_string ("-gala-wayland-panel-surface-data");
|
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) => {
|
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);
|
unowned var resource = client.create_resource (ref Pantheon.Desktop.ShellInterface.iface, (int) version, id);
|
||||||
@ -260,15 +264,29 @@ namespace Gala {
|
|||||||
ShellClientsManager.get_instance ().set_anchor (window, side);
|
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> ();
|
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
|
||||||
if (panel_surface.wayland_surface == null) {
|
if (panel_surface.wayland_surface == null) {
|
||||||
warning ("Window tried to focus but wayland surface is null.");
|
warning ("Window tried to focus but wayland surface is null.");
|
||||||
return;
|
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;
|
Meta.Window? window;
|
||||||
panel_surface.wayland_surface.get ("window", out window, null);
|
wayland_surface.get ("window", out window, null);
|
||||||
if (window == null) {
|
if (window == null) {
|
||||||
warning ("Window tried to focus but wayland surface had no associated window.");
|
warning ("Window tried to focus but wayland surface had no associated window.");
|
||||||
return;
|
return;
|
||||||
@ -326,6 +344,21 @@ namespace Gala {
|
|||||||
window.make_above ();
|
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) {
|
internal static void destroy_panel_surface (Wl.Client client, Wl.Resource resource) {
|
||||||
resource.destroy ();
|
resource.destroy ();
|
||||||
}
|
}
|
||||||
|
41
src/ShellClients/CenteredWindow.vala
Normal file
41
src/ShellClients/CenteredWindow.vala
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 elementary, Inc. (https://elementary.io)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ public class Gala.ShellClientsManager : Object {
|
|||||||
private ManagedClient[] protocol_clients = {};
|
private ManagedClient[] protocol_clients = {};
|
||||||
|
|
||||||
private GLib.HashTable<Meta.Window, PanelWindow> windows = new GLib.HashTable<Meta.Window, PanelWindow> (null, null);
|
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) {
|
private ShellClientsManager (WindowManager wm) {
|
||||||
Object (wm: wm);
|
Object (wm: wm);
|
||||||
@ -97,20 +98,22 @@ public class Gala.ShellClientsManager : Object {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_anchor (Meta.Window window, Meta.Side side) {
|
private void make_dock (Meta.Window window) {
|
||||||
if (window in windows) {
|
|
||||||
windows[window].update_anchor (side);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAS_MUTTER46
|
|
||||||
foreach (var client in protocol_clients) {
|
foreach (var client in protocol_clients) {
|
||||||
if (client.wayland_client.owns_window (window)) {
|
if (client.wayland_client.owns_window (window)) {
|
||||||
client.wayland_client.make_dock (window);
|
client.wayland_client.make_dock (window);
|
||||||
break;
|
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?
|
// TODO: Return if requested by window that's not a trusted client?
|
||||||
|
|
||||||
windows[window] = new PanelWindow (wm, window, side);
|
windows[window] = new PanelWindow (wm, window, side);
|
||||||
@ -143,4 +146,14 @@ public class Gala.ShellClientsManager : Object {
|
|||||||
|
|
||||||
windows[window].set_hide_mode (hide_mode);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ gala_bin_sources = files(
|
|||||||
'HotCorners/Barrier.vala',
|
'HotCorners/Barrier.vala',
|
||||||
'HotCorners/HotCorner.vala',
|
'HotCorners/HotCorner.vala',
|
||||||
'HotCorners/HotCornerManager.vala',
|
'HotCorners/HotCornerManager.vala',
|
||||||
|
'ShellClients/CenteredWindow.vala',
|
||||||
'ShellClients/HideTracker.vala',
|
'ShellClients/HideTracker.vala',
|
||||||
'ShellClients/ManagedClient.vala',
|
'ShellClients/ManagedClient.vala',
|
||||||
'ShellClients/NotificationsClient.vala',
|
'ShellClients/NotificationsClient.vala',
|
||||||
|
Loading…
Reference in New Issue
Block a user