diff options
author | kotontrion <[email protected]> | 2024-11-16 12:40:07 +0100 |
---|---|---|
committer | kotontrion <[email protected]> | 2024-11-16 12:40:07 +0100 |
commit | 1351db8d5b80c7521e808f81c91977a5dd2d9d34 (patch) | |
tree | a1469ed4aaca0f1f42e6d9a9251f5ccc9ff8bf78 /lib | |
parent | e674e8f6e49e74edde795e012adbfe0fcfd8d729 (diff) | |
parent | 433984c5830aac3fcde66ffff93d0dc7e5e69366 (diff) |
Merge branch 'main' into feat/tray-gtk4
Diffstat (limited to 'lib')
l---------[-rw-r--r--] | lib/astal/gtk4/gir.py | 59 | ||||
l---------[-rw-r--r--] | lib/astal/io/gir.py | 59 | ||||
-rw-r--r-- | lib/gir.py | 3 | ||||
-rw-r--r-- | lib/hyprland/monitor.vala | 24 | ||||
-rw-r--r-- | lib/network/network.vala | 26 | ||||
-rw-r--r-- | lib/powerprofiles/cli.vala | 49 | ||||
l--------- | lib/powerprofiles/gir.py | 1 | ||||
-rw-r--r-- | lib/powerprofiles/meson.build | 44 | ||||
-rw-r--r-- | lib/powerprofiles/power-profiles.vala | 109 | ||||
-rw-r--r-- | lib/tray/meson.build | 2 |
10 files changed, 178 insertions, 198 deletions
diff --git a/lib/astal/gtk4/gir.py b/lib/astal/gtk4/gir.py index 9ef680f..16a3a64 100644..120000 --- a/lib/astal/gtk4/gir.py +++ b/lib/astal/gtk4/gir.py @@ -1,58 +1 @@ -""" -Vala's generated gir does not contain comments, -so we use valadoc to generate them. However, they are formatted -for valadoc and not gi-docgen so we need to fix it. -""" - -import xml.etree.ElementTree as ET -import html -import sys -import subprocess - - -def fix_gir(name: str, gir: str, out: str): - namespaces = { - "": "http://www.gtk.org/introspection/core/1.0", - "c": "http://www.gtk.org/introspection/c/1.0", - "glib": "http://www.gtk.org/introspection/glib/1.0", - } - for prefix, uri in namespaces.items(): - ET.register_namespace(prefix, uri) - - tree = ET.parse(gir) - root = tree.getroot() - - for doc in root.findall(".//doc", namespaces): - if doc.text: - doc.text = ( - html.unescape(doc.text).replace("<para>", "").replace("</para>", "") - ) - - if (inc := root.find("c:include", namespaces)) is not None: - inc.set("name", f"{name}.h") - else: - print("no c:include tag found", file=sys.stderr) - exit(1) - - tree.write(out, encoding="utf-8", xml_declaration=True) - - -def valadoc(name: str, gir: str, args: list[str]): - cmd = ["valadoc", "-o", "docs", "--package-name", name, "--gir", gir, *args] - try: - subprocess.run(cmd, check=True, text=True, capture_output=True) - except subprocess.CalledProcessError as e: - print(e.stderr, file=sys.stderr) - exit(1) - - -if __name__ == "__main__": - name = sys.argv[1] - in_out = sys.argv[2].split(":") - args = sys.argv[3:] - - gir = in_out[0] - out = in_out[1] if len(in_out) > 1 else gir - - valadoc(name, gir, args) - fix_gir(name, gir, out) +../../gir.py
\ No newline at end of file diff --git a/lib/astal/io/gir.py b/lib/astal/io/gir.py index 9ef680f..16a3a64 100644..120000 --- a/lib/astal/io/gir.py +++ b/lib/astal/io/gir.py @@ -1,58 +1 @@ -""" -Vala's generated gir does not contain comments, -so we use valadoc to generate them. However, they are formatted -for valadoc and not gi-docgen so we need to fix it. -""" - -import xml.etree.ElementTree as ET -import html -import sys -import subprocess - - -def fix_gir(name: str, gir: str, out: str): - namespaces = { - "": "http://www.gtk.org/introspection/core/1.0", - "c": "http://www.gtk.org/introspection/c/1.0", - "glib": "http://www.gtk.org/introspection/glib/1.0", - } - for prefix, uri in namespaces.items(): - ET.register_namespace(prefix, uri) - - tree = ET.parse(gir) - root = tree.getroot() - - for doc in root.findall(".//doc", namespaces): - if doc.text: - doc.text = ( - html.unescape(doc.text).replace("<para>", "").replace("</para>", "") - ) - - if (inc := root.find("c:include", namespaces)) is not None: - inc.set("name", f"{name}.h") - else: - print("no c:include tag found", file=sys.stderr) - exit(1) - - tree.write(out, encoding="utf-8", xml_declaration=True) - - -def valadoc(name: str, gir: str, args: list[str]): - cmd = ["valadoc", "-o", "docs", "--package-name", name, "--gir", gir, *args] - try: - subprocess.run(cmd, check=True, text=True, capture_output=True) - except subprocess.CalledProcessError as e: - print(e.stderr, file=sys.stderr) - exit(1) - - -if __name__ == "__main__": - name = sys.argv[1] - in_out = sys.argv[2].split(":") - args = sys.argv[3:] - - gir = in_out[0] - out = in_out[1] if len(in_out) > 1 else gir - - valadoc(name, gir, args) - fix_gir(name, gir, out) +../../gir.py
\ No newline at end of file @@ -9,6 +9,7 @@ import html import sys import subprocess import re +import os # valac fails on gi-docgen compliant markdown @@ -47,7 +48,7 @@ def fix_gir(name: str, gir: str, out: str): def valadoc(name: str, gir: str, args: list[str]): - cmd = ["valadoc", "-o", "docs", "--package-name", name, "--gir", gir, *args] + cmd = [os.getenv("VALADOC", "valadoc"), "-o", "docs", "--package-name", name, "--gir", gir, *args] try: subprocess.run(cmd, check=True, text=True, capture_output=True) except subprocess.CalledProcessError as e: diff --git a/lib/hyprland/monitor.vala b/lib/hyprland/monitor.vala index d7b8028..6c46142 100644 --- a/lib/hyprland/monitor.vala +++ b/lib/hyprland/monitor.vala @@ -1,5 +1,4 @@ -namespace AstalHyprland { -public class Monitor : Object { +public class AstalHyprland.Monitor : Object { public signal void removed (); public int id { get; private set; } @@ -20,6 +19,7 @@ public class Monitor : Object { public int reserved_left { get; private set; } public int reserved_right { get; private set; } public double scale { get; private set; } + public Transform transform { get; private set; } public bool focused { get; private set; } public bool dpms_status { get; private set; } public bool vrr { get; private set; } @@ -43,6 +43,7 @@ public class Monitor : Object { x = (int)obj.get_int_member("x"); y = (int)obj.get_int_member("y"); scale = obj.get_double_member("scale"); + transform = (Transform)obj.get_int_member("transform"); focused = obj.get_boolean_member("focused"); dpms_status = obj.get_boolean_member("dpmsStatus"); vrr = obj.get_boolean_member("vrr"); @@ -67,5 +68,22 @@ public class Monitor : Object { public void focus() { Hyprland.get_default().dispatch("focusmonitor", id.to_string()); } -} + + public enum Transform { + NORMAL = 0, + /** rotate by 90° counter clockwise */ + ROTATE_90_DEG = 1, + /** rotate by 180° */ + ROTATE_180_DEG = 2, + /** rotate by 270° counter clockwise */ + ROTATE_270_DEG = 3, + /** mirror both axis */ + FLIPPED = 4, + /** flip and rotate by 90° */ + FLIPPED_ROTATE_90_DEG = 5, + /** flip and rotate by 180° */ + FLIPPED_ROTATE_180_DEG = 6, + /** flip and rotate by 270° */ + FLIPPED_ROTATE_270_DEG = 7, + } } diff --git a/lib/network/network.vala b/lib/network/network.vala index fb7efa0..96e19c8 100644 --- a/lib/network/network.vala +++ b/lib/network/network.vala @@ -149,19 +149,19 @@ public enum AstalNetwork.Connectivity { // alias for NM.DeviceState public enum AstalNetwork.DeviceState { - UNKNOWN, - UNMANAGED, - UNAVAILABLE, - DISCONNECTED, - PREPARE, - CONFIG, - NEED_AUTH, - IP_CONFIG, - IP_CHECK, - SECONDARIES, - ACTIVATED, - DEACTIVATING, - FAILED; + UNKNOWN = 0, + UNMANAGED = 10, + UNAVAILABLE = 20, + DISCONNECTED = 30, + PREPARE = 40, + CONFIG = 50, + NEED_AUTH = 60, + IP_CONFIG = 70, + IP_CHECK = 80, + SECONDARIES = 90, + ACTIVATED = 100, + DEACTIVATING = 110, + FAILED = 120; public string to_string() { switch (this) { diff --git a/lib/powerprofiles/cli.vala b/lib/powerprofiles/cli.vala index 7be01d2..1e5cc70 100644 --- a/lib/powerprofiles/cli.vala +++ b/lib/powerprofiles/cli.vala @@ -56,16 +56,16 @@ int main(string[] argv) { if (daemonize) { var loop = new MainLoop(); - stdout.printf("%s\n", profiles.to_json_string()); + stdout.printf("%s\n", to_json_string(profiles)); stdout.flush(); profiles.notify.connect(() => { - stdout.printf("%s\n", profiles.to_json_string()); + stdout.printf("%s\n", to_json_string(profiles)); stdout.flush(); }); profiles.profile_released.connect(() => { - stdout.printf("%s\n", profiles.to_json_string()); + stdout.printf("%s\n", to_json_string(profiles)); stdout.flush(); }); @@ -73,8 +73,49 @@ int main(string[] argv) { } if (set == null && !daemonize) { - stdout.printf("%s\n", profiles.to_json_string()); + stdout.printf("%s\n", to_json_string(profiles)); } return 0; } + +string to_json_string(AstalPowerProfiles.PowerProfiles profiles) { + var acts = new Json.Builder().begin_array(); + foreach (var action in profiles.actions) { + acts.add_string_value(action); + } + + var active_holds = new Json.Builder().begin_array(); + foreach (var action in profiles.active_profile_holds) { + active_holds.add_value(new Json.Builder() + .begin_object() + .set_member_name("application_id").add_string_value(action.application_id) + .set_member_name("profile").add_string_value(action.profile) + .set_member_name("reason").add_string_value(action.reason) + .end_object() + .get_root()); + } + + var profs = new Json.Builder().begin_array(); + foreach (var prof in profiles.profiles) { + profs.add_value(new Json.Builder() + .begin_object() + .set_member_name("profie").add_string_value(prof.profile) + .set_member_name("driver").add_string_value(prof.driver) + .set_member_name("cpu_driver").add_string_value(prof.cpu_driver) + .set_member_name("platform_driver").add_string_value(prof.platform_driver) + .end_object() + .get_root()); + } + + return Json.to_string(new Json.Builder() + .begin_object() + .set_member_name("active_profile").add_string_value(profiles.active_profile) + .set_member_name("icon_name").add_string_value(profiles.icon_name) + .set_member_name("performance_degraded").add_string_value(profiles.performance_degraded) + .set_member_name("actions").add_value(acts.end_array().get_root()) + .set_member_name("active_profile_holds").add_value(active_holds.end_array().get_root()) + .set_member_name("profiles").add_value(profs.end_array().get_root()) + .end_object() + .get_root(), false); +} diff --git a/lib/powerprofiles/gir.py b/lib/powerprofiles/gir.py new file mode 120000 index 0000000..b5b4f1d --- /dev/null +++ b/lib/powerprofiles/gir.py @@ -0,0 +1 @@ +../gir.py
\ No newline at end of file diff --git a/lib/powerprofiles/meson.build b/lib/powerprofiles/meson.build index d0fe78f..cd8cc2b 100644 --- a/lib/powerprofiles/meson.build +++ b/lib/powerprofiles/meson.build @@ -39,32 +39,38 @@ deps = [ dependency('json-glib-1.0'), ] -sources = [ - config, +sources = [config] + files( 'power-profiles.vala', -] +) if get_option('lib') lib = library( meson.project_name(), sources, dependencies: deps, + vala_args: ['--vapi-comments'], vala_header: meson.project_name() + '.h', vala_vapi: meson.project_name() + '-' + api_version + '.vapi', - vala_gir: gir, version: meson.project_version(), install: true, - install_dir: [true, true, true, true], + install_dir: [true, true, true], ) - import('pkgconfig').generate( - lib, - name: meson.project_name(), - filebase: meson.project_name() + '-' + api_version, - version: meson.project_version(), - subdirs: meson.project_name(), - requires: deps, - install_dir: get_option('libdir') / 'pkgconfig', + pkgs = [] + foreach dep : deps + pkgs += ['--pkg=' + dep.name()] + endforeach + + gir_tgt = custom_target( + gir, + command: [find_program('python3'), files('gir.py'), meson.project_name(), gir] + + pkgs + + sources, + input: sources, + depends: lib, + output: gir, + install: true, + install_dir: get_option('datadir') / 'gir-1.0', ) custom_target( @@ -77,10 +83,20 @@ if get_option('lib') ], input: lib, output: typelib, - depends: lib, + depends: [lib, gir_tgt], install: true, install_dir: get_option('libdir') / 'girepository-1.0', ) + + import('pkgconfig').generate( + lib, + name: meson.project_name(), + filebase: meson.project_name() + '-' + api_version, + version: meson.project_version(), + subdirs: meson.project_name(), + requires: deps, + install_dir: get_option('libdir') / 'pkgconfig', + ) endif if get_option('cli') diff --git a/lib/powerprofiles/power-profiles.vala b/lib/powerprofiles/power-profiles.vala index ab98505..a104d2e 100644 --- a/lib/powerprofiles/power-profiles.vala +++ b/lib/powerprofiles/power-profiles.vala @@ -16,11 +16,17 @@ private interface IPowerProfiles : DBusProxy { } public PowerProfiles get_default() { + /** Gets the default singleton PowerProfiles instance. */ return PowerProfiles.get_default(); } +/** + * Client for [[https://freedesktop-team.pages.debian.net/power-profiles-daemon/gdbus-org.freedesktop.UPower.PowerProfiles.html|PowerProfiles]]. + */ public class PowerProfiles : Object { private static PowerProfiles instance; + + /** Gets the default singleton PowerProfiles instance. */ public static PowerProfiles get_default() { if (instance == null) instance = new PowerProfiles(); @@ -52,19 +58,34 @@ public class PowerProfiles : Object { } } + /** + * The type of the currently active profile. + * It might change automatically if a profile is held, + * using the [[email protected]_profile] method. + */ public string active_profile { owned get { return proxy.active_profile; } set { proxy.active_profile = value; } } + /** + * Return a named icon based [[email protected]:active_profile]. + */ public string icon_name { owned get { return @"power-profile-$active_profile-symbolic"; } } + /** + * List of the "actions" implemented in the running daemon. + * This can used to figure out whether particular functionality is available in the daemon. + */ public string[] actions { owned get { return proxy.actions.copy(); } } + /** + * List of dictionaries representing the current profile holds. + */ public Hold[] active_profile_holds { owned get { Hold[] holds = new Hold[proxy.active_profile_holds.length]; @@ -80,14 +101,21 @@ public class PowerProfiles : Object { } } + /** + * This will be set if the performance power profile is running in degraded mode, + * with the value being used to identify the reason for that degradation. + * Possible values are: + * - "lap-detected" (the computer is sitting on the user's lap) + * - "high-operating-temperature" (the computer is close to overheating) + * - "" (the empty string, if not performance is not degraded) + */ public string performance_degraded { owned get { return proxy.performance_degraded; } } - public string performance_inhibited { - owned get { return proxy.performance_degraded; } - } - + /** + * List of each profile. + */ public Profile[] profiles { owned get { Profile[] profs = new Profile[proxy.profiles.length]; @@ -104,12 +132,31 @@ public class PowerProfiles : Object { } } + /** + * The version of the power-profiles-daemon software. + */ public string version { owned get { return proxy.version; } } + /** + * Emitted when the profile is released because + * [[email protected]:active_profile] was manually changed. + * This will only be emitted to the process that originally called + * [[email protected]_profile]. + */ public signal void profile_released (uint cookie); + /** + * This forces the passed profile (either 'power-saver' or 'performance') + * to be activated until either the caller quits, + * [[email protected]_profile] is called, + * or the [[email protected]:active_profile] is changed by the user. + * When conflicting profiles are requested to be held, + * the 'power-saver' profile will be activated in preference to the 'performance' profile. + * Those holds will be automatically cancelled if the user manually switches to another profile, + * and the [[email protected]::profile_released] signal will be emitted. + */ public int hold_profile(string profile, string reason, string application_id) { try { return (int)proxy.hold_profile(profile, reason, application_id); @@ -119,6 +166,9 @@ public class PowerProfiles : Object { } } + /** + * This removes the hold that was set on a profile. + */ public void release_profile(uint cookie) { try { proxy.release_profile(cookie); @@ -126,54 +176,21 @@ public class PowerProfiles : Object { critical(error.message); } } - - public string to_json_string() { - var acts = new Json.Builder().begin_array(); - foreach (var action in actions) { - acts.add_string_value(action); - } - - var active_holds = new Json.Builder().begin_array(); - foreach (var action in active_profile_holds) { - active_holds.add_value(new Json.Builder() - .begin_object() - .set_member_name("application_id").add_string_value(action.application_id) - .set_member_name("profile").add_string_value(action.profile) - .set_member_name("reason").add_string_value(action.reason) - .end_object() - .get_root()); - } - - var profs = new Json.Builder().begin_array(); - foreach (var prof in profiles) { - profs.add_value(new Json.Builder() - .begin_object() - .set_member_name("profie").add_string_value(prof.profile) - .set_member_name("driver").add_string_value(prof.driver) - .set_member_name("cpu_driver").add_string_value(prof.cpu_driver) - .set_member_name("platform_driver").add_string_value(prof.platform_driver) - .end_object() - .get_root()); - } - - return Json.to_string(new Json.Builder() - .begin_object() - .set_member_name("active_profile").add_string_value(active_profile) - .set_member_name("icon_name").add_string_value(icon_name) - .set_member_name("performance_degraded").add_string_value(performance_degraded) - .set_member_name("performance_inhibited").add_string_value(performance_inhibited) - .set_member_name("actions").add_value(acts.end_array().get_root()) - .set_member_name("active_profile_holds").add_value(active_holds.end_array().get_root()) - .set_member_name("profiles").add_value(profs.end_array().get_root()) - .end_object() - .get_root(), false); - } } public struct Profile { + /** + * Will be one of: + * - "power-saver" (battery saving profile) + * - "balanced" (the default profile) + * - "performance" (a profile that does not care about noise or battery consumption) + */ public string profile; public string cpu_driver; public string platform_driver; + /** + * Identifies the power-profiles-daemon backend code used to implement the profile. + */ public string driver; } diff --git a/lib/tray/meson.build b/lib/tray/meson.build index cb7ab30..139cfb1 100644 --- a/lib/tray/meson.build +++ b/lib/tray/meson.build @@ -54,7 +54,7 @@ if get_option('lib') vala_args: ['--vapi-comments'], version: meson.project_version(), install: true, - install_dir: [true, true, true], + install_dir: [true, true, true] ) pkgs = [] |