Merge remote-tracking branch 'upstream/main' into wlroots-next
This commit is contained in:
commit
8e0b5baf8e
|
@ -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
|
||||||
|
|
17
client.h
17
client.h
|
@ -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)) {
|
||||||
|
if (c->surface.xwayland->parent)
|
||||||
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
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
59
dwl.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue