swapdir
This commit is contained in:
parent
ec5427a43d
commit
4a7a296450
2 changed files with 281 additions and 80 deletions
32
config.def.h
32
config.def.h
|
|
@ -4,7 +4,7 @@
|
|||
((hex >> 8) & 0xFF) / 255.0f, \
|
||||
(hex & 0xFF) / 255.0f }
|
||||
/* 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 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 */
|
||||
|
|
@ -64,6 +64,7 @@ static int log_level = WLR_DEBUG;
|
|||
|
||||
/* 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,
|
||||
"dinit", "-q", NULL,
|
||||
// "pkexec", "swayosd-libinput-backend", NULL,
|
||||
|
|
@ -82,8 +83,10 @@ static const char *const autostart[] = {
|
|||
{ "teams", NULL, 0, 1, 0, 0, -1 },
|
||||
{ "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 */
|
||||
{ "thesaurus-syn", NULL, 0, 1, 1, 1, -1 }, /* make foot swallow clients that are not foot */
|
||||
{ NULL, "wev", 0, 0, 0, 1, -1 }, /* xev */
|
||||
{ "thesaurus-syn", NULL, 0, 1, 1, 1, -1 },
|
||||
{ "xdg-desktop-portal-gtk", "Open File", 0, 1, 0, 1, -1 },
|
||||
{ "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 */
|
||||
};
|
||||
|
||||
|
|
@ -227,15 +230,20 @@ static const Key keys[] = {
|
|||
{ MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||
|
||||
// { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, togglebar, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, focusstack, {.i = +1} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, focusstack, {.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_j, 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_k, relativeswap, {.i = -1} },
|
||||
|
||||
{ MODKEY, XKB_KEY_h, focusdir, {.ui = 0} },
|
||||
{ MODKEY, XKB_KEY_l, focusdir, {.ui = 1} },
|
||||
{ MODKEY, XKB_KEY_k, focusdir, {.ui = 2} },
|
||||
{ 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_d, incnmaster, {.i = -1} },
|
||||
{ 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_9, XKB_KEY_parenleft, 8),
|
||||
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_E, spawn, SHCMD("killall dbus-run-session") },
|
||||
|
||||
|
|
@ -299,9 +307,11 @@ static const Key keys[] = {
|
|||
{ 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = decreasebrightnesscmd } },
|
||||
|
||||
// screenshot
|
||||
{ MODKEY, XKB_KEY_Print, spawn, SCREENSHOTDIR_CMD },
|
||||
{ MODKEY, XKB_KEY_o, spawn, SCREENSHOTDIR_CMD },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, spawn, SCREENSHOTCLIPBOARD_CMD },
|
||||
{ MODKEY, XKB_KEY_Print, regions, SCREENSHOTDIR_CMD },
|
||||
{ MODKEY, XKB_KEY_o, regions, SCREENSHOTDIR_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
|
||||
{ MODKEY, XKB_KEY_m, spawn, TERM("neomutt") },
|
||||
|
|
|
|||
311
dwl.c
311
dwl.c
|
|
@ -281,6 +281,11 @@ typedef struct {
|
|||
struct wl_listener destroy;
|
||||
} SessionLock;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} Vector;
|
||||
|
||||
/* function declarations */
|
||||
static void applybounds(Client *c, struct wlr_box *bbox);
|
||||
static void applyrules(Client *c);
|
||||
|
|
@ -351,6 +356,7 @@ static void focusto(const Arg *arg);
|
|||
static void focusmon(const Arg *arg);
|
||||
static void focusstack(const Arg *arg);
|
||||
static void focusdir(const Arg *arg);
|
||||
static void swapdir(const Arg *arg);
|
||||
static Client *focustop(Monitor *m);
|
||||
static void fullscreennotify(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);
|
||||
static void wl_list_swap(struct wl_list *a, struct wl_list *b);
|
||||
static void zoom(const Arg *arg);
|
||||
static void regions(const Arg *arg);
|
||||
static pid_t getparentprocess(pid_t p);
|
||||
static int isdescprocess(pid_t p, pid_t c);
|
||||
static Client *termforwin(Client *w);
|
||||
|
|
@ -2057,48 +2064,205 @@ focusstack(const Arg *arg)
|
|||
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 */
|
||||
Client *c, *sel = focustop(selmon);
|
||||
if (!sel || sel->isfullscreen)
|
||||
return (Vector){
|
||||
.x = box->x + box->width / 2,
|
||||
.y = box->y + box->height / 2,
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
cfocused = focustop(selmon);
|
||||
wl_list_swap(&cfocused->link, &c->link);
|
||||
arrange(selmon);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We probably should change the name of this, it sounds like
|
||||
* 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;
|
||||
}
|
||||
|
||||
void
|
||||
wl_list_swap(struct wl_list *a, struct wl_list *b)
|
||||
{
|
||||
struct wl_list *prev_a = a->prev;
|
||||
struct wl_list *prev_b = b->prev;
|
||||
|
||||
if (prev_b == a) {
|
||||
wl_list_remove(a);
|
||||
wl_list_insert(b, a);
|
||||
return;
|
||||
}
|
||||
if (prev_a == b) {
|
||||
wl_list_remove(b);
|
||||
wl_list_insert(a, b);
|
||||
return;
|
||||
}
|
||||
wl_list_remove(a);
|
||||
wl_list_insert(prev_b, a);
|
||||
|
||||
wl_list_remove(b);
|
||||
wl_list_insert(prev_a, b);
|
||||
}
|
||||
// void
|
||||
// wl_list_swap(struct wl_list *a, struct wl_list *b)
|
||||
// {
|
||||
// struct wl_list *prev_a = a->prev;
|
||||
// struct wl_list *prev_b = b->prev;
|
||||
//
|
||||
// if (prev_b == a) {
|
||||
// wl_list_remove(a);
|
||||
// wl_list_insert(b, a);
|
||||
// return;
|
||||
// }
|
||||
// if (prev_a == b) {
|
||||
// wl_list_remove(b);
|
||||
// wl_list_insert(a, b);
|
||||
// return;
|
||||
// }
|
||||
// wl_list_remove(a);
|
||||
// wl_list_insert(prev_b, a);
|
||||
//
|
||||
// wl_list_remove(b);
|
||||
// wl_list_insert(prev_a, b);
|
||||
// }
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
void
|
||||
activatex11(struct wl_listener *listener, void *data)
|
||||
|
|
|
|||
Loading…
Reference in a new issue