This commit is contained in:
Ray Andrew 2024-09-29 00:08:19 -05:00
parent ec5427a43d
commit 4a7a296450
2 changed files with 281 additions and 80 deletions

View file

@ -4,7 +4,7 @@
((hex >> 8) & 0xFF) / 255.0f, \ ((hex >> 8) & 0xFF) / 255.0f, \
(hex & 0xFF) / 255.0f } (hex & 0xFF) / 255.0f }
/* appearance */ /* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */ static const int sloppyfocus = 0; /* focus follows mouse */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */ static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */
static const int monoclegaps = 1; /* 1 means outer gaps in monocle layout */ static const int monoclegaps = 1; /* 1 means outer gaps in monocle layout */
@ -64,6 +64,7 @@ static int log_level = WLR_DEBUG;
/* Autostart */ /* Autostart */
static const char *const autostart[] = { static const char *const autostart[] = {
"/usr/lib/pam_kwallet_init", NULL,
"dbus-update-activation-environment", "DISPLAY", "MOZ_DBUS_REMOTE", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP", NULL, "dbus-update-activation-environment", "DISPLAY", "MOZ_DBUS_REMOTE", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP", NULL,
"dinit", "-q", NULL, "dinit", "-q", NULL,
// "pkexec", "swayosd-libinput-backend", NULL, // "pkexec", "swayosd-libinput-backend", NULL,
@ -74,17 +75,19 @@ static const char *const autostart[] = {
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */ /* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = { static const Rule rules[] = {
/* app_id title tags mask isfloating isterm noswallow monitor */ /* app_id title tags mask isfloating isterm noswallow monitor */
/* examples: */ /* examples: */
{ "Gimp_EXAMPLE", NULL, 0, 1, 0, 0, -1 }, /* Start on currently visible tags floating, not tiled */ { "Gimp_EXAMPLE", NULL, 0, 1, 0, 0, -1 }, /* Start on currently visible tags floating, not tiled */
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, 0, 0, -1 }, /* Start on ONLY tag "9" */ { "firefox_EXAMPLE", NULL, 1 << 8, 0, 0, 0, -1 }, /* Start on ONLY tag "9" */
{ "zoom", NULL, 0, 1, 0, 0, -1 }, { "zoom", NULL, 0, 1, 0, 0, -1 },
{ "teams", NULL, 0, 1, 0, 0, -1 }, { "teams", NULL, 0, 1, 0, 0, -1 },
{ "wezterm", NULL, 0, 0, 1, 1, -1 }, /* make wezterm swallow clients that are not wezterm */ { "wezterm", NULL, 0, 0, 1, 1, -1 }, /* make wezterm swallow clients that are not wezterm */
{ "foot", NULL, 0, 0, 1, 1, -1 }, /* make foot swallow clients that are not foot */ { "foot", NULL, 0, 0, 1, 1, -1 }, /* make foot swallow clients that are not foot */
{ "thesaurus-syn", NULL, 0, 1, 1, 1, -1 }, /* make foot swallow clients that are not foot */ { "thesaurus-syn", NULL, 0, 1, 1, 1, -1 },
{ NULL, "wev", 0, 0, 0, 1, -1 }, /* xev */ { "xdg-desktop-portal-gtk", "Open File", 0, 1, 0, 1, -1 },
{ NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ { "org.freedesktop.impl.portal.desktop.kde", "Open File", 0, 1, 0, 1, -1 },
{ NULL, "wev", 0, 0, 0, 1, -1 },
{ NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
}; };
/* layout(s) */ /* layout(s) */
@ -227,15 +230,20 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} }, { MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} },
// { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, togglebar, {0} }, // { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, togglebar, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, focusstack, {.i = +1} }, { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, focusstack, {.i = -1} }, { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_j, relativeswap, {.i = +1} }, // { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_j, relativeswap, {.i = +1} },
{ MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_k, relativeswap, {.i = -1} }, // { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_k, relativeswap, {.i = -1} },
{ MODKEY, XKB_KEY_h, focusdir, {.ui = 0} }, { MODKEY, XKB_KEY_h, focusdir, {.ui = 0} },
{ MODKEY, XKB_KEY_l, focusdir, {.ui = 1} }, { MODKEY, XKB_KEY_l, focusdir, {.ui = 1} },
{ MODKEY, XKB_KEY_k, focusdir, {.ui = 2} }, { MODKEY, XKB_KEY_k, focusdir, {.ui = 2} },
{ MODKEY, XKB_KEY_j, focusdir, {.ui = 3} }, { MODKEY, XKB_KEY_j, focusdir, {.ui = 3} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H, swapdir, {.ui = 0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_L, swapdir, {.ui = 1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, swapdir, {.ui = 2} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, swapdir, {.ui = 3} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H, setmfact, {.f = -0.05f} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H, setmfact, {.f = -0.05f} },
@ -267,7 +275,7 @@ static const Key keys[] = {
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7), TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8), TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
TAGKEYS( XKB_KEY_0, XKB_KEY_parenright, 9), TAGKEYS( XKB_KEY_0, XKB_KEY_parenright, 9),
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, quit, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_bar, quit, {0} },
// { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, spawn, KILL_DWL }, // { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, spawn, KILL_DWL },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, spawn, SHCMD("killall dbus-run-session") }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, spawn, SHCMD("killall dbus-run-session") },
@ -299,9 +307,11 @@ static const Key keys[] = {
{ 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = decreasebrightnesscmd } }, { 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = decreasebrightnesscmd } },
// screenshot // screenshot
{ MODKEY, XKB_KEY_Print, spawn, SCREENSHOTDIR_CMD }, { MODKEY, XKB_KEY_Print, regions, SCREENSHOTDIR_CMD },
{ MODKEY, XKB_KEY_o, spawn, SCREENSHOTDIR_CMD }, { MODKEY, XKB_KEY_o, regions, SCREENSHOTDIR_CMD },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, spawn, SCREENSHOTCLIPBOARD_CMD }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, regions, SCREENSHOTCLIPBOARD_CMD },
// { MODKEY, XKB_KEY_r, regions, SCREENSHOTDIR_CMD },
// { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, regions, SCREENSHOTCLIPBOARD_CMD },
// Apps // Apps
{ MODKEY, XKB_KEY_m, spawn, TERM("neomutt") }, { MODKEY, XKB_KEY_m, spawn, TERM("neomutt") },

313
dwl.c
View file

@ -281,6 +281,11 @@ typedef struct {
struct wl_listener destroy; struct wl_listener destroy;
} SessionLock; } SessionLock;
typedef struct {
int x;
int y;
} Vector;
/* function declarations */ /* function declarations */
static void applybounds(Client *c, struct wlr_box *bbox); static void applybounds(Client *c, struct wlr_box *bbox);
static void applyrules(Client *c); static void applyrules(Client *c);
@ -351,6 +356,7 @@ static void focusto(const Arg *arg);
static void focusmon(const Arg *arg); static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg); static void focusstack(const Arg *arg);
static void focusdir(const Arg *arg); static void focusdir(const Arg *arg);
static void swapdir(const Arg *arg);
static Client *focustop(Monitor *m); static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data); static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data); static void gpureset(struct wl_listener *listener, void *data);
@ -436,6 +442,7 @@ 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 wl_list_swap(struct wl_list *a, struct wl_list *b); static void wl_list_swap(struct wl_list *a, struct wl_list *b);
static void zoom(const Arg *arg); static void zoom(const Arg *arg);
static void regions(const Arg *arg);
static pid_t getparentprocess(pid_t p); static pid_t getparentprocess(pid_t p);
static int isdescprocess(pid_t p, pid_t c); static int isdescprocess(pid_t p, pid_t c);
static Client *termforwin(Client *w); static Client *termforwin(Client *w);
@ -2057,48 +2064,205 @@ focusstack(const Arg *arg)
focusclient(c, 1); focusclient(c, 1);
} }
void focusdir(const Arg *arg) // void focusdir(const Arg *arg)
// {
// /* Focus the left, right, up, down client relative to the current focused client on selmon */
// Client *c, *sel = focustop(selmon);
// if (!sel || sel->isfullscreen)
// return;
//
// int dist=INT_MAX;
// Client *newsel = NULL;
// int newdist=INT_MAX;
// wl_list_for_each(c, &clients, link) {
// if (!VISIBLEON(c, selmon))
// continue; /* skip non visible windows */
//
// if (arg->ui == 0 && sel->geom.x <= c->geom.x) {
// /* Client isn't on our left */
// continue;
// }
// if (arg->ui == 1 && sel->geom.x >= c->geom.x) {
// /* Client isn't on our right */
// continue;
// }
// if (arg->ui == 2 && sel->geom.y <= c->geom.y) {
// /* Client isn't above us */
// continue;
// }
// if (arg->ui == 3 && sel->geom.y >= c->geom.y) {
// /* Client isn't below us */
// continue;
// }
//
// dist=abs(sel->geom.x-c->geom.x)+abs(sel->geom.y-c->geom.y);
// if (dist < newdist){
// newdist = dist;
// newsel=c;
// }
// }
// if (newsel != NULL){
// focusclient(newsel, 1);
// }
// }
Vector
position_of_box(const struct wlr_box *box)
{ {
/* Focus the left, right, up, down client relative to the current focused client on selmon */ return (Vector){
Client *c, *sel = focustop(selmon); .x = box->x + box->width / 2,
if (!sel || sel->isfullscreen) .y = box->y + box->height / 2,
return; };
int dist=INT_MAX;
Client *newsel = NULL;
int newdist=INT_MAX;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, selmon))
continue; /* skip non visible windows */
if (arg->ui == 0 && sel->geom.x <= c->geom.x) {
/* Client isn't on our left */
continue;
}
if (arg->ui == 1 && sel->geom.x >= c->geom.x) {
/* Client isn't on our right */
continue;
}
if (arg->ui == 2 && sel->geom.y <= c->geom.y) {
/* Client isn't above us */
continue;
}
if (arg->ui == 3 && sel->geom.y >= c->geom.y) {
/* Client isn't below us */
continue;
}
dist=abs(sel->geom.x-c->geom.x)+abs(sel->geom.y-c->geom.y);
if (dist < newdist){
newdist = dist;
newsel=c;
}
}
if (newsel != NULL){
focusclient(newsel, 1);
}
} }
Vector
diff_of_vectors(Vector *a, Vector *b)
{
return (Vector){
.x = b->x - a->x,
.y = b->y - a->y,
};
}
const char *
direction_of_vector(Vector *vector)
{
// A zero length vector has no direction
if (vector->x == 0 && vector->y == 0) return "";
if (abs(vector->y) > abs(vector->x)) {
// Careful: We are operating in a Y-inverted coordinate system.
return (vector->y > 0) ? "bottom" : "top";
} else {
return (vector->x > 0) ? "right" : "left";
}
}
uint32_t
vector_length(Vector *vector)
{
// Euclidean distance formula
return (uint32_t)sqrt(vector->x * vector->x + vector->y * vector->y);
}
// Spatial direction, based on focused client position.
Client *
client_in_direction(const char *direction, const int *skipfloat)
{
Client *cfocused = focustop(selmon);
Vector cfocusedposition;
Client *ctarget = NULL;
double targetdistance = INFINITY;
Client *c;
if (!cfocused || cfocused->isfullscreen || (skipfloat && cfocused->isfloating))
return NULL;
cfocusedposition = position_of_box(&cfocused->geom);
wl_list_for_each(c, &clients, link) {
Vector cposition;
Vector positiondiff;
uint32_t distance;
if (c == cfocused)
continue;
if (skipfloat && c->isfloating)
continue;
if (!VISIBLEON(c, selmon))
continue;
cposition = position_of_box(&c->geom);
positiondiff = diff_of_vectors(&cfocusedposition, &cposition);
if (strcmp(direction, direction_of_vector(&positiondiff)) != 0)
continue;
distance = vector_length(&positiondiff);
if (distance < targetdistance) {
ctarget = c;
targetdistance = distance;
}
}
return ctarget;
}
void
focusdir(const Arg *arg)
{
Client *c = NULL;
if (arg->ui == 0)
c = client_in_direction("left", (int *)0);
if (arg->ui == 1)
c = client_in_direction("right", (int *)0);
if (arg->ui == 2)
c = client_in_direction("top", (int *)0);
if (arg->ui == 3)
c = client_in_direction("bottom", (int *)0);
if (c != NULL)
focusclient(c, 1);
}
void
wl_list_swap(struct wl_list *list1, struct wl_list *list2)
{
struct wl_list *prev1, *next1, *prev2, *next2;
struct wl_list temp;
if (list1 == list2) {
// No need to swap the same list
return;
}
// Get the lists before and after list1
prev1 = list1->prev;
next1 = list1->next;
// Get the lists before and after list2
prev2 = list2->prev;
next2 = list2->next;
// Update the next and previous pointers of adjacent lists
prev1->next = list2;
next1->prev = list2;
prev2->next = list1;
next2->prev = list1;
// Swap the next and previous pointers of the lists to actually swap them
temp = *list1;
*list1 = *list2;
*list2 = temp;
}
void
swapdir(const Arg *arg)
{
Client *c = NULL;
Client *cfocused;
if (arg->ui == 0)
c = client_in_direction("left", (int *)1);
if (arg->ui == 1)
c = client_in_direction("right", (int *)1);
if (arg->ui == 2)
c = client_in_direction("top", (int *)1);
if (arg->ui == 3)
c = client_in_direction("bottom", (int *)1);
if (c == NULL)
return;
cfocused = focustop(selmon);
wl_list_swap(&cfocused->link, &c->link);
arrange(selmon);
}
/* We probably should change the name of this, it sounds like /* We probably should change the name of this, it sounds like
* will focus the topmost client of this mon, when actually will * will focus the topmost client of this mon, when actually will
@ -4042,28 +4206,28 @@ xytomon(double x, double y)
return o ? o->data : NULL; return o ? o->data : NULL;
} }
void // void
wl_list_swap(struct wl_list *a, struct wl_list *b) // wl_list_swap(struct wl_list *a, struct wl_list *b)
{ // {
struct wl_list *prev_a = a->prev; // struct wl_list *prev_a = a->prev;
struct wl_list *prev_b = b->prev; // struct wl_list *prev_b = b->prev;
//
if (prev_b == a) { // if (prev_b == a) {
wl_list_remove(a); // wl_list_remove(a);
wl_list_insert(b, a); // wl_list_insert(b, a);
return; // return;
} // }
if (prev_a == b) { // if (prev_a == b) {
wl_list_remove(b); // wl_list_remove(b);
wl_list_insert(a, b); // wl_list_insert(a, b);
return; // return;
} // }
wl_list_remove(a); // wl_list_remove(a);
wl_list_insert(prev_b, a); // wl_list_insert(prev_b, a);
//
wl_list_remove(b); // wl_list_remove(b);
wl_list_insert(prev_a, b); // wl_list_insert(prev_a, b);
} // }
void void
xytonode(double x, double y, struct wlr_surface **psurface, xytonode(double x, double y, struct wlr_surface **psurface,
@ -4177,6 +4341,33 @@ fdestroynotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->fdestroy.link); wl_list_remove(&c->fdestroy.link);
} }
void
regions(const Arg *arg)
{
int pipefd[2];
Client *c;
Monitor *m;
if (pipe(pipefd) == -1)
return;
if (fork() == 0) {
close(pipefd[1]);
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
die("dwl: execvp %s failed:", ((char **)arg->v)[0]);
}
close(pipefd[0]);
wl_list_for_each(m, &mons, link)
wl_list_for_each(c, &clients, link)
if (VISIBLEON(c, m))
dprintf(pipefd[1], "%d,%d %dx%d\n",
c->geom.x, c->geom.y, c->geom.width, c->geom.height);
close(pipefd[1]);
}
#ifdef XWAYLAND #ifdef XWAYLAND
void void
activatex11(struct wl_listener *listener, void *data) activatex11(struct wl_listener *listener, void *data)