feat: powermanager protocol support

This commit is contained in:
DreamMaoMao 2025-03-20 16:04:37 +08:00
parent dee9717fef
commit 0406ce2397
3 changed files with 166 additions and 1 deletions

View file

@ -46,6 +46,7 @@
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_output_power_management_v1.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h>
@ -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) {