diff --git a/data/gala.gschema.xml b/data/gala.gschema.xml index ea079697a..a726ae8bb 100644 --- a/data/gala.gschema.xml +++ b/data/gala.gschema.xml @@ -204,6 +204,16 @@ The shortcut to enable picture-in-picture window The shortcut to show the selection area to choose a window. + + + Monitor brightness up + Increase monitor brightness on supported panels + + + + Monitor brightness down + Decrease monitor brightness on supported panels + diff --git a/src/DBus.vala b/src/DBus.vala index 5541df51c..612754b22 100644 --- a/src/DBus.vala +++ b/src/DBus.vala @@ -22,6 +22,9 @@ public class Gala.DBus { (connection, name) => { try { connection.register_object ("/io/elementary/gala", WindowDragProvider.get_instance ()); +#if HAS_MUTTER50 + connection.register_object ("/io/elementary/gala/BrightnessManager", new BrightnessManager (wm.get_display ())); +#endif } catch (Error e) { warning (e.message); } diff --git a/src/Misc/BrightnessManager.vala b/src/Misc/BrightnessManager.vala new file mode 100644 index 000000000..e7d98903f --- /dev/null +++ b/src/Misc/BrightnessManager.vala @@ -0,0 +1,122 @@ +/* + * Copyright 2026 elementary, Inc. (https://elementary.io) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Authored by: Denis Garaev + */ + +#if HAS_MUTTER50 +public struct Gala.Monitor { + unowned Meta.Monitor meta_mointor; + unowned Meta.Backlight backlight; + ulong connection_id; +} + +[DBus (name = "io.elementary.gala.BrightnessManager")] +public class Gala.BrightnessManager : GLib.Object { + public signal void monitors_changed (); + public signal void monitor_brightness_changed (uint index, uint value); + + [DBus (visible = false)] + public unowned Meta.Display display { private get; construct; } + + private unowned Meta.MonitorManager monitor_manager; + private GLib.List monitors; + + public BrightnessManager (Meta.Display display) { + Object ( + display: display + ); + } + + construct { + monitor_manager = display.get_context ().get_backend ().get_monitor_manager (); + monitor_manager.monitors_changed.connect (monitors_changed_cb); + monitors = new GLib.List (); + monitors_changed_cb (); + + var keybinding_settings = new GLib.Settings ("io.elementary.desktop.wm.keybindings"); + display.add_keybinding ("brightness-brighter", keybinding_settings, Meta.KeyBindingFlags.NONE, () => { + try { + set_monitor_brightness (0, get_monitor_brightness (0) + 5); + } catch {} + }); + display.add_keybinding ("brightness-dimmer", keybinding_settings, Meta.KeyBindingFlags.NONE, () => { + try { + int delta = get_monitor_brightness (0) - 5; + if (delta < 0) + delta = 0; + + set_monitor_brightness (0, delta); + } catch {} + }); + } + + public void set_monitor_brightness (uint index, uint value) throws GLib.Error { + if (index < monitors.length ()) { + var backlight = monitors.nth_data (index).backlight; + int min, max; + backlight.get_brightness_info (out min, out max); + backlight.set_brightness ((int) (value * (max - min) / 100) + min); + } + } + + public int get_monitor_brightness (uint index) throws GLib.Error { + if (index < monitors.length ()) { + var backlight = monitors.nth_data (index).backlight; + int min, max; + int value; + backlight.get_brightness_info (out min, out max); + value = backlight.get_brightness (); + return (((value - min) * 100) / (max - min)).clamp (0, 100); + } else + return -1; + } + + public string get_monitor_data (uint index) throws GLib.Error { + if (index < monitors.length ()) + return monitors.nth_data (index).meta_mointor.get_display_name (); + else + return ""; + } + + public uint get_monitor_count () throws GLib.Error { + return monitors.length (); + } + + private void monitors_changed_cb () { + foreach (var data in monitors) { + data.backlight.disconnect (data.connection_id); + monitors.remove (data); + } + + var meta_monitors = monitor_manager.get_monitors ().copy (); + foreach (var meta_monitor in meta_monitors) { + var backlight = meta_monitor.get_backlight (); + var connection_id = backlight.notify["brightness"].connect (monitor_brightness_changed_cb); + if (meta_monitor.is_primary ()) + monitors.insert ({ meta_monitor, backlight, connection_id }, 0); + else + monitors.append ({ meta_monitor, backlight, connection_id }); + } + + monitors_changed (); + } + + private void monitor_brightness_changed_cb (GLib.Object sender, GLib.ParamSpec prop) { + var backlight = (Meta.Backlight) sender; + var list = monitors.search (backlight, (monitor, backlight) => { + if (monitor.backlight == backlight) + return 0; + else + return -1; + }).copy (); + + if (list == null || list.is_empty ()) + return; + + var index = monitors.index (list.data); + monitor_brightness_changed (index, get_monitor_brightness (index)); + } +} +#endif diff --git a/src/meson.build b/src/meson.build index 6b941f249..cfc0fd2d9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -25,6 +25,7 @@ gala_bin_sources = files( 'HotCorners/HotCorner.vala', 'HotCorners/HotCornerManager.vala', 'Misc/BlurManager.vala', + 'Misc/BrightnessManager.vala', 'Misc/DaemonManager.vala', 'Misc/DBusAccelerator.vala', 'Misc/DesktopIntegration.vala', diff --git a/vapi/Meta-18.metadata b/vapi/Meta-18.metadata index 05cf306ee..d85250716 100644 --- a/vapi/Meta-18.metadata +++ b/vapi/Meta-18.metadata @@ -12,6 +12,7 @@ BackgroundContent cheader_filename="meta/meta-background-content.h" BackgroundGroup cheader_filename="meta/meta-background-group.h" BackgroundImage cheader_filename="meta/meta-background-image.h" BackgroundImageCache cheader_filename="meta/meta-background-image.h" +Backlight cheader_filename="meta/meta-backlight.h" Barrier cheader_filename="meta/barrier.h" BarrierDirection cheader_filename="meta/barrier.h" BarrierEvent cheader_filename="meta/barrier.h" @@ -56,6 +57,7 @@ KeyHandlerFunc.window nullable LaunchContext cheader_filename="meta/meta-launch-context.h" Laters cheader_filename="meta/types.h" LaterType cheader_filename="meta/util.h" +LogicalMonitor cheader_filename="meta/meta-logical-monitor.h" MaximizeFlags cheader_filename="meta/window.h" MultiTexture cheader_filename="meta/meta-multi-texture.h" MultiTextureAlphaMode.n_meta_multi_texture_alpha_modes name="N_MODES" @@ -67,6 +69,7 @@ MultiTextureCoefficients cheader_filename="meta/meta-multi-texture-format.h" cpr MultiTextureFormat.n_meta_multi_texture_formats name="N_FORMATS" MultiTextureFormat.meta_multi_texture_format_* name="meta_multi_texture_format_(.+)" MultiTextureFormat cheader_filename="meta/meta-multi-texture-format.h" cprefix="META_MULTI_TEXTURE_FORMAT_" +Monitor cheader_filename="meta/meta-monitor.h" MonitorManager cheader_filename="meta/meta-monitor-manager.h" MonitorSwitchConfigType cheader_filename="meta/meta-monitor-manager.h" MotionDirection cheader_filename="meta/common.h" diff --git a/vapi/libmutter.vapi b/vapi/libmutter.vapi index 9b6a81576..ff133b5fa 100644 --- a/vapi/libmutter.vapi +++ b/vapi/libmutter.vapi @@ -276,7 +276,7 @@ namespace Meta { public void purge (GLib.File file); } #if HAS_MUTTER49 - [CCode (cheader_filename = "meta/main.h", type_id = "meta_backlight_get_type ()")] + [CCode (cheader_filename = "meta/meta-backlight.h", type_id = "meta_backlight_get_type ()")] public abstract class Backlight : GLib.Object { [CCode (has_construct_function = false)] protected Backlight (); @@ -647,14 +647,14 @@ namespace Meta { public Meta.Workspace workspace { owned get; set; } } #if HAS_MUTTER49 - [CCode (cheader_filename = "meta/main.h", type_id = "meta_logical_monitor_get_type ()")] + [CCode (cheader_filename = "meta/meta-logical-monitor.h", type_id = "meta_logical_monitor_get_type ()")] public class LogicalMonitor : GLib.Object { [CCode (has_construct_function = false)] protected LogicalMonitor (); public unowned GLib.List get_monitors (); public int get_number (); } - [CCode (cheader_filename = "meta/main.h", type_id = "meta_monitor_get_type ()")] + [CCode (cheader_filename = "meta/meta-monitor.h", type_id = "meta_monitor_get_type ()")] public class Monitor : GLib.Object { [CCode (has_construct_function = false)] protected Monitor ();