aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@firemail.cc>2023-09-22 18:01:10 +0530
committersinanmohd <sinan@firemail.cc>2023-09-22 18:01:10 +0530
commit662c3b5c3c55dea5eeeb6ebad81d09b645cece4d (patch)
treed95dfb6600039fea53c5a55f2ce7e7fa874f8d4c
parent57c70b14a494dfaa05181cdafed8ea8bb979520d (diff)
parent755fcae2afbed51f38c167bdc56a5437cda8137a (diff)
repo: merge remote-tracking branch 'upstream/main'
-rw-r--r--README.md5
-rw-r--r--config.def.h3
-rw-r--r--dwl.12
-rw-r--r--dwl.c159
4 files changed, 83 insertions, 86 deletions
diff --git a/README.md b/README.md
index 05f149c..1ac5b4b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# dwl - dwm for Wayland
-Join us on our [Discord server] or at [#dwl] on irc.libera.chat.
+Join us on our IRC channel: [#dwl on Libera Chat]
+Or on our [Discord server].
dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is
intended to fill the same space in the Wayland world that dwm does in X11,
@@ -143,7 +144,7 @@ inspiration, and to the various contributors to the project, including:
[Discord server]: https://discord.gg/jJxZnrGPWN
-[#dwl]: https://web.libera.chat/?channels=#dwl
+[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl
[Wayland]: https://wayland.freedesktop.org/
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
[wlroots-next branch]: https://github.com/djpohly/dwl/tree/wlroots-next
diff --git a/config.def.h b/config.def.h
index d4b4fe0..f505aa7 100644
--- a/config.def.h
+++ b/config.def.h
@@ -10,7 +10,8 @@ static const float focuscolor[] = {0.0, 0.33, 0.47, 1.0};
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
/* tagging - tagcount must be no greater than 31 */
-static const int tagcount = 9;
+#define TAGCOUNT (9)
+static const int tagcount = TAGCOUNT;
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
diff --git a/dwl.1 b/dwl.1
index cae1036..6f164e6 100644
--- a/dwl.1
+++ b/dwl.1
@@ -101,7 +101,7 @@ These environment variables are used by
A directory where temporary user files, such as the Wayland socket,
are stored.
.It Ev XDG_CONFIG_DIR
-A directory containung configuration of various programs and
+A directory containing configuration of various programs and
libraries, including libxkbcommon.
.It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET
Tell how to connect to an underlying X11 or Wayland server.
diff --git a/dwl.c b/dwl.c
index 05b5f29..d03f2b7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -260,7 +260,7 @@ static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
-static int handlesig(int signo, void *data);
+static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
static int keybinding(uint32_t mods, xkb_keysym_t sym);
@@ -315,7 +315,7 @@ static void urgent(struct wl_listener *listener, void *data);
static void view(const Arg *arg);
static void virtualkeyboard(struct wl_listener *listener, void *data);
static Monitor *xytomon(double x, double y);
-static struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface **psurface,
+static void xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny);
static void zoom(const Arg *arg);
@@ -326,11 +326,10 @@ static pid_t child_pid = -1;
static int locked;
static void *exclusive_focus;
static struct wl_display *dpy;
-static struct wl_event_loop *eventloop;
-static struct wl_event_source *sighandler[4];
static struct wlr_backend *backend;
static struct wlr_scene *scene;
static struct wlr_scene_tree *layers[NUM_LAYERS];
+static struct wlr_scene_tree *drag_icon;
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay };
static struct wlr_renderer *drw;
@@ -653,7 +652,6 @@ checkidleinhibitor(struct wlr_surface *exclude)
void
cleanup(void)
{
- int i;
#ifdef XWAYLAND
wlr_xwayland_destroy(xwayland);
#endif
@@ -663,14 +661,13 @@ cleanup(void)
waitpid(child_pid, NULL, 0);
}
wlr_backend_destroy(backend);
+ wlr_scene_node_destroy(&scene->tree.node);
wlr_renderer_destroy(drw);
wlr_allocator_destroy(alloc);
wlr_xcursor_manager_destroy(cursor_mgr);
wlr_cursor_destroy(cursor);
wlr_output_layout_destroy(output_layout);
wlr_seat_destroy(seat);
- for (i = 0; i < LENGTH(sighandler); i++)
- wl_event_source_remove(sighandler[i]);
wl_display_destroy(dpy);
}
@@ -771,12 +768,6 @@ void
commitnotify(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, commit);
- struct wlr_box box = {0};
- client_get_geometry(c, &box);
-
- if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw
- || box.height != c->geom.height - 2 * c->bw))
- c->isfloating ? resize(c, c->geom, 1) : arrange(c->mon);
/* mark a pending resize as completed */
if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
@@ -824,7 +815,8 @@ createkeyboard(struct wlr_keyboard *keyboard)
wlr_seat_set_keyboard(seat, keyboard);
- kb->key_repeat_source = wl_event_loop_add_timer(eventloop, keyrepeat, kb);
+ kb->key_repeat_source = wl_event_loop_add_timer(
+ wl_display_get_event_loop(dpy), keyrepeat, kb);
/* And add the keyboard to our list of keyboards */
wl_list_insert(&keyboards, &kb->link);
@@ -1141,15 +1133,16 @@ destroylocksurface(struct wl_listener *listener, void *data)
m->lock_surface = NULL;
wl_list_remove(&m->destroy_lock_surface.link);
- if (lock_surface->surface == seat->keyboard_state.focused_surface) {
- if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) {
- surface = wl_container_of(cur_lock->surfaces.next, surface, link);
- client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
- } else if (!locked) {
- focusclient(focustop(selmon), 1);
- } else {
- wlr_seat_keyboard_clear_focus(seat);
- }
+ if (lock_surface->surface != seat->keyboard_state.focused_surface)
+ return;
+
+ if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) {
+ surface = wl_container_of(cur_lock->surfaces.next, surface, link);
+ client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
+ } else if (!locked) {
+ focusclient(focustop(selmon), 1);
+ } else {
+ wlr_seat_keyboard_clear_focus(seat);
}
}
@@ -1337,8 +1330,8 @@ fullscreennotify(struct wl_listener *listener, void *data)
setfullscreen(c, client_wants_fullscreen(c));
}
-int
-handlesig(int signo, void *data)
+void
+handlesig(int signo)
{
if (signo == SIGCHLD) {
#ifdef XWAYLAND
@@ -1356,7 +1349,6 @@ handlesig(int signo, void *data)
} else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL);
}
- return 0;
}
void
@@ -1456,12 +1448,13 @@ keypress(struct wl_listener *listener, void *data)
wl_event_source_timer_update(kb->key_repeat_source, 0);
}
- if (!handled) {
- /* Pass unhandled keycodes along to the client. */
- wlr_seat_set_keyboard(seat, kb->wlr_keyboard);
- wlr_seat_keyboard_notify_key(seat, event->time_msec,
- event->keycode, event->state);
- }
+ if (handled)
+ return;
+
+ /* Pass unhandled keycodes along to the client. */
+ wlr_seat_set_keyboard(seat, kb->wlr_keyboard);
+ wlr_seat_keyboard_notify_key(seat, event->time_msec,
+ event->keycode, event->state);
}
void
@@ -1487,13 +1480,14 @@ keyrepeat(void *data)
{
Keyboard *kb = data;
int i;
- if (kb->nsyms && kb->wlr_keyboard->repeat_info.rate > 0) {
- wl_event_source_timer_update(kb->key_repeat_source,
- 1000 / kb->wlr_keyboard->repeat_info.rate);
+ if (!kb->nsyms || kb->wlr_keyboard->repeat_info.rate <= 0)
+ return 0;
- for (i = 0; i < kb->nsyms; i++)
- keybinding(kb->mods, kb->keysyms[i]);
- }
+ wl_event_source_timer_update(kb->key_repeat_source,
+ 1000 / kb->wlr_keyboard->repeat_info.rate);
+
+ for (i = 0; i < kb->nsyms; i++)
+ keybinding(kb->mods, kb->keysyms[i]);
return 0;
}
@@ -1535,7 +1529,6 @@ void
maplayersurfacenotify(struct wl_listener *listener, void *data)
{
LayerSurface *l = wl_container_of(listener, l, map);
- wlr_surface_send_enter(l->layer_surface->surface, l->mon->wlr_output);
motionnotify(0);
}
@@ -1668,7 +1661,6 @@ motionnotify(uint32_t time)
LayerSurface *l = NULL;
int type;
struct wlr_surface *surface = NULL;
- struct wlr_drag_icon *icon;
/* time is 0 in internal calls meant to restore pointer focus. */
if (time) {
@@ -1679,10 +1671,9 @@ motionnotify(uint32_t time)
selmon = xytomon(cursor->x, cursor->y);
}
- /* Update drag icon's position if any */
- if (seat->drag && (icon = seat->drag->icon))
- wlr_scene_node_set_position(icon->data, cursor->x + icon->surface->sx,
- cursor->y + icon->surface->sy);
+ /* Update drag icon's position */
+ wlr_scene_node_set_position(&drag_icon->node, cursor->x, cursor->y);
+
/* If we are currently grabbing the mouse, handle and return */
if (cursor_mode == CurMove) {
/* Move the grabbed client to the new position. */
@@ -2041,6 +2032,8 @@ void
setfloating(Client *c, int floating)
{
c->isfloating = floating;
+ if (!c->mon)
+ return;
wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]);
arrange(c->mon);
printstatus();
@@ -2108,17 +2101,15 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
c->mon = m;
c->prev = c->geom;
- /* TODO leave/enter is not optimal but works */
- if (oldmon) {
- wlr_surface_send_leave(client_surface(c), oldmon->wlr_output);
+ /* Scene graph sends surface leave/enter events on move and resize */
+ if (oldmon)
arrange(oldmon);
- }
if (m) {
/* Make sure window actually overlaps with the monitor */
resize(c, c->geom, 0);
- wlr_surface_send_enter(client_surface(c), m->wlr_output);
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
+ setfloating(c, c->isfloating);
}
focusclient(focustop(selmon), 1);
}
@@ -2149,13 +2140,15 @@ void
setup(void)
{
int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
+ struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
+ sigemptyset(&sa.sa_mask);
+
+ for (i = 0; i < LENGTH(sig); i++)
+ sigaction(sig[i], &sa, NULL);
/* The Wayland display is managed by libwayland. It handles accepting
* clients from the Unix socket, manging Wayland globals, and so on. */
dpy = wl_display_create();
- eventloop = wl_display_get_event_loop(dpy);
- for (i = 0; i < LENGTH(sighandler); i++)
- sighandler[i] = wl_event_loop_add_signal(eventloop, sig[i], handlesig, NULL);
/* The backend is a wlroots feature which abstracts the underlying input and
* output hardware. The autocreate option will choose the most suitable
@@ -2172,6 +2165,8 @@ setup(void)
scene = wlr_scene_create();
for (i = 0; i < NUM_LAYERS; i++)
layers[i] = wlr_scene_tree_create(&scene->tree);
+ drag_icon = wlr_scene_tree_create(&scene->tree);
+ wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node);
/* Create a renderer with the default implementation */
if (!(drw = wlr_renderer_autocreate(backend)))
@@ -2338,14 +2333,10 @@ void
startdrag(struct wl_listener *listener, void *data)
{
struct wlr_drag *drag = data;
- struct wlr_scene_tree *icon;
-
if (!drag->icon)
return;
- drag->icon->data = icon = wlr_scene_subsurface_tree_create(&scene->tree, drag->icon->surface);
- wlr_scene_node_place_below(&icon->node, &layers[LyrBlock]->node);
- motionnotify(0);
+ drag->icon->data = &wlr_scene_subsurface_tree_create(drag_icon, drag->icon->surface)->node;
wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy);
}
@@ -2353,11 +2344,12 @@ void
tag(const Arg *arg)
{
Client *sel = focustop(selmon);
- if (sel && arg->ui & TAGMASK) {
- sel->tags = arg->ui & TAGMASK;
- focusclient(focustop(selmon), 1);
- arrange(selmon);
- }
+ if (!sel || (arg->ui & TAGMASK) == 0)
+ return;
+
+ sel->tags = arg->ui & TAGMASK;
+ focusclient(focustop(selmon), 1);
+ arrange(selmon);
printstatus();
}
@@ -2432,11 +2424,12 @@ toggletag(const Arg *arg)
if (!sel)
return;
newtags = sel->tags ^ (arg->ui & TAGMASK);
- if (newtags) {
- sel->tags = newtags;
- focusclient(focustop(selmon), 1);
- arrange(selmon);
- }
+ if (!newtags)
+ return;
+
+ sel->tags = newtags;
+ focusclient(focustop(selmon), 1);
+ arrange(selmon);
printstatus();
}
@@ -2445,11 +2438,12 @@ toggleview(const Arg *arg)
{
uint32_t newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0;
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
- focusclient(focustop(selmon), 1);
- arrange(selmon);
- }
+ if (!newtagset)
+ return;
+
+ selmon->tagset[selmon->seltags] = newtagset;
+ focusclient(focustop(selmon), 1);
+ arrange(selmon);
printstatus();
}
@@ -2606,10 +2600,11 @@ urgent(struct wl_listener *listener, void *data)
struct wlr_xdg_activation_v1_request_activate_event *event = data;
Client *c = NULL;
toplevel_from_wlr_surface(event->surface, &c, NULL);
- if (c && c != focustop(selmon)) {
- c->isurgent = 1;
- printstatus();
- }
+ if (!c || c == focustop(selmon))
+ return;
+
+ c->isurgent = 1;
+ printstatus();
}
void
@@ -2639,7 +2634,7 @@ xytomon(double x, double y)
return o ? o->data : NULL;
}
-struct wlr_scene_node *
+void
xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny)
{
@@ -2668,7 +2663,6 @@ xytonode(double x, double y, struct wlr_surface **psurface,
if (psurface) *psurface = surface;
if (pc) *pc = c;
if (pl) *pl = l;
- return node;
}
void
@@ -2768,10 +2762,11 @@ void
sethints(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_hints);
- if (c != focustop(selmon)) {
- c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
- printstatus();
- }
+ if (c == focustop(selmon))
+ return;
+
+ c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
+ printstatus();
}
void