From 0406ce239710348339285fb96f695ddb757b05fe Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 20 Mar 2025 16:04:37 +0800 Subject: [PATCH] feat: powermanager protocol support --- maomao.c | 38 +++++- protocols/meson.build | 1 + ...lr-output-power-management-unstable-v1.xml | 128 ++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 protocols/wlr-output-power-management-unstable-v1.xml diff --git a/maomao.c b/maomao.c index 7a5ba248..5adcfac3 100644 --- a/maomao.c +++ b/maomao.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -348,6 +349,8 @@ struct Monitor { Client *sel, *prevsel; int isoverview; int is_in_hotarea; + int gamma_lut_changed; + int asleep; }; typedef struct { @@ -504,6 +507,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); static void printstatus(void); static void quitsignal(int signo); +static void powermgrsetmode(struct wl_listener *listener, void *data); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); static void requeststartdrag(struct wl_listener *listener, void *data); @@ -633,6 +637,7 @@ static struct wlr_layer_shell_v1 *layer_shell; static struct wlr_output_manager_v1 *output_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; +static struct wlr_output_power_manager_v1 *power_mgr; static struct wlr_cursor *cursor; static struct wlr_xcursor_manager *cursor_mgr; @@ -696,6 +701,7 @@ static struct wl_listener new_xdg_decoration = {.notify = createdecoration}; static struct wl_listener new_layer_surface = {.notify = createlayersurface}; static struct wl_listener output_mgr_apply = {.notify = outputmgrapply}; static struct wl_listener output_mgr_test = {.notify = outputmgrtest}; +static struct wl_listener output_power_mgr_set_mode = {.notify = powermgrsetmode}; static struct wl_listener request_activate = {.notify = urgent}; static struct wl_listener request_cursor = {.notify = setcursor}; static struct wl_listener request_set_psel = {.notify = setpsel}; @@ -2110,6 +2116,7 @@ void cleanuplisteners(void) { wl_list_remove(&new_layer_surface.link); wl_list_remove(&output_mgr_apply.link); wl_list_remove(&output_mgr_test.link); + wl_list_remove(&output_power_mgr_set_mode.link); wl_list_remove(&request_activate.link); wl_list_remove(&request_cursor.link); wl_list_remove(&request_set_psel.link); @@ -4067,6 +4074,10 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) { Monitor *m = wlr_output->data; struct wlr_output_state state; + /* Ensure displays previously disabled by wlr-output-power-management-v1 + * are properly handled*/ + m->asleep = 0; + wlr_output_state_init(&state); wlr_output_state_set_enabled(&state, config_head->state.enabled); if (!config_head->state.enabled) @@ -4154,6 +4165,24 @@ printstatus(void) { } } +void +powermgrsetmode(struct wl_listener *listener, void *data) +{ + struct wlr_output_power_v1_set_mode_event *event = data; + struct wlr_output_state state = {0}; + Monitor *m = event->output->data; + + if (!m) + return; + + m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */ + wlr_output_state_set_enabled(&state, event->mode); + wlr_output_commit_state(m->wlr_output, &state); + + m->asleep = !event->mode; + updatemons(NULL, NULL); +} + void // 0.5 custom quit(const Arg *arg) { wl_display_terminate(dpy); @@ -5122,6 +5151,9 @@ void setup(void) { wlr_scene_set_gamma_control_manager_v1(scene, wlr_gamma_control_manager_v1_create(dpy)); + power_mgr = wlr_output_power_manager_v1_create(dpy); + wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); + /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ output_layout = wlr_output_layout_create(dpy); @@ -6181,7 +6213,7 @@ updatemons(struct wl_listener *listener, void *data) { /* First remove from the layout the disabled monitors */ wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled) + if (m->wlr_output->enabled || m->asleep) continue; config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); @@ -6234,6 +6266,10 @@ updatemons(struct wl_listener *listener, void *data) { if ((c = focustop(m)) && c->isfullscreen) resize(c, m->m, 0); + /* Try to re-set the gamma LUT when updating monitors, + * it's only really needed when enabling a disabled output, but meh. */ + m->gamma_lut_changed = 1; + config_head->state.x = m->m.x; config_head->state.y = m->m.y; if (!selmon) { diff --git a/protocols/meson.build b/protocols/meson.build index bf5796f1..13b2f30a 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -18,6 +18,7 @@ wayland_xmls = [ 'wlr-foreign-toplevel-management-unstable-v1.xml', 'dwl-ipc-unstable-v2.xml', 'wlr-layer-shell-unstable-v1.xml', + 'wlr-output-power-management-unstable-v1.xml', ] wayland_sources = [ wayland_scanner_code.process(wayland_xmls), diff --git a/protocols/wlr-output-power-management-unstable-v1.xml b/protocols/wlr-output-power-management-unstable-v1.xml new file mode 100644 index 00000000..a9778399 --- /dev/null +++ b/protocols/wlr-output-power-management-unstable-v1.xml @@ -0,0 +1,128 @@ + + + + Copyright © 2019 Purism SPC + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol allows clients to control power management modes + of outputs that are currently part of the compositor space. The + intent is to allow special clients like desktop shells to power + down outputs when the system is idle. + + To modify outputs not currently part of the compositor space see + wlr-output-management. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + This interface is a manager that allows creating per-output power + management mode controls. + + + + + Create a output power management mode control that can be used to + adjust the power management mode for a given output. + + + + + + + + All objects created by the manager will still remain valid, until their + appropriate destroy request has been called. + + + + + + + This object offers requests to set the power management mode of + an output. + + + + + + + + + + + + + + Set an output's power save mode to the given mode. The mode change + is effective immediately. If the output does not support the given + mode a failed event is sent. + + + + + + + Report the power management mode change of an output. + + The mode event is sent after an output changed its power + management mode. The reason can be a client using set_mode or the + compositor deciding to change an output's mode. + This event is also sent immediately when the object is created + so the client is informed about the current power management mode. + + + + + + + This event indicates that the output power management mode control + is no longer valid. This can happen for a number of reasons, + including: + - The output doesn't support power management + - Another client already has exclusive power management mode control + for this output + - The output disappeared + + Upon receiving this event, the client should destroy this object. + + + + + + Destroys the output power management mode control object. + + + +