29 Commits
v0.2 ... v0.2.1

Author SHA1 Message Date
Devin J. Pohly
3a72cd924c fix README for main branch 2021-04-08 07:11:13 -05:00
Devin J. Pohly
2a9404ac2a Merge branch 'main' into wlroots-next 2021-03-30 13:57:34 -05:00
Devin J. Pohly
3c83e0cfb8 don't move/resize if already moving/resizing
Fixes #102.  The "ideal" behavior might be to ignore buttons other than
the one being used for the action, but this is super-simple and still
seems reasonable.
2021-03-30 13:56:04 -05:00
Devin J. Pohly
e73ea679f4 Merge branch 'main' into wlroots-next 2021-03-30 13:48:06 -05:00
Devin J. Pohly
db647f2df6 fix labels on issue templates 2021-03-29 17:04:37 -05:00
Devin J. Pohly
cd3d0a102f Merge branch 'main' into wlroots-next 2021-03-25 10:09:58 -05:00
Stivvo
38ba6d2277 Fullscreen: simplifications and fixes
Merges #69.
2021-03-25 10:05:12 -05:00
Devin J. Pohly
c2b53c2d8d Merge pull request #91 from drdonahue/wip-tag-status-interface
Interface to display tag information on status bar
2021-03-25 09:58:17 -05:00
David Donahue
ecc60878b3 changed fprintf(stdout) instances to printf(), changed function name from statusbar to printstatus 2021-03-13 11:20:33 -06:00
Devin J. Pohly
43b6e804cf Revert "remove sigchld function"
This reverts commit 1fa72b0772.
Fixes #97.
2021-03-13 10:42:42 -06:00
Devin J. Pohly
fba820d5f6 Merge branch 'main' into wlroots-next 2021-03-10 09:53:09 -06:00
Devin J. Pohly
1fa72b0772 remove sigchld function
Explicitly setting the handler for SIGCHLD to SIG_IGN tells the OS to
reap zombie processes automatically, which is what we wanted anyway.
2021-03-10 09:50:09 -06:00
David Donahue
7cee5060bc added redirect from stdout to stderr for spawned processes to prevent conflicts with the statusbar outputs 2021-03-06 12:20:56 -06:00
Devin J. Pohly
2144546192 Merge branch 'main' into wlroots-next 2021-03-03 11:30:39 -06:00
Devin J. Pohly
15f5d31f98 correct key constant name
Fixes #94.
2021-03-03 11:29:53 -06:00
David Donahue
5b51bb82e2 Fixed tab formatting in 6 locations where statusbar() is called 2021-03-01 14:38:00 -06:00
David Donahue
f5e7caac00 Changed output to stdout instead of a file 2021-03-01 13:49:29 -06:00
David Donahue
593b7eec3c updated output format for better expansibility and easier parsing 2021-03-01 13:19:25 -06:00
Devin J. Pohly
b063dd89c3 Merge branch 'main' into wlroots-next 2021-03-01 11:26:16 -06:00
Devin J. Pohly
fd498e1910 clarify a bit about status bars 2021-03-01 11:25:28 -06:00
Devin J. Pohly
02eed717ca add explanatory command about Ctrl-Alt-Bksp/Fx 2021-03-01 11:22:08 -06:00
Devin J. Pohly
2d71c9b9ff Add default menu command
dwm config parity
2021-03-01 11:21:15 -06:00
Devin J. Pohly
87b16e6095 Defaults should match dwm/Xorg default behavior 2021-03-01 11:17:10 -06:00
Devin J. Pohly
c1eb2b49cd Revert "Revert "remove EGL parameter from backend_autocreate""
This reverts commit 8ed88822ca.
2021-02-16 13:13:49 -06:00
Devin J. Pohly
e8192b4fc9 Revert "Revert "fix undeclared WLR_KEY_PRESSED""
This reverts commit a11f2bbc7a.
2021-02-16 13:13:48 -06:00
Devin J. Pohly
4798450944 Revert "Revert "document that we currently follow wlroots-git""
This reverts commit ed8e80d961.
2021-02-16 13:13:47 -06:00
David Donahue
a1e24075d8 Removed unused variable from statusbar 2021-02-08 18:12:24 -06:00
David Donahue
27598bd04a added statusbar update when tags are updated 2021-02-07 01:03:04 -06:00
David Donahue
3868217466 Added interface to output information about tags, the currently selected monitor, and the focused client to a file for use by a status bar 2021-02-07 00:31:01 -06:00
5 changed files with 61 additions and 47 deletions

View File

@@ -2,7 +2,7 @@
name: Bug report
about: Something in dwl isn't working correctly
title: ''
labels: 'Type: bug'
labels: 'A: bug'
assignees: ''
---

View File

@@ -2,7 +2,7 @@
name: Enhancement idea
about: Suggest a feature or improvement
title: ''
labels: 'Type: enhancement'
labels: 'A: enhancement'
assignees: ''
---

View File

@@ -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 0.13 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).
To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`.

View File

@@ -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),

90
dwl.c
View File

@@ -175,7 +175,6 @@ struct Monitor {
unsigned int tagset[2];
double mfact;
int nmaster;
Client *fullscreenclient;
};
typedef struct {
@@ -249,7 +248,6 @@ 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 maximizeclient(Client *c);
static void monocle(Monitor *m);
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time);
@@ -260,6 +258,7 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int
static void outputmgrtest(struct wl_listener *listener, void *data);
static void pointerfocus(Client *c, struct wlr_surface *surface,
double sx, double sy, uint32_t time);
static void printstatus(void);
static void quit(const Arg *arg);
static void render(struct wlr_surface *surface, int sx, int sy, void *data);
static void renderclients(Monitor *m, struct timespec *now);
@@ -484,8 +483,6 @@ arrange(Monitor *m)
{
if (m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
else if (m->fullscreenclient)
maximizeclient(m->fullscreenclient);
/* TODO recheck pointer focus here... or in resize()? */
}
@@ -884,9 +881,6 @@ createnotify(struct wl_listener *listener, void *data)
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
return;
wl_list_for_each(c, &clients, link)
if (c->isfullscreen && VISIBLEON(c, c->mon))
setfullscreen(c, 0);
/* Allocate a Client for this surface */
c = xdg_surface->data = calloc(1, sizeof(*c));
@@ -1041,14 +1035,8 @@ void
togglefullscreen(const Arg *arg)
{
Client *sel = selclient();
setfullscreen(sel, !sel->isfullscreen);
}
void
maximizeclient(Client *c)
{
resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
/* used for fullscreen clients */
if (sel)
setfullscreen(sel, !sel->isfullscreen);
}
void
@@ -1063,13 +1051,11 @@ setfullscreen(Client *c, int fullscreen)
c->prevy = c->geom.y;
c->prevheight = c->geom.height;
c->prevwidth = c->geom.width;
c->mon->fullscreenclient = c;
maximizeclient(c);
resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
} else {
/* restore previous size instead of arrange for floating windows since
* client positions are set by the user and cannot be recalculated */
resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
c->mon->fullscreenclient = NULL;
arrange(c->mon);
}
}
@@ -1116,6 +1102,7 @@ focusclient(Client *c, int lift)
wl_list_insert(&fstack, &c->flink);
selmon = c->mon;
}
printstatus();
/* Deactivate old client if focus is changing */
if (old && (!c || client_surface(c) != old)) {
@@ -1284,7 +1271,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;
@@ -1335,7 +1322,7 @@ void
mapnotify(struct wl_listener *listener, void *data)
{
/* Called when the surface is mapped, or ready to display on-screen. */
Client *c = wl_container_of(listener, c, map), *oldfocus = selclient();
Client *c = wl_container_of(listener, c, map);
if (client_is_unmanaged(c)) {
/* Insert this independent into independents lists. */
@@ -1354,14 +1341,6 @@ mapnotify(struct wl_listener *listener, void *data)
/* Set initial monitor, tags, floating status, and focus */
applyrules(c);
if (c->mon->fullscreenclient && c->mon->fullscreenclient == oldfocus
&& !c->isfloating && c->mon->lt[c->mon->sellt]->arrange) {
maximizeclient(c->mon->fullscreenclient);
focusclient(c->mon->fullscreenclient, 1);
/* give the focus back the fullscreen client on that monitor if exists,
* is focused and the new client isn't floating */
}
}
void
@@ -1370,12 +1349,9 @@ monocle(Monitor *m)
Client *c;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating)
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (c->isfullscreen)
maximizeclient(c);
else
resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0);
resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0);
}
}
@@ -1478,8 +1454,7 @@ motionrelative(struct wl_listener *listener, void *data)
void
moveresize(const Arg *arg)
{
grabc = xytoclient(cursor->x, cursor->y);
if (!grabc)
if (cursor_mode != CurNormal || !(grabc = xytoclient(cursor->x, cursor->y)))
return;
/* Float the window and tell motionnotify to grab it */
@@ -1602,6 +1577,31 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
focusclient(c, 0);
}
void
printstatus(void)
{
Monitor *m = NULL;
Client *c = NULL;
unsigned int activetags;
wl_list_for_each(m, &mons, link) {
activetags=0;
wl_list_for_each(c, &clients, link) {
if (c->mon == m)
activetags |= c->tags;
}
if (focustop(m))
printf("%s title %s\n", m->wlr_output->name, client_get_title(focustop(m)));
else
printf("%s title \n", m->wlr_output->name);
printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
printf("%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]);
printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol);
}
fflush(stdout);
}
void
quit(const Arg *arg)
{
@@ -1844,6 +1844,7 @@ run(char *startup_cmd)
if (startup_pid < 0)
EBARF("startup: fork");
if (startup_pid == 0) {
dup2(STDERR_FILENO, STDOUT_FILENO);
execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
EBARF("startup: execl");
}
@@ -1914,6 +1915,7 @@ setlayout(const Arg *arg)
selmon->lt[selmon->sellt] = (Layout *)arg->v;
/* TODO change layout symbol? */
arrange(selmon);
printstatus();
}
/* arg > 1.0 will set mfact absolutely */
@@ -1995,7 +1997,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.
@@ -2139,6 +2141,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))
@@ -2149,6 +2156,7 @@ void
spawn(const Arg *arg)
{
if (fork() == 0) {
dup2(STDERR_FILENO, STDOUT_FILENO);
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
EBARF("dwl: execvp %s failed", ((char **)arg->v)[0]);
@@ -2164,6 +2172,7 @@ tag(const Arg *arg)
focusclient(focustop(selmon), 1);
arrange(selmon);
}
printstatus();
}
void
@@ -2193,11 +2202,9 @@ tile(Monitor *m)
mw = m->w.width;
i = my = ty = 0;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating)
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (c->isfullscreen)
maximizeclient(c);
else if (i < m->nmaster) {
if (i < m->nmaster) {
h = (m->w.height - my) / (MIN(n, m->nmaster) - i);
resize(c, m->w.x, m->w.y + my, mw, h, 0);
my += c->geom.height;
@@ -2233,6 +2240,7 @@ toggletag(const Arg *arg)
focusclient(focustop(selmon), 1);
arrange(selmon);
}
printstatus();
}
void
@@ -2245,6 +2253,7 @@ toggleview(const Arg *arg)
focusclient(focustop(selmon), 1);
arrange(selmon);
}
printstatus();
}
void
@@ -2325,6 +2334,7 @@ view(const Arg *arg)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
focusclient(focustop(selmon), 1);
arrange(selmon);
printstatus();
}
void