Merge remote-tracking branch 'upstream/main' into wlroots-next

This commit is contained in:
Leonardo Hernández Hernández 2023-09-24 11:44:29 -06:00
commit 1333f8cc6e
No known key found for this signature in database
GPG Key ID: E538897EE11B9624
7 changed files with 75 additions and 64 deletions

View File

@ -55,8 +55,11 @@ install: dwl
mkdir -p $(DESTDIR)$(MANDIR)/man1 mkdir -p $(DESTDIR)$(MANDIR)/man1
cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1 cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1
chmod 644 $(DESTDIR)$(MANDIR)/man1/dwl.1 chmod 644 $(DESTDIR)$(MANDIR)/man1/dwl.1
mkdir -p $(DESTDIR)$(DATADIR)/wayland-sessions
cp -f dwl.desktop $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop
chmod 644 $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop
uninstall: uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1 rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1 $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop
.SUFFIXES: .c .o .SUFFIXES: .c .o
.c.o: .c.o:

View File

@ -1,6 +1,7 @@
# dwl - dwm for Wayland # 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 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, 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 [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/ [Wayland]: https://wayland.freedesktop.org/
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
[wlroots-next branch]: https://github.com/djpohly/dwl/tree/wlroots-next [wlroots-next branch]: https://github.com/djpohly/dwl/tree/wlroots-next

View File

@ -8,7 +8,8 @@ static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
/* tagging - tagcount must be no greater than 31 */ /* 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[] = { static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */ /* app_id title tags mask isfloating monitor */

View File

@ -6,6 +6,7 @@ PKG_CONFIG = pkg-config
# paths # paths
PREFIX = /usr/local PREFIX = /usr/local
MANDIR = $(PREFIX)/share/man MANDIR = $(PREFIX)/share/man
DATADIR = $(PREFIX)/share
XWAYLAND = XWAYLAND =
XLIBS = XLIBS =

2
dwl.1
View File

@ -101,7 +101,7 @@ These environment variables are used by
A directory where temporary user files, such as the Wayland socket, A directory where temporary user files, such as the Wayland socket,
are stored. are stored.
.It Ev XDG_CONFIG_DIR .It Ev XDG_CONFIG_DIR
A directory containung configuration of various programs and A directory containing configuration of various programs and
libraries, including libxkbcommon. libraries, including libxkbcommon.
.It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET .It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET
Tell how to connect to an underlying X11 or Wayland server. Tell how to connect to an underlying X11 or Wayland server.

118
dwl.c
View File

@ -323,7 +323,7 @@ static void urgent(struct wl_listener *listener, void *data);
static void view(const Arg *arg); static void view(const Arg *arg);
static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualkeyboard(struct wl_listener *listener, void *data);
static Monitor *xytomon(double x, double y); 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); Client **pc, LayerSurface **pl, double *nx, double *ny);
static void zoom(const Arg *arg); static void zoom(const Arg *arg);
@ -750,12 +750,6 @@ void
commitnotify(struct wl_listener *listener, void *data) commitnotify(struct wl_listener *listener, void *data)
{ {
Client *c = wl_container_of(listener, c, commit); 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 */ /* mark a pending resize as completed */
if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
@ -1120,15 +1114,16 @@ destroylocksurface(struct wl_listener *listener, void *data)
m->lock_surface = NULL; m->lock_surface = NULL;
wl_list_remove(&m->destroy_lock_surface.link); wl_list_remove(&m->destroy_lock_surface.link);
if (lock_surface->surface == seat->keyboard_state.focused_surface) { if (lock_surface->surface != seat->keyboard_state.focused_surface)
if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) { return;
surface = wl_container_of(cur_lock->surfaces.next, surface, link);
client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat)); if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) {
} else if (!locked) { surface = wl_container_of(cur_lock->surfaces.next, surface, link);
focusclient(focustop(selmon), 1); client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
} else { } else if (!locked) {
wlr_seat_keyboard_clear_focus(seat); focusclient(focustop(selmon), 1);
} } else {
wlr_seat_keyboard_clear_focus(seat);
} }
} }
@ -1438,12 +1433,13 @@ keypress(struct wl_listener *listener, void *data)
wl_event_source_timer_update(kb->key_repeat_source, 0); wl_event_source_timer_update(kb->key_repeat_source, 0);
} }
if (!handled) { if (handled)
/* Pass unhandled keycodes along to the client. */ return;
wlr_seat_set_keyboard(seat, kb->wlr_keyboard);
wlr_seat_keyboard_notify_key(seat, event->time_msec, /* Pass unhandled keycodes along to the client. */
event->keycode, event->state); wlr_seat_set_keyboard(seat, kb->wlr_keyboard);
} wlr_seat_keyboard_notify_key(seat, event->time_msec,
event->keycode, event->state);
} }
void void
@ -1469,13 +1465,14 @@ keyrepeat(void *data)
{ {
Keyboard *kb = data; Keyboard *kb = data;
int i; int i;
if (kb->nsyms && kb->wlr_keyboard->repeat_info.rate > 0) { if (!kb->nsyms || kb->wlr_keyboard->repeat_info.rate <= 0)
wl_event_source_timer_update(kb->key_repeat_source, return 0;
1000 / kb->wlr_keyboard->repeat_info.rate);
for (i = 0; i < kb->nsyms; i++) wl_event_source_timer_update(kb->key_repeat_source,
keybinding(kb->mods, kb->keysyms[i]); 1000 / kb->wlr_keyboard->repeat_info.rate);
}
for (i = 0; i < kb->nsyms; i++)
keybinding(kb->mods, kb->keysyms[i]);
return 0; return 0;
} }
@ -1516,7 +1513,6 @@ void
maplayersurfacenotify(struct wl_listener *listener, void *data) maplayersurfacenotify(struct wl_listener *listener, void *data)
{ {
LayerSurface *l = wl_container_of(listener, l, map); LayerSurface *l = wl_container_of(listener, l, map);
wlr_surface_send_enter(l->layer_surface->surface, l->mon->wlr_output);
motionnotify(0); motionnotify(0);
} }
@ -2030,6 +2026,8 @@ void
setfloating(Client *c, int floating) setfloating(Client *c, int floating)
{ {
c->isfloating = floating; c->isfloating = floating;
if (!c->mon)
return;
wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]);
arrange(c->mon); arrange(c->mon);
printstatus(); printstatus();
@ -2118,17 +2116,15 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
c->mon = m; c->mon = m;
c->prev = c->geom; c->prev = c->geom;
/* TODO leave/enter is not optimal but works */ /* Scene graph sends surface leave/enter events on move and resize */
if (oldmon) { if (oldmon)
wlr_surface_send_leave(client_surface(c), oldmon->wlr_output);
arrange(oldmon); arrange(oldmon);
}
if (m) { if (m) {
/* Make sure window actually overlaps with the monitor */ /* Make sure window actually overlaps with the monitor */
resize(c, c->geom, 0); 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 */ c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
setfloating(c, c->isfloating);
} }
focusclient(focustop(selmon), 1); focusclient(focustop(selmon), 1);
} }
@ -2378,11 +2374,12 @@ void
tag(const Arg *arg) tag(const Arg *arg)
{ {
Client *sel = focustop(selmon); Client *sel = focustop(selmon);
if (sel && arg->ui & TAGMASK) { if (!sel || (arg->ui & TAGMASK) == 0)
sel->tags = arg->ui & TAGMASK; return;
focusclient(focustop(selmon), 1);
arrange(selmon); sel->tags = arg->ui & TAGMASK;
} focusclient(focustop(selmon), 1);
arrange(selmon);
printstatus(); printstatus();
} }
@ -2452,11 +2449,12 @@ toggletag(const Arg *arg)
if (!sel) if (!sel)
return; return;
newtags = sel->tags ^ (arg->ui & TAGMASK); newtags = sel->tags ^ (arg->ui & TAGMASK);
if (newtags) { if (!newtags)
sel->tags = newtags; return;
focusclient(focustop(selmon), 1);
arrange(selmon); sel->tags = newtags;
} focusclient(focustop(selmon), 1);
arrange(selmon);
printstatus(); printstatus();
} }
@ -2465,11 +2463,12 @@ toggleview(const Arg *arg)
{ {
uint32_t newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0; uint32_t newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0;
if (newtagset) { if (!newtagset)
selmon->tagset[selmon->seltags] = newtagset; return;
focusclient(focustop(selmon), 1);
arrange(selmon); selmon->tagset[selmon->seltags] = newtagset;
} focusclient(focustop(selmon), 1);
arrange(selmon);
printstatus(); printstatus();
} }
@ -2625,10 +2624,11 @@ urgent(struct wl_listener *listener, void *data)
struct wlr_xdg_activation_v1_request_activate_event *event = data; struct wlr_xdg_activation_v1_request_activate_event *event = data;
Client *c = NULL; Client *c = NULL;
toplevel_from_wlr_surface(event->surface, &c, NULL); toplevel_from_wlr_surface(event->surface, &c, NULL);
if (c && c != focustop(selmon)) { if (!c || c == focustop(selmon))
c->isurgent = 1; return;
printstatus();
} c->isurgent = 1;
printstatus();
} }
void void
@ -2658,7 +2658,7 @@ xytomon(double x, double y)
return o ? o->data : NULL; return o ? o->data : NULL;
} }
struct wlr_scene_node * void
xytonode(double x, double y, struct wlr_surface **psurface, xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny) Client **pc, LayerSurface **pl, double *nx, double *ny)
{ {
@ -2687,7 +2687,6 @@ xytonode(double x, double y, struct wlr_surface **psurface,
if (psurface) *psurface = surface; if (psurface) *psurface = surface;
if (pc) *pc = c; if (pc) *pc = c;
if (pl) *pl = l; if (pl) *pl = l;
return node;
} }
void void
@ -2806,10 +2805,11 @@ void
sethints(struct wl_listener *listener, void *data) sethints(struct wl_listener *listener, void *data)
{ {
Client *c = wl_container_of(listener, c, set_hints); Client *c = wl_container_of(listener, c, set_hints);
if (c != focustop(selmon)) { if (c == focustop(selmon))
c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); return;
printstatus();
} c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
printstatus();
} }
void void

5
dwl.desktop Normal file
View File

@ -0,0 +1,5 @@
[Desktop Entry]
Name=dwl
Comment=dwm for Wayland
Exec=dwl
Type=Application