mirror of
https://codeberg.org/dwl/dwl.git
synced 2026-11-03 20:02:23 +00:00
keep outputs off when they reconnect
Some monitors disconnect when they are turned off and reconnect shortly after, and createmon() enabled them again. Remember the names of the outputs turned off through output_power_management or output_management and don't enable them in createmon(). Fixes https://codeberg.org/dwl/dwl/issues/719
This commit is contained in:
@@ -328,6 +328,7 @@ static void mapnotify(struct wl_listener *listener, void *data);
|
||||
static void maximizenotify(struct wl_listener *listener, void *data);
|
||||
static void monocle(Monitor *m);
|
||||
static void motionabsolute(struct wl_listener *listener, void *data);
|
||||
static char **monoff(struct wlr_output *wlr_output);
|
||||
static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx,
|
||||
double sy, double sx_unaccel, double sy_unaccel);
|
||||
static void motionrelative(struct wl_listener *listener, void *data);
|
||||
@@ -353,6 +354,7 @@ static void setfullscreen(Client *c, int fullscreen);
|
||||
static void setlayout(const Arg *arg);
|
||||
static void setmfact(const Arg *arg);
|
||||
static void setmon(Client *c, Monitor *m, uint32_t newtags);
|
||||
static void setmonoff(struct wlr_output *wlr_output, int off);
|
||||
static void setpsel(struct wl_listener *listener, void *data);
|
||||
static void setsel(struct wl_listener *listener, void *data);
|
||||
static void setup(void);
|
||||
@@ -450,6 +452,7 @@ static struct wl_event_source *transaction_idle;
|
||||
static struct wl_event_source *transaction_timer;
|
||||
static int transaction_waiting;
|
||||
static struct wl_array ghosts; /* struct wlr_scene_node *, unmapped clients */
|
||||
static struct wl_array offmons; /* char *, names of outputs turned off by clients */
|
||||
|
||||
/* global event handlers */
|
||||
static struct wl_listener cursor_axis = {.notify = axisnotify};
|
||||
@@ -824,6 +827,8 @@ checkidleinhibitor(struct wlr_surface *exclude)
|
||||
void
|
||||
cleanup(void)
|
||||
{
|
||||
char **name;
|
||||
|
||||
cleanuplisteners();
|
||||
#ifdef XWAYLAND
|
||||
wlr_xwayland_destroy(xwayland);
|
||||
@@ -849,6 +854,9 @@ cleanup(void)
|
||||
wl_event_source_remove(transaction_idle);
|
||||
wl_event_source_remove(transaction_timer);
|
||||
wl_array_release(&ghosts);
|
||||
wl_array_for_each(name, &offmons)
|
||||
free(*name);
|
||||
wl_array_release(&offmons);
|
||||
|
||||
wl_display_destroy(dpy);
|
||||
/* Destroy after the wayland display (when the monitors are already destroyed)
|
||||
@@ -1229,14 +1237,17 @@ createmon(struct wl_listener *listener, void *data)
|
||||
* monitor supports only a specific set of modes. We just pick the
|
||||
* monitor's preferred mode; a more sophisticated compositor would let
|
||||
* the user configure it. */
|
||||
wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output));
|
||||
|
||||
/* Set up event listeners */
|
||||
LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
|
||||
LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon);
|
||||
LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate);
|
||||
|
||||
wlr_output_state_set_enabled(&state, 1);
|
||||
/* Some monitors disconnect when they are turned off and reconnect shortly
|
||||
* after, so keep outputs that were turned off disabled. */
|
||||
if (!monoff(wlr_output)) {
|
||||
wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output));
|
||||
wlr_output_state_set_enabled(&state, 1);
|
||||
}
|
||||
wlr_output_commit_state(wlr_output, &state);
|
||||
wlr_output_state_finish(&state);
|
||||
|
||||
@@ -2068,6 +2079,17 @@ motionabsolute(struct wl_listener *listener, void *data)
|
||||
motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
|
||||
}
|
||||
|
||||
char **
|
||||
monoff(struct wlr_output *wlr_output)
|
||||
{
|
||||
char **name;
|
||||
wl_array_for_each(name, &offmons) {
|
||||
if (!strcmp(*name, wlr_output->name))
|
||||
return name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double dy,
|
||||
double dx_unaccel, double dy_unaccel)
|
||||
@@ -2254,6 +2276,7 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test)
|
||||
/* Ensure displays previously disabled by wlr-output-power-management-v1
|
||||
* are properly handled*/
|
||||
m->asleep = 0;
|
||||
setmonoff(wlr_output, !config_head->state.enabled);
|
||||
|
||||
/* Don't move monitors if position wouldn't change. This avoids
|
||||
* wlroots marking the output as manually configured.
|
||||
@@ -2372,6 +2395,10 @@ powermgrsetmode(struct wl_listener *listener, void *data)
|
||||
|
||||
m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the output */
|
||||
wlr_output_state_set_enabled(&state, event->mode);
|
||||
/* The output was reconnected while off and was never modeset */
|
||||
if (event->mode && !m->wlr_output->current_mode)
|
||||
wlr_output_state_set_mode(&state, wlr_output_preferred_mode(m->wlr_output));
|
||||
setmonoff(m->wlr_output, !event->mode);
|
||||
wlr_output_commit_state(m->wlr_output, &state);
|
||||
|
||||
m->asleep = !event->mode;
|
||||
@@ -2647,6 +2674,22 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
|
||||
focusclient(focustop(selmon), NULL, 1);
|
||||
}
|
||||
|
||||
void
|
||||
setmonoff(struct wlr_output *wlr_output, int off)
|
||||
{
|
||||
char **name = monoff(wlr_output), **last;
|
||||
|
||||
if (off && !name && (name = wl_array_add(&offmons, sizeof(*name)))) {
|
||||
if (!(*name = strdup(wlr_output->name)))
|
||||
offmons.size -= sizeof(*name);
|
||||
} else if (!off && name) {
|
||||
free(*name);
|
||||
last = (char **)((char *)offmons.data + offmons.size) - 1;
|
||||
*name = *last;
|
||||
offmons.size -= sizeof(*name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setpsel(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -2787,6 +2830,7 @@ setup(void)
|
||||
|
||||
transaction_timer = wl_event_loop_add_timer(event_loop, transactiontimeout, NULL);
|
||||
wl_array_init(&ghosts);
|
||||
wl_array_init(&offmons);
|
||||
|
||||
xdg_shell = wlr_xdg_shell_create(dpy, 6);
|
||||
wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel);
|
||||
|
||||
Reference in New Issue
Block a user