From 16d6775ac27a8eb2e4a14b6e569f0c50f25d3eb7 Mon Sep 17 00:00:00 2001 From: amolinae06 Date: Sun, 2 Feb 2025 13:09:20 -0600 Subject: [PATCH] dwl 7.0 --- .mailmap | 2 - CHANGELOG.md | 31 +++------- Makefile | 9 ++- README.md | 1 + client.h | 43 +++++++------ config.def.h | 16 ++--- config.h | 2 +- config.mk | 23 +------ dwl.c | 169 ++++++++++++++++++++++++++++++--------------------- util.c | 10 +-- 10 files changed, 148 insertions(+), 158 deletions(-) diff --git a/.mailmap b/.mailmap index 1778cb9..911248c 100644 --- a/.mailmap +++ b/.mailmap @@ -1,3 +1 @@ Lennart Jablonka -Leonardo Hernández Hernández -Leonardo Hernández Hernández diff --git a/CHANGELOG.md b/CHANGELOG.md index 07c9ee4..3a299c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,36 +1,13 @@ # Changelog -* [Unreleased](#unreleased) * [0.7](#0.7) * [0.6](#0.6) * [0.5](#0.5) -## Unreleased -### Added - -* Support for the linux-drm-syncobj-v1 protocol ([wlroots!4715][wlroots!4715], [#685][685]) -* Allow the use of non-system wlroots library ([#646][646]) - -[wlroots!4715]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4715 -[685]: https://codeberg.org/dwl/dwl/pulls/685 -[646]: https://codeberg.org/dwl/dwl/pulls/646 - - -### Changed -### Deprecated -### Removed -### Fixed - -* Crash when a client is created while all outputs are disabled. - -### Security -### Contributors - - ## 0.7 -This version is just 0.6 with wlroots 0.18 compatibility. +See also [0.6](#0.6) release notes. 0.7 builds against wlroots 0.18.x. ### Added @@ -41,9 +18,15 @@ This version is just 0.6 with wlroots 0.18 compatibility. [601]: https://codeberg.org/dwl/dwl/issues/601 +### Fixed + +* Crash when re-mapping unmapped clients. + + ### Contributors Guido Cella +Lennart Jablonka ## 0.6 diff --git a/Makefile b/Makefile index 279b1c0..9bc67db 100644 --- a/Makefile +++ b/Makefile @@ -6,15 +6,15 @@ include config.mk # flags for compiling DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \ -DVERSION=\"$(VERSION)\" $(XWAYLAND) -DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \ +DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ -Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \ -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \ -Wfloat-conversion # CFLAGS / LDFLAGS -PKGS = wayland-server xkbcommon libinput pixman-1 fcft $(XLIBS) -DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) -LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS) +PKGS = wlroots-0.18 wayland-server xkbcommon libinput pixman-1 fcft $(XLIBS) +DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) +LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) all: dwl dwl: dwl.o util.o @@ -61,7 +61,6 @@ dist: clean install: dwl mkdir -p $(DESTDIR)$(PREFIX)/bin - rm -f $(DESTDIR)$(PREFIX)/bin/dwl cp -f dwl $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/dwl mkdir -p $(DESTDIR)$(MANDIR)/man1 diff --git a/README.md b/README.md index 43c22b3..6c59a75 100644 --- a/README.md +++ b/README.md @@ -213,3 +213,4 @@ inspiration, and to the various contributors to the project, including: [wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [Discord server]: https://discord.gg/jJxZnrGPWN [Wayland]: https://wayland.freedesktop.org/ + diff --git a/client.h b/client.h index 389b4f0..42f225f 100644 --- a/client.h +++ b/client.h @@ -126,14 +126,15 @@ client_get_appid(Client *c) { #ifdef XWAYLAND if (client_is_x11(c)) - return c->surface.xwayland->class ? c->surface.xwayland->class : "broken"; + return c->surface.xwayland->class; #endif - return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id : "broken"; + return c->surface.xdg->toplevel->app_id; } static inline void client_get_clip(Client *c, struct wlr_box *clip) { + struct wlr_box xdg_geom = {0}; *clip = (struct wlr_box){ .x = 0, .y = 0, @@ -146,8 +147,9 @@ client_get_clip(Client *c, struct wlr_box *clip) return; #endif - clip->x = c->surface.xdg->geometry.x; - clip->y = c->surface.xdg->geometry.y; + wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom); + clip->x = xdg_geom.x; + clip->y = xdg_geom.y; } static inline void @@ -162,7 +164,7 @@ client_get_geometry(Client *c, struct wlr_box *geom) return; } #endif - *geom = c->surface.xdg->geometry; + wlr_xdg_surface_get_geometry(c->surface.xdg, geom); } static inline Client * @@ -198,9 +200,9 @@ client_get_title(Client *c) { #ifdef XWAYLAND if (client_is_x11(c)) - return c->surface.xwayland->title ? c->surface.xwayland->title : "broken"; + return c->surface.xwayland->title; #endif - return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title : "broken"; + return c->surface.xdg->toplevel->title; } static inline int @@ -299,6 +301,17 @@ client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb) wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); } +static inline void +client_restack_surface(Client *c) +{ +#ifdef XWAYLAND + if (client_is_x11(c)) + wlr_xwayland_surface_restack(c->surface.xwayland, NULL, + XCB_STACK_MODE_ABOVE); +#endif + return; +} + static inline void client_send_close(Client *c) { @@ -331,13 +344,6 @@ client_set_fullscreen(Client *c, int fullscreen) wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); } -static inline void -client_set_scale(struct wlr_surface *s, float scale) -{ - wlr_fractional_scale_v1_notify_scale(s, scale); - wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); -} - static inline uint32_t client_set_size(Client *c, uint32_t width, uint32_t height) { @@ -358,11 +364,8 @@ static inline void client_set_tiled(Client *c, uint32_t edges) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_set_maximized(c->surface.xwayland, - edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE); + if (client_is_x11(c)) return; - } #endif if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { @@ -388,8 +391,8 @@ client_wants_focus(Client *c) { #ifdef XWAYLAND return client_is_unmanaged(c) - && wlr_xwayland_surface_override_redirect_wants_focus(c->surface.xwayland) - && wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; + && wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) + && wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; #endif return 0; } diff --git a/config.def.h b/config.def.h index c0db1c8..67cb5d0 100644 --- a/config.def.h +++ b/config.def.h @@ -7,21 +7,15 @@ static const int sloppyfocus = 1; /* focus follows mouse */ static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */ static const unsigned int borderpx = 1; /* border pixel of windows */ -static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ -static const int monoclegaps = 0; /* 1 means outer gaps in monocle layout */ -static const unsigned int gappih = 10; /* horiz inner gap between windows */ -static const unsigned int gappiv = 10; /* vert inner gap between windows */ -static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ -static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ -static const char *cursor_theme = NULL; -static const char cursor_size[] = "24"; /* Make sure it's a valid integer, otherwise things will break */ -static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ +static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ static const char *fonts[] = {"monospace:size=10"}; static const float rootcolor[] = COLOR(0x000000ff); /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ +static const char *cursor_theme = NULL; +static const char cursor_size[] = "24"; /* Make sure it's a valid integer, otherwise things will break */ static uint32_t colors[][3] = { /* fg bg border */ [SchemeNorm] = { 0xbbbbbbff, 0x222222ff, 0x444444ff }, diff --git a/config.h b/config.h index 2ea2c50..011f9ed 100644 --- a/config.h +++ b/config.h @@ -97,7 +97,7 @@ static const struct xkb_rule_names xkb_rules[] = { static const InputRule inputrules[] = { /* name kbcreate ptrcreate */ /* ignore bad device - like a touchpad ;) */ - { "BAD DEVICE", NULL, NULL }, + { "Synaptics TM3276-022", NULL, NULL }, /* ungroup ydotool device - fixes a bug */ { "ydotoold virtual device", createungroupedkeyboard, createpointer }, /* put your touchpad name here to enable toggle touchpad */ diff --git a/config.mk b/config.mk index e2f1816..1e0b810 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ -_VERSION = 0.8-dev +_VERSION = 0.7 VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)` PKG_CONFIG = pkg-config @@ -8,29 +8,10 @@ PREFIX = /usr/local MANDIR = $(PREFIX)/share/man DATADIR = $(PREFIX)/share -WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` -WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` - -# Allow using an alternative wlroots installations -# This has to have all the includes required by wlroots, e.g: -# Assuming wlroots git repo is "${PWD}/wlroots" and you only ran "meson setup build && ninja -C build" -#WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \ -# -I$(PWD)/wlroots/include -# Set -rpath to avoid using the wrong library. -#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/build -L$(PWD)/wlroots/build -lwlroots-0.19 - -# Assuming you ran "meson setup --prefix ${PWD}/0.19 build && ninja -C build install" -#WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \ -# -I$(PWD)/wlroots/0.19/include/wlroots-0.19 -#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/0.19/lib64 -L$(PWD)/wlroots/0.19/lib64 -lwlroots-0.19 - XWAYLAND = XLIBS = # Uncomment to build XWayland support #XWAYLAND = -DXWAYLAND #XLIBS = xcb xcb-icccm -# dwl itself only uses C99 features, but wlroots' headers use anonymous unions (C11). -# To avoid warnings about them, we do not use -std=c99 and instead of using the -# gmake default 'CC=c99', we use cc. -CC = cc +CC = gcc diff --git a/dwl.c b/dwl.c index 922b921..f405548 100644 --- a/dwl.c +++ b/dwl.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -113,18 +112,16 @@ typedef struct { typedef struct Monitor Monitor; typedef struct { - /* Must keep this field first */ + /* Must keep these three elements in this order */ unsigned int type; /* XDGShell or X11* */ - int interact; + int interact; + struct wlr_box geom; /* layout-relative, includes border */ Monitor *mon; struct wlr_scene_tree *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_tree *scene_surface; struct wl_list link; struct wl_list flink; - struct wlr_box geom; /* layout-relative, includes border */ - struct wlr_box prev; /* layout-relative, includes border */ - struct wlr_box bounds; /* only width and height are used */ union { struct wlr_xdg_surface *xdg; struct wlr_xwayland_surface *xwayland; @@ -139,6 +136,8 @@ typedef struct { struct wl_listener fullscreen; struct wl_listener set_decoration_mode; struct wl_listener destroy_decoration; + struct wlr_box prev; /* layout-relative, includes border */ + struct wlr_box bounds; #ifdef XWAYLAND struct wl_listener activate; struct wl_listener associate; @@ -166,6 +165,7 @@ typedef struct { } Key; typedef struct { + struct wl_list link; struct wlr_keyboard_group *wlr_group; int nsyms; @@ -179,9 +179,9 @@ typedef struct { } KeyboardGroup; typedef struct { - /* Must keep this field first */ + /* Must keep these three elements in this order */ unsigned int type; /* LayerShell */ - + struct wlr_box geom; Monitor *mon; struct wlr_scene_tree *scene; struct wlr_scene_tree *popups; @@ -387,6 +387,7 @@ static void setcursorshape(struct wl_listener *listener, void *data); static void setfloating(Client *c, int floating); static void setfullscreen(Client *c, int fullscreen); static void setsticky(Client *c, int sticky); +static void setgamma(struct wl_listener *listener, void *data); static void setgaps(int oh, int ov, int ih, int iv); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); @@ -426,6 +427,7 @@ static void zoom(const Arg *arg); static void rotatetags(const Arg *arg); /* variables */ +static const char broken[] = "broken"; static pid_t child_pid = -1; static int locked; static void *exclusive_focus; @@ -451,6 +453,7 @@ static struct wlr_idle_notifier_v1 *idle_notifier; static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr; static struct wlr_layer_shell_v1 *layer_shell; static struct wlr_output_manager_v1 *output_mgr; +static struct wlr_gamma_control_manager_v1 *gamma_control_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; @@ -490,15 +493,15 @@ static const struct wlr_buffer_impl buffer_impl = { .end_data_ptr_access = bufdataend, }; -static int enablegaps = 1; /* enables gaps, used by togglegaps */ -static void (*resize)(Client *c, struct wlr_box geo, int interact) = resizeapply; - static const struct xkb_rule_names en_rules = {.layout = "us"}; static struct xkb_context *en_context; static struct xkb_keymap *en_keymap; static struct xkb_state *en_state, *en_state_shift; static xkb_mod_index_t en_shift; +static int enablegaps = 1; /* enables gaps, used by togglegaps */ +static void (*resize)(Client *c, struct wlr_box geo, int interact) = resizeapply; + static struct libinput_device *togglepointerdevice = NULL; #ifdef XWAYLAND @@ -552,8 +555,10 @@ applyrules(Client *c) Monitor *mon = selmon, *m; c->isfloating = client_is_float_type(c); - appid = client_get_appid(c); - title = client_get_title(c); + if (!(appid = client_get_appid(c))) + appid = broken; + if (!(title = client_get_title(c))) + title = broken; for (r = rules; r < END(rules); r++) { if ((!r->title || strstr(title, r->title)) @@ -662,6 +667,8 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, usable_area); wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, l->scene->node.y); + l->geom.x = l->scene->node.x; + l->geom.y = l->scene->node.y; } } @@ -890,17 +897,17 @@ buttonpress(struct wl_listener *listener, void *data) break; case WL_POINTER_BUTTON_STATE_RELEASED: /* If you released any buttons, we exit interactive move/resize mode. */ - /* TODO: should reset to the pointer focus's current setcursor */ + /* TODO should reset to the pointer focus's current setcursor */ if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); cursor_mode = CurNormal; /* Drop the window off on its new monitor */ selmon = xytomon(cursor->x, cursor->y); setmon(grabc, selmon, 0); - grabc = NULL; return; + } else { + cursor_mode = CurNormal; } - cursor_mode = CurNormal; break; } /* If the event wasn't handled by the compositor, notify the client with @@ -1046,7 +1053,8 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) struct wlr_layer_surface_v1_state old_state; if (l->layer_surface->initial_commit) { - client_set_scale(layer_surface->surface, l->mon->wlr_output->scale); + wlr_fractional_scale_v1_notify_scale(layer_surface->surface, l->mon->wlr_output->scale); + wlr_surface_set_preferred_buffer_scale(layer_surface->surface, (int32_t)ceilf(l->mon->wlr_output->scale)); /* Temporarily set the layer's current state to pending * so that we can easily arrange it */ @@ -1085,20 +1093,19 @@ commitnotify(struct wl_listener *listener, void *data) * a wrong monitor. */ applyrules(c); - if (c->mon) { - client_set_scale(client_surface(c), c->mon->wlr_output->scale); - } + wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); + wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ - wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, - WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); if (c->decoration) requestdecorationmode(&c->set_decoration_mode, c->decoration); - wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); return; } - resize(c, c->geom, (c->isfloating && !c->isfullscreen)); + if (client_surface(c)->mapped && c->mon) + resize(c, c->geom, (c->isfloating && !c->isfullscreen)); /* mark a pending resize as completed */ if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) @@ -1123,13 +1130,11 @@ commitpopup(struct wl_listener *listener, void *data) return; popup->base->surface->data = wlr_scene_xdg_surface_create( popup->parent->data, popup->base); - if ((l && !l->mon) || (c && !c->mon)) { - wlr_xdg_popup_destroy(popup); + if ((l && !l->mon) || (c && !c->mon)) return; - } box = type == LayerShell ? l->mon->m : c->mon->w; - box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x); - box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y); + box.x -= (type == LayerShell ? l->geom.x : c->geom.x); + box.y -= (type == LayerShell ? l->geom.y : c->geom.y); wlr_xdg_popup_unconstrain_from_box(popup, &box); wl_list_remove(&listener->link); } @@ -1395,10 +1400,10 @@ createpointer(struct wlr_pointer *pointer) libinput_device_config_middle_emulation_set_enabled(device, middle_button_emulation); if (libinput_device_config_scroll_get_methods(device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) - libinput_device_config_scroll_set_method(device, scroll_method); + libinput_device_config_scroll_set_method (device, scroll_method); if (libinput_device_config_click_get_methods(device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE) - libinput_device_config_click_set_method(device, click_method); + libinput_device_config_click_set_method (device, click_method); if (libinput_device_config_send_events_get_modes(device)) libinput_device_config_send_events_set_mode(device, send_events_mode); @@ -1505,6 +1510,7 @@ void destroydecoration(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, destroy_decoration); + c->decoration = NULL; wl_list_remove(&c->destroy_decoration.link); wl_list_remove(&c->set_decoration_mode.link); @@ -1605,7 +1611,6 @@ destroynotify(struct wl_listener *listener, void *data) wl_list_remove(&c->commit.link); wl_list_remove(&c->map.link); wl_list_remove(&c->unmap.link); - wl_list_remove(&c->maximize.link); } free(c); } @@ -1768,6 +1773,7 @@ focusclient(Client *c, int lift) wl_list_insert(&fstack, &c->flink); selmon = c->mon; c->isurgent = 0; + client_restack_surface(c); /* Don't change border color if there is an exclusive focus or we are * handling a drag operation */ @@ -2199,8 +2205,7 @@ mapnotify(struct wl_listener *listener, void *data) /* Create scene tree for this client and its border */ c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); - /* Enabled later by a call to arrange() */ - wlr_scene_node_set_enabled(&c->scene->node, client_is_unmanaged(c)); + wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); c->scene_surface = c->type == XDGShell ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); @@ -2213,7 +2218,6 @@ mapnotify(struct wl_listener *listener, void *data) /* Unmanaged clients always are floating */ wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); - client_set_size(c, c->geom.width, c->geom.height); if (client_wants_focus(c)) { focusclient(c, 1); exclusive_focus = c; @@ -2346,8 +2350,8 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d && toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) { c = w; surface = seat->pointer_state.focused_surface; - sx = cursor->x - (l ? l->scene->node.x : w->geom.x); - sy = cursor->y - (l ? l->scene->node.y : w->geom.y); + sx = cursor->x - (l ? l->geom.x : w->geom.x); + sy = cursor->y - (l ? l->geom.y : w->geom.y); } /* time is 0 in internal calls meant to restore pointer focus. */ @@ -2555,6 +2559,7 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, wlr_seat_pointer_notify_motion(seat, time, sx, sy); } + void powermgrsetmode(struct wl_listener *listener, void *data) { @@ -2570,7 +2575,6 @@ powermgrsetmode(struct wl_listener *listener, void *data) wlr_output_commit_state(m->wlr_output, &state); m->asleep = !event->mode; - updatemons(NULL, NULL); } void @@ -2587,6 +2591,7 @@ rendermon(struct wl_listener *listener, void *data) Monitor *m = wl_container_of(listener, m, frame); Client *c; struct wlr_output_state pending = {0}; + struct wlr_gamma_control_v1 *gamma_control; struct timespec now; /* Render if no XDG clients have an outstanding resize and are visible on @@ -2596,7 +2601,32 @@ rendermon(struct wl_listener *listener, void *data) goto skip; } - wlr_scene_output_commit(m->scene_output, NULL); + /* + * HACK: The "correct" way to set the gamma is to commit it together with + * the rest of the state in one go, but to do that we would need to rewrite + * wlr_scene_output_commit() in order to add the gamma to the pending + * state before committing, instead try to commit the gamma in one frame, + * and commit the rest of the state in the next one (or in the same frame if + * the gamma can not be committed). + */ + if (m->gamma_lut_changed) { + gamma_control + = wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, m->wlr_output); + m->gamma_lut_changed = 0; + + if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) + goto commit; + + if (!wlr_output_test_state(m->wlr_output, &pending)) { + wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); + goto commit; + } + wlr_output_commit_state(m->wlr_output, &pending); + wlr_output_schedule_frame(m->wlr_output); + } else { +commit: + wlr_scene_output_commit(m->scene_output, NULL); + } skip: /* Let clients know a frame has been rendered */ @@ -2795,6 +2825,17 @@ setfullscreen(Client *c, int fullscreen) drawbars(); } +void +setgamma(struct wl_listener *listener, void *data) +{ + struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; + Monitor *m = event->output->data; + if (!m) + return; + m->gamma_lut_changed = 1; + wlr_output_schedule_frame(m->wlr_output); +} + void setgaps(int oh, int ov, int ih, int iv) { @@ -2893,7 +2934,7 @@ setsel(struct wl_listener *listener, void *data) void setup(void) { - int drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; + int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; sigemptyset(&sa.sa_mask); @@ -2944,10 +2985,6 @@ setup(void) wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); } - if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline - && backend->features.timeline) - wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd); - /* Autocreates an allocator for us. * The allocator is the bridge between the renderer and the backend. It * handles the buffer creation, allowing wlroots to render onto the @@ -2971,14 +3008,15 @@ setup(void) wlr_viewporter_create(dpy); wlr_single_pixel_buffer_manager_v1_create(dpy); wlr_fractional_scale_manager_v1_create(dpy, 1); - wlr_presentation_create(dpy, backend, 2); + wlr_presentation_create(dpy, backend); wlr_alpha_modifier_v1_create(dpy); /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); LISTEN_STATIC(&activation->events.request_activate, urgent); - wlr_scene_set_gamma_control_manager_v1(scene, wlr_gamma_control_manager_v1_create(dpy)); + gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); + LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); power_mgr = wlr_output_power_manager_v1_create(dpy); LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); @@ -3278,16 +3316,6 @@ togglegaps(const Arg *arg) arrange(selmon); } -void -togglesticky(const Arg *arg) -{ - Client *c = focustop(selmon); - if(!c) - return; - - setsticky(c, !c->issticky); -} - void togglepointer(const Arg *arg) { @@ -3300,6 +3328,16 @@ togglepointer(const Arg *arg) ); } +void +togglesticky(const Arg *arg) +{ + Client *c = focustop(selmon); + if(!c) + return; + + setsticky(c, !c->issticky); +} + void toggletag(const Arg *arg) { @@ -3712,24 +3750,17 @@ configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); struct wlr_xwayland_surface_configure_event *event = data; - if (!client_surface(c) || !client_surface(c)->mapped) { + /* TODO: figure out if there is another way to do this */ + if (!c->mon) { wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, event->width, event->height); return; } - if (client_is_unmanaged(c)) { - wlr_scene_node_set_position(&c->scene->node, event->x, event->y); - wlr_xwayland_surface_configure(c->surface.xwayland, - event->x, event->y, event->width, event->height); - return; - } - if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) { - resize(c, (struct wlr_box){.x = event->x - c->bw, - .y = event->y - c->bw, .width = event->width + c->bw * 2, - .height = event->height + c->bw * 2}, 0); - } else { + if (c->isfloating || client_is_unmanaged(c)) + resize(c, (struct wlr_box){.x = event->x, .y = event->y, + .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); + else arrange(c->mon); - } } void diff --git a/util.c b/util.c index b925987..51130af 100644 --- a/util.c +++ b/util.c @@ -38,14 +38,14 @@ ecalloc(size_t nmemb, size_t size) int fd_set_nonblock(int fd) { int flags = fcntl(fd, F_GETFL); - if (flags < 0) { + if (flags < 0) { perror("fcntl(F_GETFL):"); - return -1; - } - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + return -1; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("fcntl(F_SETFL):"); return -1; - } + } return 0; }