2024-02-18 05:03:26 +03:00
|
|
|
/*
|
|
|
|
* Copyright 2024 elementary, Inc. (https://elementary.io)
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
*/
|
|
|
|
|
2024-07-05 21:14:35 +03:00
|
|
|
public enum Gala.ActionType {
|
|
|
|
NONE = 0,
|
|
|
|
SHOW_WORKSPACE_VIEW,
|
|
|
|
MAXIMIZE_CURRENT,
|
|
|
|
HIDE_CURRENT,
|
|
|
|
OPEN_LAUNCHER,
|
|
|
|
CUSTOM_COMMAND,
|
|
|
|
WINDOW_OVERVIEW,
|
|
|
|
WINDOW_OVERVIEW_ALL,
|
|
|
|
SWITCH_TO_WORKSPACE_PREVIOUS,
|
|
|
|
SWITCH_TO_WORKSPACE_NEXT,
|
|
|
|
SWITCH_TO_WORKSPACE_LAST,
|
|
|
|
START_MOVE_CURRENT,
|
|
|
|
START_RESIZE_CURRENT,
|
|
|
|
TOGGLE_ALWAYS_ON_TOP_CURRENT,
|
|
|
|
TOGGLE_ALWAYS_ON_VISIBLE_WORKSPACE_CURRENT,
|
|
|
|
MOVE_CURRENT_WORKSPACE_LEFT,
|
|
|
|
MOVE_CURRENT_WORKSPACE_RIGHT,
|
|
|
|
CLOSE_CURRENT,
|
|
|
|
SCREENSHOT_CURRENT
|
|
|
|
}
|
|
|
|
|
|
|
|
[Flags]
|
|
|
|
public enum Gala.WindowFlags {
|
|
|
|
NONE = 0,
|
|
|
|
CAN_HIDE,
|
|
|
|
CAN_MAXIMIZE,
|
|
|
|
IS_MAXIMIZED,
|
|
|
|
ALLOWS_MOVE,
|
|
|
|
ALLOWS_RESIZE,
|
|
|
|
ALWAYS_ON_TOP,
|
|
|
|
ON_ALL_WORKSPACES,
|
|
|
|
CAN_CLOSE,
|
|
|
|
IS_TILED
|
|
|
|
}
|
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
[DBus (name = "org.pantheon.gala")]
|
|
|
|
public interface Gala.WMDBus : GLib.Object {
|
|
|
|
public abstract void perform_action (Gala.ActionType type) throws DBusError, IOError;
|
|
|
|
}
|
2018-09-11 01:16:52 +03:00
|
|
|
|
2024-02-20 02:15:24 +03:00
|
|
|
public struct Gala.Daemon.MonitorLabelInfo {
|
|
|
|
public int monitor;
|
|
|
|
public string label;
|
|
|
|
public string background_color;
|
|
|
|
public string text_color;
|
|
|
|
public int x;
|
|
|
|
public int y;
|
|
|
|
}
|
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
[DBus (name = "org.pantheon.gala.daemon")]
|
2024-02-20 02:15:24 +03:00
|
|
|
public class Gala.Daemon.DBus : GLib.Object {
|
2023-02-18 20:32:32 +03:00
|
|
|
private const string DBUS_NAME = "org.pantheon.gala";
|
|
|
|
private const string DBUS_OBJECT_PATH = "/org/pantheon/gala";
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2023-02-18 20:32:32 +03:00
|
|
|
private const string DAEMON_DBUS_NAME = "org.pantheon.gala.daemon";
|
|
|
|
private const string DAEMON_DBUS_OBJECT_PATH = "/org/pantheon/gala/daemon";
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-07-05 21:14:35 +03:00
|
|
|
private const string BG_MENU_ACTION_GROUP_PREFIX = "background-menu";
|
|
|
|
private const string BG_MENU_ACTION_PREFIX = BG_MENU_ACTION_GROUP_PREFIX + ".";
|
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
private WMDBus? wm_proxy = null;
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-07-05 21:14:35 +03:00
|
|
|
private Window window;
|
2024-02-18 05:03:26 +03:00
|
|
|
private WindowMenu? window_menu;
|
2024-07-05 21:14:35 +03:00
|
|
|
private Gtk.PopoverMenu background_menu;
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-02-20 02:15:24 +03:00
|
|
|
private List<MonitorLabel> monitor_labels = new List<MonitorLabel> ();
|
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
construct {
|
|
|
|
Bus.watch_name (BusType.SESSION, DBUS_NAME, BusNameWatcherFlags.NONE, gala_appeared, lost_gala);
|
2024-07-05 21:14:35 +03:00
|
|
|
|
|
|
|
window = new Window ();
|
|
|
|
|
|
|
|
var background_menu_top_section = new Menu ();
|
|
|
|
background_menu_top_section.append (
|
|
|
|
_("Change Wallpaper…"),
|
|
|
|
Action.print_detailed_name (BG_MENU_ACTION_PREFIX + "launch-uri", "settings://desktop/appearance/wallpaper")
|
|
|
|
);
|
|
|
|
background_menu_top_section.append (
|
|
|
|
_("Display Settings…"),
|
|
|
|
Action.print_detailed_name (BG_MENU_ACTION_PREFIX + "launch-uri", "settings://display")
|
|
|
|
);
|
|
|
|
|
|
|
|
var background_menu_bottom_section = new Menu ();
|
|
|
|
background_menu_bottom_section.append (
|
|
|
|
_("System Settings…"),
|
|
|
|
Action.print_detailed_name (BG_MENU_ACTION_PREFIX + "launch-uri", "settings://")
|
|
|
|
);
|
|
|
|
|
|
|
|
var background_menu_model = new Menu ();
|
|
|
|
background_menu_model.append_section (null, background_menu_top_section);
|
|
|
|
background_menu_model.append_section (null, background_menu_bottom_section);
|
|
|
|
|
|
|
|
background_menu = new Gtk.PopoverMenu.from_model (background_menu_model) {
|
|
|
|
halign = START,
|
|
|
|
position = BOTTOM,
|
|
|
|
autohide = false,
|
|
|
|
has_arrow = false
|
|
|
|
};
|
|
|
|
background_menu.set_parent (window.child);
|
|
|
|
background_menu.closed.connect (window.close);
|
|
|
|
|
|
|
|
var launch_action = new SimpleAction ("launch-uri", VariantType.STRING);
|
|
|
|
launch_action.activate.connect (action_launch);
|
|
|
|
|
|
|
|
var action_group = new SimpleActionGroup ();
|
|
|
|
action_group.add_action (launch_action);
|
|
|
|
|
|
|
|
background_menu.insert_action_group (BG_MENU_ACTION_GROUP_PREFIX, action_group);
|
|
|
|
|
|
|
|
window_menu = new WindowMenu ();
|
|
|
|
window_menu.set_parent (window.child);
|
|
|
|
window_menu.closed.connect (window.close);
|
|
|
|
window_menu.perform_action.connect ((type) => {
|
|
|
|
Idle.add (() => {
|
|
|
|
perform_action (type);
|
|
|
|
return Source.REMOVE;
|
|
|
|
});
|
|
|
|
});
|
2024-02-18 05:03:26 +03:00
|
|
|
}
|
2020-01-15 18:06:13 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
private void on_gala_get (GLib.Object? obj, GLib.AsyncResult? res) {
|
|
|
|
try {
|
|
|
|
wm_proxy = Bus.get_proxy.end (res);
|
|
|
|
} catch (Error e) {
|
|
|
|
warning ("Failed to get Gala proxy: %s", e.message);
|
2020-01-15 18:06:13 +03:00
|
|
|
}
|
2024-02-18 05:03:26 +03:00
|
|
|
}
|
2020-01-15 18:06:13 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
private void lost_gala () {
|
|
|
|
wm_proxy = null;
|
|
|
|
}
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
private void gala_appeared () {
|
|
|
|
if (wm_proxy == null) {
|
|
|
|
Bus.get_proxy.begin<WMDBus> (BusType.SESSION, DBUS_NAME, DBUS_OBJECT_PATH, 0, null, on_gala_get);
|
2019-09-24 20:33:52 +03:00
|
|
|
}
|
2024-02-18 05:03:26 +03:00
|
|
|
}
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
private void perform_action (Gala.ActionType type) {
|
|
|
|
if (wm_proxy != null) {
|
2019-09-24 20:33:52 +03:00
|
|
|
try {
|
2024-02-18 05:03:26 +03:00
|
|
|
wm_proxy.perform_action (type);
|
2019-09-24 20:33:52 +03:00
|
|
|
} catch (Error e) {
|
2024-02-18 05:03:26 +03:00
|
|
|
warning ("Failed to perform Gala action over DBus: %s", e.message);
|
2019-09-24 20:33:52 +03:00
|
|
|
}
|
|
|
|
}
|
2024-02-18 05:03:26 +03:00
|
|
|
}
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
public void show_window_menu (Gala.WindowFlags flags, int display_width, int display_height, int x, int y) throws DBusError, IOError {
|
|
|
|
window_menu.update (flags);
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-07-05 21:14:35 +03:00
|
|
|
show_menu (window_menu, display_width, display_height, x, y);
|
2024-02-18 05:03:26 +03:00
|
|
|
}
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
public void show_desktop_menu (int display_width, int display_height, int x, int y) throws DBusError, IOError {
|
2024-07-05 21:14:35 +03:00
|
|
|
show_menu (background_menu, display_width, display_height, x, y);
|
2024-02-18 05:03:26 +03:00
|
|
|
}
|
2021-03-05 09:48:28 +03:00
|
|
|
|
2024-07-05 21:14:35 +03:00
|
|
|
private void show_menu (Gtk.Popover menu, int display_width, int display_height, int x, int y) {
|
|
|
|
window.default_width = display_width;
|
|
|
|
window.default_height = display_height;
|
2024-02-18 05:03:26 +03:00
|
|
|
window.present ();
|
2021-03-05 09:48:28 +03:00
|
|
|
|
2024-02-18 05:03:26 +03:00
|
|
|
Gdk.Rectangle rect = {
|
|
|
|
x,
|
|
|
|
y,
|
|
|
|
0,
|
|
|
|
0
|
|
|
|
};
|
2024-07-05 21:14:35 +03:00
|
|
|
menu.pointing_to = rect;
|
2019-09-24 20:33:52 +03:00
|
|
|
|
2024-07-05 21:14:35 +03:00
|
|
|
Idle.add (() => {
|
|
|
|
menu.popup ();
|
|
|
|
return Source.REMOVE;
|
|
|
|
});
|
2019-09-24 20:33:52 +03:00
|
|
|
}
|
2024-02-20 02:15:24 +03:00
|
|
|
|
|
|
|
public void show_monitor_labels (MonitorLabelInfo[] label_infos) throws GLib.DBusError, GLib.IOError {
|
|
|
|
hide_monitor_labels ();
|
|
|
|
|
|
|
|
monitor_labels = new List<MonitorLabel> ();
|
|
|
|
foreach (var info in label_infos) {
|
|
|
|
var label = new MonitorLabel (info);
|
|
|
|
monitor_labels.append (label);
|
|
|
|
label.present ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void hide_monitor_labels () throws GLib.DBusError, GLib.IOError {
|
|
|
|
foreach (var monitor_label in monitor_labels) {
|
|
|
|
monitor_label.close ();
|
|
|
|
}
|
|
|
|
}
|
2024-07-05 21:14:35 +03:00
|
|
|
|
|
|
|
private static void action_launch (SimpleAction action, Variant? variant) {
|
|
|
|
try {
|
|
|
|
AppInfo.launch_default_for_uri (variant.get_string (), null);
|
|
|
|
} catch (Error e) {
|
|
|
|
var message_dialog = new Granite.MessageDialog.with_image_from_icon_name (
|
|
|
|
_("Failed to open System Settings"),
|
|
|
|
_("A handler for the “settings://” URI scheme must be installed."),
|
|
|
|
"dialog-error",
|
|
|
|
Gtk.ButtonsType.CLOSE
|
|
|
|
);
|
|
|
|
message_dialog.show_error_details (e.message);
|
|
|
|
message_dialog.present ();
|
|
|
|
message_dialog.response.connect (message_dialog.destroy);
|
|
|
|
}
|
|
|
|
}
|
2018-09-11 01:16:52 +03:00
|
|
|
}
|