mirror of
https://codeberg.org/dwl/dwl.git
synced 2025-10-27 10:14:14 +00:00
Merge pull request #1 from Stivvo/basic_damage_tracking
Keep track of subsurfaces
This commit is contained in:
commit
2af3b1d588
@ -11,7 +11,7 @@ dwl is a compact, hackable compositor for Wayland based on [wlroots](https://git
|
||||
|
||||
dwl is not meant to provide every feature under the sun. Instead, like dwm, it sticks to features which are necessary, simple, and straightforward to implement given the base on which it is built. Implemented default features are:
|
||||
|
||||
- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. The built-in status bar is an exception to avoid taking a dependency on FreeType or Pango and increasing the SLOC
|
||||
- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an exception to this goal, to avoid dependencies on font rendering and/or drawing libraries when an external bar could work well.
|
||||
- Configurable multi-monitor layout support, including position and rotation
|
||||
- Configurable HiDPI/multi-DPI support
|
||||
- Various Wayland protocols
|
||||
@ -21,7 +21,7 @@ dwl is not meant to provide every feature under the sun. Instead, like dwm, it s
|
||||
Features under consideration (possibly as patches) are:
|
||||
|
||||
- Protocols made trivial by wlroots
|
||||
- Communication from the compositor to status bars. A straightforward possibility would be to use stdout or a provided file descriptor.
|
||||
- Provide information to external status bars via stdout or another file descriptor
|
||||
- Implement the input-inhibitor protocol to support screen lockers
|
||||
- Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring
|
||||
- Layer shell popups (used by Waybar)
|
||||
@ -37,7 +37,7 @@ Feature *non-goals* include:
|
||||
|
||||
## Building dwl
|
||||
|
||||
dwl has only two dependencies: wlroots 0.12 and wayland-protocols. Simply install these and run `make`. If you wish to build against a Git version of wlroots, check out the [wlroots-next branch](https://github.com/djpohly/dwl/tree/wlroots-next).
|
||||
dwl has only two dependencies: wlroots-git and wayland-protocols. Simply install these and run `make`.
|
||||
|
||||
To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`.
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ static const int repeat_delay = 600;
|
||||
|
||||
/* Trackpad */
|
||||
static const int tap_to_click = 1;
|
||||
static const int natural_scrolling = 1;
|
||||
static const int natural_scrolling = 0;
|
||||
|
||||
#define MODKEY WLR_MODIFIER_ALT
|
||||
#define TAGKEYS(KEY,SKEY,TAG) \
|
||||
@ -62,11 +62,13 @@ static const int natural_scrolling = 1;
|
||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
|
||||
/* commands */
|
||||
static const char *termcmd[] = { "alacritty", NULL };
|
||||
static const char *termcmd[] = { "alacritty", NULL };
|
||||
static const char *menucmd[] = { "bemenu-run", NULL };
|
||||
|
||||
static const Key keys[] = {
|
||||
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
||||
/* modifier key function argument */
|
||||
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||
@ -99,6 +101,8 @@ static const Key keys[] = {
|
||||
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
|
||||
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
|
||||
|
||||
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
|
||||
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
|
||||
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
|
||||
|
||||
79
dwl.c
79
dwl.c
@ -93,6 +93,7 @@ typedef struct {
|
||||
struct wlr_xwayland_surface *xwayland;
|
||||
} surface;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener new_sub;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
@ -115,6 +116,16 @@ typedef struct {
|
||||
int isfullscreen;
|
||||
} Client;
|
||||
|
||||
typedef struct {
|
||||
struct wl_list link;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
struct wlr_subsurface *subsurface;
|
||||
Client *c;
|
||||
} Subsurface;
|
||||
|
||||
typedef struct {
|
||||
struct wl_listener request_mode;
|
||||
struct wl_listener destroy;
|
||||
@ -227,6 +238,7 @@ static void cleanupmon(struct wl_listener *listener, void *data);
|
||||
static void closemon(Monitor *m);
|
||||
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void commitnotify(struct wl_listener *listener, void *data);
|
||||
static void commitnotify_sub(struct wl_listener *listener, void *data);
|
||||
static void createkeyboard(struct wlr_input_device *device);
|
||||
static void createmon(struct wl_listener *listener, void *data);
|
||||
static void createnotify(struct wl_listener *listener, void *data);
|
||||
@ -236,6 +248,7 @@ static void createxdeco(struct wl_listener *listener, void *data);
|
||||
static void cursorframe(struct wl_listener *listener, void *data);
|
||||
static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void destroynotify(struct wl_listener *listener, void *data);
|
||||
static void destroynotify_sub(struct wl_listener *listener, void *data);
|
||||
static void destroyxdeco(struct wl_listener *listener, void *data);
|
||||
static Monitor *dirtomon(enum wlr_direction dir);
|
||||
static void focusclient(Client *c, int lift);
|
||||
@ -252,12 +265,14 @@ static void keypressmod(struct wl_listener *listener, void *data);
|
||||
static void killclient(const Arg *arg);
|
||||
static void maplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void mapnotify(struct wl_listener *listener, void *data);
|
||||
static void mapnotify_sub(struct wl_listener *listener, void *data);
|
||||
static void maximizeclient(Client *c);
|
||||
static void monocle(Monitor *m);
|
||||
static void motionabsolute(struct wl_listener *listener, void *data);
|
||||
static void motionnotify(uint32_t time);
|
||||
static void motionrelative(struct wl_listener *listener, void *data);
|
||||
static void moveresize(const Arg *arg);
|
||||
static void new_subnotify(struct wl_listener *listener, void *data);
|
||||
static void outputmgrapply(struct wl_listener *listener, void *data);
|
||||
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
|
||||
static void outputmgrtest(struct wl_listener *listener, void *data);
|
||||
@ -293,6 +308,7 @@ static void toggleview(const Arg *arg);
|
||||
static void unmaplayersurface(LayerSurface *layersurface);
|
||||
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void unmapnotify(struct wl_listener *listener, void *data);
|
||||
static void unmapnotify_sub(struct wl_listener *listener, void *data);
|
||||
static void updatemons(struct wl_listener *listener, void *data);
|
||||
static void view(const Arg *arg);
|
||||
static void virtualkeyboard(struct wl_listener *listener, void *data);
|
||||
@ -314,6 +330,7 @@ static struct wl_list clients; /* tiling order */
|
||||
static struct wl_list fstack; /* focus order */
|
||||
static struct wl_list stack; /* stacking z-order */
|
||||
static struct wl_list independents;
|
||||
static struct wl_list subsurfaces;
|
||||
static struct wlr_idle *idle;
|
||||
static struct wlr_layer_shell_v1 *layer_shell;
|
||||
static struct wlr_xdg_decoration_manager_v1 *xdeco_mgr;
|
||||
@ -490,6 +507,7 @@ arrange(Monitor *m)
|
||||
else if (m->fullscreenclient)
|
||||
maximizeclient(m->fullscreenclient);
|
||||
/* TODO recheck pointer focus here... or in resize()? */
|
||||
wlr_output_damage_add_whole(m->damage);
|
||||
}
|
||||
|
||||
void
|
||||
@ -791,6 +809,13 @@ commitnotify(struct wl_listener *listener, void *data)
|
||||
wlr_output_damage_add_whole(c->mon->damage);
|
||||
}
|
||||
|
||||
void
|
||||
commitnotify_sub(struct wl_listener *listener, void *data)
|
||||
{
|
||||
Subsurface *s = wl_container_of(listener, s, commit);
|
||||
wlr_output_damage_add_whole(s->c->mon->damage);
|
||||
}
|
||||
|
||||
void
|
||||
createkeyboard(struct wlr_input_device *device)
|
||||
{
|
||||
@ -909,6 +934,7 @@ createnotify(struct wl_listener *listener, void *data)
|
||||
WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
|
||||
LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify);
|
||||
LISTEN(&xdg_surface->surface->events.new_subsurface, &c->new_sub, new_subnotify);
|
||||
LISTEN(&xdg_surface->events.map, &c->map, mapnotify);
|
||||
LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify);
|
||||
LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify);
|
||||
@ -1042,6 +1068,17 @@ destroynotify(struct wl_listener *listener, void *data)
|
||||
free(c);
|
||||
}
|
||||
|
||||
void
|
||||
destroynotify_sub(struct wl_listener *listener, void *data)
|
||||
{
|
||||
Subsurface *s = wl_container_of(listener, s, destroy);
|
||||
wl_list_remove(&s->commit.link);
|
||||
wl_list_remove(&s->map.link);
|
||||
wl_list_remove(&s->unmap.link);
|
||||
wl_list_remove(&s->destroy.link);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void
|
||||
destroyxdeco(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@ -1300,7 +1337,7 @@ keypress(struct wl_listener *listener, void *data)
|
||||
wlr_idle_notify_activity(idle, seat);
|
||||
|
||||
/* On _press_, attempt to process a compositor keybinding. */
|
||||
if (event->state == WLR_KEY_PRESSED)
|
||||
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||
for (i = 0; i < nsyms; i++)
|
||||
handled = keybinding(mods, syms[i]) || handled;
|
||||
|
||||
@ -1383,6 +1420,15 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mapnotify_sub(struct wl_listener *listener, void *data)
|
||||
{
|
||||
Subsurface *s = wl_container_of(listener, s, map);
|
||||
wl_list_insert(&subsurfaces, &s->link);
|
||||
wlr_output_damage_add_whole(s->c->mon->damage);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
monocle(Monitor *m)
|
||||
{
|
||||
@ -1521,6 +1567,20 @@ moveresize(const Arg *arg)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
new_subnotify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_subsurface *subsurface = data;
|
||||
Subsurface *s = subsurface->data = calloc(1, sizeof(*s));
|
||||
s->subsurface = subsurface;
|
||||
s->c = wl_container_of(listener, s->c, new_sub);
|
||||
|
||||
LISTEN(&s->subsurface->surface->events.commit, &s->commit, commitnotify_sub);
|
||||
LISTEN(&s->subsurface->events.map, &s->map, mapnotify_sub);
|
||||
LISTEN(&s->subsurface->events.unmap, &s->unmap, unmapnotify_sub);
|
||||
LISTEN(&s->subsurface->events.destroy, &s->destroy, destroynotify_sub);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
outputmgrapply(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@ -1971,7 +2031,6 @@ setmon(Client *c, Monitor *m, unsigned int newtags)
|
||||
if (oldmon) {
|
||||
wlr_surface_send_leave(client_surface(c), oldmon->wlr_output);
|
||||
arrange(oldmon);
|
||||
wlr_output_damage_add_whole(oldmon->damage);
|
||||
}
|
||||
if (m) {
|
||||
/* Make sure window actually overlaps with the monitor */
|
||||
@ -1979,7 +2038,6 @@ setmon(Client *c, Monitor *m, unsigned int newtags)
|
||||
wlr_surface_send_enter(client_surface(c), m->wlr_output);
|
||||
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
|
||||
arrange(m);
|
||||
wlr_output_damage_add_whole(m->damage);
|
||||
}
|
||||
focusclient(focustop(selmon), 1);
|
||||
}
|
||||
@ -2024,7 +2082,7 @@ setup(void)
|
||||
* backend uses the renderer, for example, to fall back to software cursors
|
||||
* if the backend does not support hardware cursors (some older GPUs
|
||||
* don't). */
|
||||
if (!(backend = wlr_backend_autocreate(dpy, NULL)))
|
||||
if (!(backend = wlr_backend_autocreate(dpy)))
|
||||
BARF("couldn't create backend");
|
||||
|
||||
/* If we don't provide a renderer, autocreate makes a GLES2 renderer for us.
|
||||
@ -2069,6 +2127,7 @@ setup(void)
|
||||
wl_list_init(&fstack);
|
||||
wl_list_init(&stack);
|
||||
wl_list_init(&independents);
|
||||
wl_list_init(&subsurfaces);
|
||||
|
||||
idle = wlr_idle_create(dpy);
|
||||
|
||||
@ -2168,6 +2227,11 @@ setup(void)
|
||||
void
|
||||
sigchld(int unused)
|
||||
{
|
||||
/* We should be able to remove this function in favor of a simple
|
||||
* signal(SIGCHLD, SIG_IGN);
|
||||
* but the Xwayland implementation in wlroots currently prevents us from
|
||||
* setting our own disposition for SIGCHLD.
|
||||
*/
|
||||
if (signal(SIGCHLD, sigchld) == SIG_ERR)
|
||||
EBARF("can't install SIGCHLD handler");
|
||||
while (0 < waitpid(-1, NULL, WNOHANG))
|
||||
@ -2312,6 +2376,13 @@ unmapnotify(struct wl_listener *listener, void *data)
|
||||
wl_list_remove(&c->slink);
|
||||
}
|
||||
|
||||
void
|
||||
unmapnotify_sub(struct wl_listener *listener, void *data)
|
||||
{
|
||||
Subsurface *s = wl_container_of(listener, s, unmap);
|
||||
wl_list_remove(&s->link);
|
||||
}
|
||||
|
||||
void
|
||||
updatemons(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user