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

This commit is contained in:
Leonardo Hernández Hernández 2024-02-07 02:27:07 +00:00
commit 8e0b5baf8e
No known key found for this signature in database
GPG key ID: E538897EE11B9624
3 changed files with 62 additions and 21 deletions

View file

@ -86,7 +86,7 @@ Wayland without restarting the entire display server, so any changes will take
effect the next time dwl is executed. effect the next time dwl is executed.
As in the dwm community, we encourage users to share patches they have created. As in the dwm community, we encourage users to share patches they have created.
Check out the [patches page on our wiki]! Check out the dwl [patches repository] and [patches wiki]!
## Running dwl ## Running dwl
@ -169,7 +169,8 @@ inspiration, and to the various contributors to the project, including:
[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://codeberg.org/dwl/dwl/src/branch/wlroots-next [wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next
[patches page on our wiki]: https://codeberg.org/dwl/dwl/wiki/Patches [patches repository]: https://codeberg.org/dwl/dwl-patches
[patches wiki]: https://codeberg.org/dwl/dwl-patches/wiki
[s6]: https://skarnet.org/software/s6/ [s6]: https://skarnet.org/software/s6/
[anopa]: https://jjacky.com/anopa/ [anopa]: https://jjacky.com/anopa/
[runit]: http://smarden.org/runit/faq.html#userservices [runit]: http://smarden.org/runit/faq.html#userservices

View file

@ -172,14 +172,29 @@ client_get_parent(Client *c)
{ {
Client *p = NULL; Client *p = NULL;
#ifdef XWAYLAND #ifdef XWAYLAND
if (client_is_x11(c) && c->surface.xwayland->parent) if (client_is_x11(c)) {
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); if (c->surface.xwayland->parent)
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
return p;
}
#endif #endif
if (c->surface.xdg->toplevel->parent) if (c->surface.xdg->toplevel->parent)
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);
return p; return p;
} }
static inline int
client_has_children(Client *c)
{
#ifdef XWAYLAND
if (client_is_x11(c))
return !wl_list_empty(&c->surface.xwayland->children);
#endif
/* surface.xdg->link is never empty because it always contains at least the
* surface itself. */
return wl_list_length(&c->surface.xdg->link) > 1;
}
static inline const char * static inline const char *
client_get_title(Client *c) client_get_title(Client *c)
{ {

59
dwl.c
View file

@ -47,6 +47,7 @@
#include <wlr/types/wlr_subcompositor.h> #include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_viewporter.h> #include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h> #include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_activation_v1.h> #include <wlr/types/wlr_xdg_activation_v1.h>
#include <wlr/types/wlr_xdg_decoration_v1.h> #include <wlr/types/wlr_xdg_decoration_v1.h>
@ -330,6 +331,7 @@ static void updatetitle(struct wl_listener *listener, void *data);
static void urgent(struct wl_listener *listener, void *data); 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 void virtualpointer(struct wl_listener *listener, void *data);
static Monitor *xytomon(double x, double y); static Monitor *xytomon(double x, double y);
static void 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);
@ -364,6 +366,7 @@ static struct wlr_layer_shell_v1 *layer_shell;
static struct wlr_output_manager_v1 *output_mgr; static struct wlr_output_manager_v1 *output_mgr;
static struct wlr_gamma_control_manager_v1 *gamma_control_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_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; static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
static struct wlr_cursor *cursor; static struct wlr_cursor *cursor;
@ -412,8 +415,8 @@ void
applybounds(Client *c, struct wlr_box *bbox) applybounds(Client *c, struct wlr_box *bbox)
{ {
/* set minimum possible */ /* set minimum possible */
c->geom.width = MAX(1, c->geom.width); c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width);
c->geom.height = MAX(1, c->geom.height); c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height);
if (c->geom.x >= bbox->x + bbox->width) if (c->geom.x >= bbox->x + bbox->width)
c->geom.x = bbox->x + bbox->width - c->geom.width; c->geom.x = bbox->x + bbox->width - c->geom.width;
@ -453,7 +456,6 @@ applyrules(Client *c)
} }
} }
} }
wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]);
setmon(c, mon, newtags); setmon(c, mon, newtags);
} }
@ -906,7 +908,8 @@ createmon(struct wl_listener *listener, void *data)
m->m.y = r->y; m->m.y = r->y;
m->mfact = r->mfact; m->mfact = r->mfact;
m->nmaster = r->nmaster; m->nmaster = r->nmaster;
m->lt[0] = m->lt[1] = r->lt; m->lt[0] = r->lt;
m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]];
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
wlr_output_state_set_scale(&state, r->scale); wlr_output_state_set_scale(&state, r->scale);
wlr_output_state_set_transform(&state, r->rr); wlr_output_state_set_transform(&state, r->rr);
@ -1273,7 +1276,7 @@ focusstack(const Arg *arg)
{ {
/* Focus the next or previous client (in tiling order) on selmon */ /* Focus the next or previous client (in tiling order) on selmon */
Client *c, *sel = focustop(selmon); Client *c, *sel = focustop(selmon);
if (!sel || sel->isfullscreen) if (!sel || (sel->isfullscreen && !client_has_children(sel)))
return; return;
if (arg->i > 0) { if (arg->i > 0) {
wl_list_for_each(c, &sel->link, link) { wl_list_for_each(c, &sel->link, link) {
@ -1513,7 +1516,8 @@ void
mapnotify(struct wl_listener *listener, void *data) mapnotify(struct wl_listener *listener, void *data)
{ {
/* Called when the surface is mapped, or ready to display on-screen. */ /* Called when the surface is mapped, or ready to display on-screen. */
Client *p, *w, *c = wl_container_of(listener, c, map); Client *p = NULL;
Client *w, *c = wl_container_of(listener, c, map);
Monitor *m; Monitor *m;
int i; int i;
@ -1559,10 +1563,8 @@ mapnotify(struct wl_listener *listener, void *data)
* we always consider floating, clients that have parent and thus * we always consider floating, clients that have parent and thus
* we set the same tags and monitor than its parent, if not * we set the same tags and monitor than its parent, if not
* try to apply rules for them */ * try to apply rules for them */
/* TODO: https://github.com/djpohly/dwl/pull/334#issuecomment-1330166324 */ if ((p = client_get_parent(c))) {
if (c->type == XDGShell && (p = client_get_parent(c))) {
c->isfloating = 1; c->isfloating = 1;
wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]);
setmon(c, p->mon, p->tags); setmon(c, p->mon, p->tags);
} else { } else {
applyrules(c); applyrules(c);
@ -1572,7 +1574,7 @@ mapnotify(struct wl_listener *listener, void *data)
unset_fullscreen: unset_fullscreen:
m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y);
wl_list_for_each(w, &clients, link) { wl_list_for_each(w, &clients, link) {
if (w != c && w->isfullscreen && m == w->mon && (w->tags & c->tags)) if (w != c && w != p && w->isfullscreen && m == w->mon && (w->tags & c->tags))
setfullscreen(w, 0); setfullscreen(w, 0);
} }
} }
@ -1781,6 +1783,9 @@ apply_or_test:
else else
wlr_output_configuration_v1_send_failed(config); wlr_output_configuration_v1_send_failed(config);
wlr_output_configuration_v1_destroy(config); wlr_output_configuration_v1_destroy(config);
/* TODO: use a wrapper function? */
updatemons(NULL, NULL);
} }
void void
@ -1840,8 +1845,8 @@ printstatus(void)
appid = client_get_appid(c); appid = client_get_appid(c);
printf("%s title %s\n", m->wlr_output->name, title ? title : broken); printf("%s title %s\n", m->wlr_output->name, title ? title : broken);
printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken); printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken);
printf("%s fullscreen %u\n", m->wlr_output->name, c->isfullscreen); printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen);
printf("%s floating %u\n", m->wlr_output->name, c->isfloating); printf("%s floating %d\n", m->wlr_output->name, c->isfloating);
sel = c->tags; sel = c->tags;
} else { } else {
printf("%s title \n", m->wlr_output->name); printf("%s title \n", m->wlr_output->name);
@ -1852,8 +1857,8 @@ printstatus(void)
} }
printf("%s selmon %u\n", m->wlr_output->name, m == selmon); printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, printf("%s tags %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32"\n",
m->tagset[m->seltags], sel, urg); m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg);
printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol); printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
} }
fflush(stdout); fflush(stdout);
@ -2061,11 +2066,13 @@ setcursorshape(struct wl_listener *listener, void *data)
void void
setfloating(Client *c, int floating) setfloating(Client *c, int floating)
{ {
Client *p = client_get_parent(c);
c->isfloating = floating; c->isfloating = floating;
if (!c->mon) if (!c->mon)
return; return;
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
? LyrFS : c->isfloating ? LyrFloat : LyrTile]); (p && p->isfullscreen) ? LyrFS
: c->isfloating ? LyrFloat : LyrTile]);
arrange(c->mon); arrange(c->mon);
printstatus(); printstatus();
} }
@ -2353,6 +2360,9 @@ setup(void)
LISTEN_STATIC(&backend->events.new_input, inputdevice); LISTEN_STATIC(&backend->events.new_input, inputdevice);
virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy);
LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard); LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard);
virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy);
LISTEN_STATIC(&virtual_pointer_mgr->events.new_virtual_pointer, virtualpointer);
seat = wlr_seat_create(dpy, "seat0"); seat = wlr_seat_create(dpy, "seat0");
LISTEN_STATIC(&seat->events.request_set_cursor, setcursor); LISTEN_STATIC(&seat->events.request_set_cursor, setcursor);
LISTEN_STATIC(&seat->events.request_set_selection, setsel); LISTEN_STATIC(&seat->events.request_set_selection, setsel);
@ -2750,6 +2760,17 @@ virtualkeyboard(struct wl_listener *listener, void *data)
wlr_keyboard_group_add_keyboard(vkb_group.wlr_group, &keyboard->keyboard); wlr_keyboard_group_add_keyboard(vkb_group.wlr_group, &keyboard->keyboard);
} }
void
virtualpointer(struct wl_listener *listener, void *data)
{
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
struct wlr_pointer pointer = event->new_pointer->pointer;
wlr_cursor_attach_input_device(cursor, &pointer.base);
if (event->suggested_output)
wlr_cursor_map_input_to_output(cursor, &pointer.base, event->suggested_output);
}
Monitor * Monitor *
xytomon(double x, double y) xytomon(double x, double y)
{ {
@ -2846,8 +2867,12 @@ configurex11(struct wl_listener *listener, void *data)
{ {
Client *c = wl_container_of(listener, c, configure); Client *c = wl_container_of(listener, c, configure);
struct wlr_xwayland_surface_configure_event *event = data; struct wlr_xwayland_surface_configure_event *event = data;
if (!c->mon) /* 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; return;
}
if (c->isfloating || client_is_unmanaged(c)) if (c->isfloating || client_is_unmanaged(c))
resize(c, (struct wlr_box){.x = event->x, .y = event->y, resize(c, (struct wlr_box){.x = event->x, .y = event->y,
.width = event->width, .height = event->height}, 0); .width = event->width, .height = event->height}, 0);