mirror of
https://github.com/vale981/bspwm
synced 2025-03-05 09:51:38 -05:00
parent
644b9e591a
commit
00cf7896a4
11 changed files with 101 additions and 44 deletions
|
@ -135,32 +135,41 @@ bool find_any_desktop(coordinates_t *ref, coordinates_t *dst, desktop_select_t *
|
|||
return false;
|
||||
}
|
||||
|
||||
bool set_layout(monitor_t *m, desktop_t *d, layout_t l)
|
||||
bool set_layout(monitor_t *m, desktop_t *d, layout_t l, bool user)
|
||||
{
|
||||
layout_t actual_layout = IS_SINGLE_MONOCLE(d) ? LAYOUT_MONOCLE : l;
|
||||
bool actual_layout_changed = (d->layout != actual_layout);
|
||||
|
||||
if (d->layout == l) {
|
||||
if ((user && d->user_layout == l) || (!user && d->layout == l)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
layout_t old_layout = d->layout;
|
||||
|
||||
if (user) {
|
||||
d->user_layout = l;
|
||||
} else {
|
||||
d->layout = l;
|
||||
|
||||
handle_presel_feedbacks(m, d);
|
||||
|
||||
if (!actual_layout_changed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
arrange(m, d);
|
||||
if (user && (!single_monocle || tiled_count(d->root, true) > 1)) {
|
||||
d->layout = l;
|
||||
}
|
||||
|
||||
put_status(SBSC_MASK_DESKTOP_LAYOUT, "desktop_layout 0x%08X 0x%08X %s\n", m->id, d->id, LAYOUT_STR(actual_layout));
|
||||
if (d->layout != old_layout) {
|
||||
handle_presel_feedbacks(m, d);
|
||||
|
||||
if (user) {
|
||||
arrange(m, d);
|
||||
}
|
||||
|
||||
put_status(SBSC_MASK_DESKTOP_LAYOUT, "desktop_layout 0x%08X 0x%08X %s\n", m->id, d->id, LAYOUT_STR(d->layout));
|
||||
|
||||
if (d == m->desk) {
|
||||
put_status(SBSC_MASK_REPORT);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_presel_feedbacks(monitor_t *m, desktop_t *d)
|
||||
|
@ -255,7 +264,7 @@ desktop_t *make_desktop(const char *name, uint32_t id)
|
|||
}
|
||||
d->prev = d->next = NULL;
|
||||
d->root = d->focus = NULL;
|
||||
d->layout = LAYOUT_TILED;
|
||||
d->layout = d->user_layout = LAYOUT_TILED;
|
||||
d->padding = (padding_t) PADDING;
|
||||
d->window_gap = window_gap;
|
||||
d->border_width = border_width;
|
||||
|
|
|
@ -31,7 +31,7 @@ void focus_desktop(monitor_t *m, desktop_t *d);
|
|||
bool activate_desktop(monitor_t *m, desktop_t *d);
|
||||
bool find_closest_desktop(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir, desktop_select_t *sel);
|
||||
bool find_any_desktop(coordinates_t *ref, coordinates_t *dst, desktop_select_t *sel);
|
||||
bool set_layout(monitor_t *m, desktop_t *d, layout_t l);
|
||||
bool set_layout(monitor_t *m, desktop_t *d, layout_t l, bool user);
|
||||
void handle_presel_feedbacks(monitor_t *m, desktop_t *d);
|
||||
bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d, bool follow);
|
||||
desktop_t *make_desktop(const char *name, uint32_t id);
|
||||
|
|
|
@ -41,10 +41,6 @@
|
|||
#define IS_FULLSCREEN(c) (c->state == STATE_FULLSCREEN)
|
||||
#define IS_RECEPTACLE(n) (is_leaf(n) && n->client == NULL)
|
||||
|
||||
#define IS_SINGLE_MONOCLE(d) (single_monocle && tiled_count(d->root, true) <= 1)
|
||||
#define IS_MONOCLE(d) (d->layout == LAYOUT_MONOCLE || IS_SINGLE_MONOCLE(d))
|
||||
#define ACTUAL_LAYOUT(d) (IS_MONOCLE(d) ? LAYOUT_MONOCLE : d->layout)
|
||||
|
||||
#define BOOL_STR(A) ((A) ? "true" : "false")
|
||||
#define ON_OFF_STR(A) ((A) ? "on" : "off")
|
||||
#define LAYOUT_STR(A) ((A) == LAYOUT_TILED ? "tiled" : "monocle")
|
||||
|
|
|
@ -745,9 +745,9 @@ void cmd_desktop(char **args, int num, FILE *rsp)
|
|||
layout_t lyt;
|
||||
cycle_dir_t cyc;
|
||||
if (parse_cycle_direction(*args, &cyc)) {
|
||||
ret = set_layout(trg.monitor, trg.desktop, (trg.desktop->layout + 1) % 2);
|
||||
ret = set_layout(trg.monitor, trg.desktop, (trg.desktop->layout + 1) % 2, true);
|
||||
} else if (parse_layout(*args, &lyt)) {
|
||||
ret = set_layout(trg.monitor, trg.desktop, lyt);
|
||||
ret = set_layout(trg.monitor, trg.desktop, lyt, true);
|
||||
} else {
|
||||
fail(rsp, "desktop %s: Invalid argument: '%s'.\n", *(args - 1), *args);
|
||||
break;
|
||||
|
@ -1637,6 +1637,24 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
|
|||
fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
|
||||
return;
|
||||
}
|
||||
} else if (streq("single_monocle", name)) {
|
||||
bool b;
|
||||
if (parse_bool(value, &b)) {
|
||||
if (b == single_monocle) {
|
||||
fail(rsp, "");
|
||||
return;
|
||||
}
|
||||
single_monocle = b;
|
||||
for (monitor_t *m = mon_head; m != NULL; m = m->next) {
|
||||
for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
|
||||
layout_t l = (single_monocle && tiled_count(d->root, true) <= 1) ? LAYOUT_MONOCLE : d->user_layout;
|
||||
set_layout(m, d, l, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
|
||||
return;
|
||||
}
|
||||
} else if (streq("focus_follows_pointer", name)) {
|
||||
bool b;
|
||||
if (parse_bool(value, &b)) {
|
||||
|
@ -1674,8 +1692,6 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
|
|||
SET_BOOL(presel_feedback)
|
||||
SET_BOOL(borderless_monocle)
|
||||
SET_BOOL(gapless_monocle)
|
||||
SET_BOOL(single_monocle)
|
||||
put_status(SBSC_MASK_REPORT);
|
||||
SET_BOOL(swallow_first_click)
|
||||
SET_BOOL(pointer_follows_focus)
|
||||
SET_BOOL(pointer_follows_monitor)
|
||||
|
|
|
@ -101,6 +101,7 @@ void query_desktop(desktop_t *d, FILE *rsp)
|
|||
fprintf(rsp, "\"name\":\"%s\",", d->name);
|
||||
fprintf(rsp, "\"id\":%u,", d->id);
|
||||
fprintf(rsp, "\"layout\":\"%s\",", LAYOUT_STR(d->layout));
|
||||
fprintf(rsp, "\"userLayout\":\"%s\",", LAYOUT_STR(d->user_layout));
|
||||
fprintf(rsp, "\"windowGap\":%i,", d->window_gap);
|
||||
fprintf(rsp, "\"borderWidth\":%u,", d->border_width);
|
||||
fprintf(rsp, "\"focusedNodeId\":%u,", d->focus != NULL ? d->focus->id : 0);
|
||||
|
|
|
@ -314,6 +314,7 @@ desktop_t *restore_desktop(jsmntok_t **t, char *json)
|
|||
snprintf(d->name, (*t)->end - (*t)->start + 1, "%s", json + (*t)->start);
|
||||
RESTORE_UINT(id, &d->id)
|
||||
RESTORE_ANY(layout, &d->layout, parse_layout)
|
||||
RESTORE_ANY(userLayout, &d->user_layout, parse_layout)
|
||||
RESTORE_INT(windowGap, &d->window_gap)
|
||||
RESTORE_UINT(borderWidth, &d->border_width)
|
||||
} else if (keyeq("focusedNodeId", *t, json)) {
|
||||
|
|
|
@ -101,7 +101,7 @@ int print_report(FILE *stream)
|
|||
fprintf(stream, ":%c%s", c, d->name);
|
||||
}
|
||||
if (m->desk != NULL) {
|
||||
fprintf(stream, ":L%c", LAYOUT_CHR(ACTUAL_LAYOUT(m->desk)));
|
||||
fprintf(stream, ":L%c", LAYOUT_CHR(m->desk->layout));
|
||||
if (m->desk->focus != NULL) {
|
||||
node_t *n = m->desk->focus;
|
||||
if (n->client != NULL) {
|
||||
|
|
55
src/tree.c
55
src/tree.c
|
@ -46,8 +46,6 @@ void arrange(monitor_t *m, desktop_t *d)
|
|||
return;
|
||||
}
|
||||
|
||||
layout_t l = ACTUAL_LAYOUT(d);
|
||||
|
||||
xcb_rectangle_t rect = m->rectangle;
|
||||
|
||||
rect.x += m->padding.left + d->padding.left;
|
||||
|
@ -55,24 +53,24 @@ void arrange(monitor_t *m, desktop_t *d)
|
|||
rect.width -= m->padding.left + d->padding.left + d->padding.right + m->padding.right;
|
||||
rect.height -= m->padding.top + d->padding.top + d->padding.bottom + m->padding.bottom;
|
||||
|
||||
if (l == LAYOUT_MONOCLE) {
|
||||
if (d->layout == LAYOUT_MONOCLE) {
|
||||
rect.x += monocle_padding.left;
|
||||
rect.y += monocle_padding.top;
|
||||
rect.width -= monocle_padding.left + monocle_padding.right;
|
||||
rect.height -= monocle_padding.top + monocle_padding.bottom;
|
||||
}
|
||||
|
||||
if (!gapless_monocle || l != LAYOUT_MONOCLE) {
|
||||
if (!gapless_monocle || d->layout != LAYOUT_MONOCLE) {
|
||||
rect.x += d->window_gap;
|
||||
rect.y += d->window_gap;
|
||||
rect.width -= d->window_gap;
|
||||
rect.height -= d->window_gap;
|
||||
}
|
||||
|
||||
apply_layout(m, d, d->root, l, rect, rect);
|
||||
apply_layout(m, d, d->root, rect, rect);
|
||||
}
|
||||
|
||||
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
|
||||
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
|
||||
{
|
||||
if (n == NULL) {
|
||||
return;
|
||||
|
@ -91,7 +89,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectang
|
|||
}
|
||||
|
||||
unsigned int bw;
|
||||
if ((borderless_monocle && l == LAYOUT_MONOCLE && IS_TILED(n->client))
|
||||
if ((borderless_monocle && d->layout == LAYOUT_MONOCLE && IS_TILED(n->client))
|
||||
|| n->client->state == STATE_FULLSCREEN) {
|
||||
bw = 0;
|
||||
} else {
|
||||
|
@ -103,7 +101,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectang
|
|||
client_state_t s = n->client->state;
|
||||
/* tiled and pseudo-tiled clients */
|
||||
if (s == STATE_TILED || s == STATE_PSEUDO_TILED) {
|
||||
int wg = (gapless_monocle && l == LAYOUT_MONOCLE ? 0 : d->window_gap);
|
||||
int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
|
||||
r = rect;
|
||||
int bleed = wg + 2 * bw;
|
||||
r.width = (bleed < r.width ? r.width - bleed : 1);
|
||||
|
@ -143,7 +141,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectang
|
|||
xcb_rectangle_t first_rect;
|
||||
xcb_rectangle_t second_rect;
|
||||
|
||||
if (l == LAYOUT_MONOCLE || n->first_child->vacant || n->second_child->vacant) {
|
||||
if (d->layout == LAYOUT_MONOCLE || n->first_child->vacant || n->second_child->vacant) {
|
||||
first_rect = second_rect = rect;
|
||||
} else {
|
||||
unsigned int fence;
|
||||
|
@ -176,8 +174,8 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectang
|
|||
}
|
||||
}
|
||||
|
||||
apply_layout(m, d, n->first_child, l, first_rect, root_rect);
|
||||
apply_layout(m, d, n->second_child, l, second_rect, root_rect);
|
||||
apply_layout(m, d, n->first_child, first_rect, root_rect);
|
||||
apply_layout(m, d, n->second_child, second_rect, root_rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,7 +438,9 @@ void insert_receptacle(monitor_t *m, desktop_t *d, node_t *n)
|
|||
node_t *r = make_node(XCB_NONE);
|
||||
insert_node(m, d, r, n);
|
||||
|
||||
put_status(SBSC_MASK_REPORT);
|
||||
if (single_monocle && d->layout == LAYOUT_MONOCLE && tiled_count(d->root, true) > 1) {
|
||||
set_layout(m, d, d->user_layout, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool activate_node(monitor_t *m, desktop_t *d, node_t *n)
|
||||
|
@ -1321,6 +1321,10 @@ void remove_node(monitor_t *m, desktop_t *d, node_t *n)
|
|||
}
|
||||
free_node(n);
|
||||
|
||||
if (single_monocle && d->layout != LAYOUT_MONOCLE && tiled_count(d->root, true) <= 1) {
|
||||
set_layout(m, d, LAYOUT_MONOCLE, false);
|
||||
}
|
||||
|
||||
ewmh_update_client_list(false);
|
||||
ewmh_update_client_list(true);
|
||||
|
||||
|
@ -1430,6 +1434,13 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
|
|||
show_node(d1, n2);
|
||||
}
|
||||
|
||||
if (single_monocle) {
|
||||
layout_t l1 = tiled_count(d1->root, true) <= 1 ? LAYOUT_MONOCLE : d1->user_layout;
|
||||
layout_t l2 = tiled_count(d2->root, true) <= 1 ? LAYOUT_MONOCLE : d2->user_layout;
|
||||
set_layout(m1, d1, l1, false);
|
||||
set_layout(m2, d2, l2, false);
|
||||
}
|
||||
|
||||
if (n1_held_focus) {
|
||||
if (d1_was_focused) {
|
||||
if (follow) {
|
||||
|
@ -1526,6 +1537,14 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
|
|||
draw_border(ns, is_descendant(ns, ds->focus), (ms == mon));
|
||||
}
|
||||
} else {
|
||||
if (single_monocle) {
|
||||
if (ds->layout != LAYOUT_MONOCLE && tiled_count(ds->root, true) <= 1) {
|
||||
set_layout(ms, ds, LAYOUT_MONOCLE, false);
|
||||
}
|
||||
if (dd->layout == LAYOUT_MONOCLE && tiled_count(dd->root, true) > 1) {
|
||||
set_layout(md, dd, dd->user_layout, false);
|
||||
}
|
||||
}
|
||||
if (held_focus) {
|
||||
if (follow) {
|
||||
if (ds_was_focused) {
|
||||
|
@ -1725,6 +1744,8 @@ bool set_state(monitor_t *m, desktop_t *d, node_t *n, client_state_t s)
|
|||
|
||||
client_t *c = n->client;
|
||||
|
||||
bool was_tiled = IS_TILED(c);
|
||||
|
||||
c->last_state = c->state;
|
||||
c->state = s;
|
||||
|
||||
|
@ -1760,6 +1781,14 @@ bool set_state(monitor_t *m, desktop_t *d, node_t *n, client_state_t s)
|
|||
put_status(SBSC_MASK_REPORT);
|
||||
}
|
||||
|
||||
if (single_monocle && was_tiled != IS_TILED(c)) {
|
||||
if (was_tiled && d->layout != LAYOUT_MONOCLE && tiled_count(d->root, true) <= 1) {
|
||||
set_layout(m, d, LAYOUT_MONOCLE, false);
|
||||
} else if (!was_tiled && d->layout == LAYOUT_MONOCLE && tiled_count(d->root, true) > 1) {
|
||||
set_layout(m, d, d->user_layout, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2054,7 +2083,7 @@ xcb_rectangle_t get_rectangle(monitor_t *m, desktop_t *d, node_t *n)
|
|||
return c->tiled_rectangle;
|
||||
}
|
||||
} else {
|
||||
int wg = (d == NULL ? 0 : (gapless_monocle && IS_MONOCLE(d) ? 0 : d->window_gap));
|
||||
int wg = (d == NULL ? 0 : (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap));
|
||||
xcb_rectangle_t rect = n->rectangle;
|
||||
rect.width -= wg;
|
||||
rect.height -= wg;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#define MIN_HEIGHT 32
|
||||
|
||||
void arrange(monitor_t *m, desktop_t *d);
|
||||
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectangle_t rect, xcb_rectangle_t root_rect);
|
||||
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect);
|
||||
presel_t *make_presel(void);
|
||||
void set_ratio(node_t *n, double rat);
|
||||
void presel_dir(monitor_t *m, desktop_t *d, node_t *n, direction_t dir);
|
||||
|
|
|
@ -268,6 +268,7 @@ struct desktop_t {
|
|||
char name[SMALEN];
|
||||
uint32_t id;
|
||||
layout_t layout;
|
||||
layout_t user_layout;
|
||||
node_t *root;
|
||||
node_t *focus;
|
||||
desktop_t *prev;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "bspwm.h"
|
||||
#include "ewmh.h"
|
||||
#include "monitor.h"
|
||||
#include "desktop.h"
|
||||
#include "query.h"
|
||||
#include "rule.h"
|
||||
#include "settings.h"
|
||||
|
@ -165,6 +166,9 @@ bool manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
|
|||
|
||||
f = insert_node(m, d, n, f);
|
||||
clients_count++;
|
||||
if (single_monocle && d->layout == LAYOUT_MONOCLE && tiled_count(d->root, true) > 1) {
|
||||
set_layout(m, d, d->user_layout, false);
|
||||
}
|
||||
|
||||
n->vacant = false;
|
||||
|
||||
|
@ -293,7 +297,7 @@ void draw_presel_feedback(monitor_t *m, desktop_t *d, node_t *n)
|
|||
initialize_presel_feedback(n);
|
||||
}
|
||||
|
||||
int gap = gapless_monocle && IS_MONOCLE(d) ? 0 : d->window_gap;
|
||||
int gap = gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap;
|
||||
presel_t *p = n->presel;
|
||||
xcb_rectangle_t rect = n->rectangle;
|
||||
rect.x = rect.y = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue