diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/astal.vala | 137 | ||||
-rw-r--r-- | src/cli.vala | 41 |
2 files changed, 164 insertions, 14 deletions
diff --git a/src/astal.vala b/src/astal.vala index fd8431b..3e94dfc 100644 --- a/src/astal.vala +++ b/src/astal.vala @@ -1,16 +1,14 @@ namespace Astal { +[DBus (name="io.Astal.Application")] public class Application : Gtk.Application { private List<Gtk.CssProvider> css_providers = new List<Gtk.CssProvider>(); private SocketService service; + private DBusConnection conn; + private string _instance_name; public string socket_path { get; private set; } - public new string application_id { - get { return base.application_id; } - set { base.application_id = value; } - } - - private string _instance_name; + [DBus (visible=false)] public string instance_name { get { return _instance_name; } set { @@ -19,33 +17,40 @@ public class Application : Gtk.Application { } } + [DBus (visible=false)] public List<Gtk.Window> windows { get { return get_windows(); } } + [DBus (visible=false)] public Gtk.Settings settings { get { return Gtk.Settings.get_default(); } } + [DBus (visible=false)] public Gdk.Screen screen { get { return Gdk.Screen.get_default(); } } + [DBus (visible=false)] public string gtk_theme { owned get { return settings.gtk_theme_name; } set { settings.gtk_theme_name = value; } } + [DBus (visible=false)] public string icon_theme { owned get { return settings.gtk_icon_theme_name; } set { settings.gtk_icon_theme_name = value; } } + [DBus (visible=false)] public string cursor_theme { owned get { return settings.gtk_cursor_theme_name; } set { settings.gtk_cursor_theme_name = value; } } + [DBus (visible=false)] public void reset_css() { foreach(var provider in css_providers) { Gtk.StyleContext.remove_provider_for_screen(screen, provider); @@ -53,10 +58,11 @@ public class Application : Gtk.Application { css_providers = new List<Gtk.CssProvider>(); } - public void inspector() { + public void inspector() throws DBusError, IOError { Gtk.Window.set_interactive_debugging(true); } + [DBus (visible=false)] public Gtk.Window? get_window(string name) { foreach(var win in windows) { if (win.name == name) @@ -67,6 +73,16 @@ public class Application : Gtk.Application { return null; } + public void toggle_window(string window) throws DBusError, IOError { + var win = get_window(window); + if (win != null) { + win.visible = !win.visible; + } else { + throw new IOError.FAILED("window not found"); + } + } + + [DBus (visible=false)] public void apply_css(string style, bool reset = false) { var provider = new Gtk.CssProvider(); @@ -88,6 +104,7 @@ public class Application : Gtk.Application { css_providers.append(provider); } + [DBus (visible=false)] public void add_icons(string? path) { if (path != null) Gtk.IconTheme.get_default().prepend_search_path(path); @@ -98,6 +115,7 @@ public class Application : Gtk.Application { request(message != null ? message.strip() : "", conn); } + [DBus (visible=false)] public virtual void request(string msg, SocketConnection conn) { write_sock.begin(conn, "missing response implementation on ".concat(application_id)); } @@ -106,6 +124,7 @@ public class Application : Gtk.Application { * should be called before `run()` * the return value indicates if instance is already running */ + [DBus (visible=false)] public bool acquire_socket() { socket_path = GLib.Environment.get_user_runtime_dir().concat( "/", @@ -131,6 +150,22 @@ public class Application : Gtk.Application { return false; }); + + Bus.own_name( + BusType.SESSION, + "io.Astal." + instance_name, + BusNameOwnerFlags.NONE, + (conn) => { + try { + this.conn = conn; + conn.register_object("/io/Astal/Application", this); + } catch (Error err) { + critical(err.message); + } + }, + () => {}, + () => {}); + info("socket acquired: %s\n", socket_path); return true; } catch (Error err) { @@ -140,6 +175,7 @@ public class Application : Gtk.Application { } } + [DBus (visible=false)] public string? message(string? msg) { var client = new SocketClient(); @@ -172,11 +208,90 @@ public class Application : Gtk.Application { } }); - SourceFunc close = () => { quit(); }; - Unix.signal_add(1, close, Priority.HIGH); - Unix.signal_add(2, close, Priority.HIGH); - Unix.signal_add(15, close, Priority.HIGH); + Unix.signal_add(1, () => { try { quit(); } catch(Error err) {} }, Priority.HIGH); + Unix.signal_add(2, () => { try { quit(); } catch(Error err) {} }, Priority.HIGH); + Unix.signal_add(15, () => { try { quit(); } catch(Error err) {} }, Priority.HIGH); } + + public new void quit() throws DBusError, IOError { + base.quit(); + } + + public static List<string> get_instances() { + var list = new List<string>(); + var prefix = "io.Astal."; + + try { + DBusImpl dbus = Bus.get_proxy_sync( + BusType.SESSION, + "org.freedesktop.DBus", + "/org/freedesktop/DBus" + ); + + foreach (var busname in dbus.list_names()) { + if (busname.has_prefix(prefix)) + list.append(busname.replace(prefix, "")); + } + } catch (Error err) { + critical(err.message); + } + + return list; + } + + public static void quit_instance(string instance) { + try { + IApplication proxy = Bus.get_proxy_sync( + BusType.SESSION, + "io.Astal." + instance, + "/io/Astal/Application" + ); + + proxy.quit(); + } catch (Error err) { + critical(err.message); + } + } + + public static void open_inspector(string instance) { + try { + IApplication proxy = Bus.get_proxy_sync( + BusType.SESSION, + "io.Astal." + instance, + "/io/Astal/Application" + ); + + proxy.inspector(); + } catch (Error err) { + critical(err.message); + } + } + + public static void toggle_window_by_name(string instance, string window) { + try { + IApplication proxy = Bus.get_proxy_sync( + BusType.SESSION, + "io.Astal." + instance, + "/io/Astal/Application" + ); + + proxy.toggle_window(window); + } catch (Error err) { + critical(err.message); + } + } +} + +[DBus (name="org.freedesktop.DBus")] +private interface DBusImpl : DBusProxy { + public abstract string[] list_names() throws GLib.Error; +} + +[DBus (name="io.Astal.Application")] +private interface IApplication : DBusProxy { + public abstract void quit() throws GLib.Error; + public abstract void inspector() throws GLib.Error; + public abstract void toggle_window(string window) throws GLib.Error; } public async string read_sock(SocketConnection conn) { diff --git a/src/cli.vala b/src/cli.vala index 82a99a4..3da4586 100644 --- a/src/cli.vala +++ b/src/cli.vala @@ -1,11 +1,20 @@ private static bool version; private static bool help; +private static bool list; +private static bool quit; +private static bool inspector; +private static string? toggle_window; private static string? instance_name; private const GLib.OptionEntry[] options = { { "version", 'v', OptionFlags.NONE, OptionArg.NONE, ref version, null, null }, { "help", 'h', OptionFlags.NONE, OptionArg.NONE, ref help, null, null }, - { "instance-name", 'i', OptionFlags.NONE, OptionArg.STRING, ref instance_name, null, null }, + { "list", 'l', OptionFlags.NONE, OptionArg.NONE, ref list, null, null }, + { "quit", 'q', OptionFlags.NONE, OptionArg.NONE, ref quit, null, null }, + { "quit", 'q', OptionFlags.NONE, OptionArg.NONE, ref quit, null, null }, + { "inspector", 'I', OptionFlags.NONE, OptionArg.NONE, ref inspector, null, null }, + { "toggle-window", 't', OptionFlags.NONE, OptionArg.STRING, ref toggle_window, null, null }, + { "instance", 'i', OptionFlags.NONE, OptionArg.STRING, ref instance_name, null, null }, { null }, }; @@ -22,13 +31,17 @@ async int main(string[] argv) { } if (help) { - print("Client for the socket of an Astal.Application instance\n\n"); + print("Client for Astal.Application instances\n\n"); print("Usage:\n"); print(" %s [flags] message\n\n", argv[0]); print("Flags:\n"); print(" -h, --help Print this help and exit\n"); print(" -v, --version Print version number and exit\n"); - print(" -i, --instance-name Instance name of the Astal instance\n"); + print(" -l, --list List running Astal instances and exit\n"); + print(" -q, --quit Quit an Astal.Application instance\n"); + print(" -i, --instance Instance name of the Astal instance\n"); + print(" -I, --inspector Open up Gtk debug tool\n"); + print(" -t, --toggle-window Show or hide a window\n"); return 0; } @@ -40,6 +53,28 @@ async int main(string[] argv) { if (instance_name == null) instance_name = "astal"; + if (list) { + foreach (var name in Astal.Application.get_instances()) + stdout.printf("%s\n", name); + + return 0; + } + + if (quit) { + Astal.Application.quit_instance(instance_name); + return 0; + } + + if (inspector) { + Astal.Application.open_inspector(instance_name); + return 0; + } + + if (toggle_window != null) { + Astal.Application.toggle_window_by_name(instance_name, toggle_window); + return 0; + } + var request = ""; for (var i = 1; i < argv.length; ++i) { request = request.concat(" ", argv[i]); |