mirror of
https://github.com/vale981/bspwm
synced 2025-03-05 18:01:37 -05:00
Implement the pseudo-tiled window state
This commit is contained in:
parent
e0b6cd3cd4
commit
48e0043f84
14 changed files with 73 additions and 38 deletions
|
@ -444,6 +444,11 @@ floating
|
|||
Is above any tiled window and can be moved/resized freely\&. Although it doesn\(cqt occupy any tiling space, it is still part of the window tree\&.
|
||||
.RE
|
||||
.PP
|
||||
pseudo_tiled
|
||||
.RS 4
|
||||
Has a libre size while being centered in its tiling space\&.
|
||||
.RE
|
||||
.PP
|
||||
fullscreen
|
||||
.RS 4
|
||||
Fills its monitor rectangle, is above all the other windows and has no borders\&.
|
||||
|
@ -534,7 +539,7 @@ Set and change the splitting ratio of (or pull, or push) the edge located in the
|
|||
Rotate the tree holding the edge located in the given direction in relation to the selected window\&.
|
||||
.RE
|
||||
.PP
|
||||
\fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|locked|sticky|private[=on|off]
|
||||
\fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|pseudo_tiled|locked|sticky|private[=on|off]
|
||||
.RS 4
|
||||
Set or toggle the given state for the selected window\&.
|
||||
.RE
|
||||
|
@ -876,7 +881,7 @@ rule \fIOPTIONS\fR
|
|||
\fBOptions\fR
|
||||
.RS 4
|
||||
.PP
|
||||
\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name>|* [\fB\-o\fR|\fB\-\-one\-shot\fR] [desktop=DESKTOP_SEL|monitor=MONITOR_SEL] [(floating|fullscreen|locked|sticky|private|center|lower|follow|manage|focus)=(true|false)]
|
||||
\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name>|* [\fB\-o\fR|\fB\-\-one\-shot\fR] [desktop=DESKTOP_SEL|monitor=MONITOR_SEL] [(floating|fullscreen|pseudo_tiled|locked|sticky|private|center|lower|follow|manage|focus)=(true|false)]
|
||||
.RS 4
|
||||
Create a new rule\&.
|
||||
.RE
|
||||
|
|
|
@ -293,6 +293,9 @@ Window States
|
|||
floating::
|
||||
Is above any tiled window and can be moved/resized freely. Although it doesn't occupy any tiling space, it is still part of the window tree.
|
||||
|
||||
pseudo_tiled::
|
||||
Has a libre size while being centered in its tiling space.
|
||||
|
||||
fullscreen::
|
||||
Fills its monitor rectangle, is above all the other windows and has no borders.
|
||||
|
||||
|
@ -346,7 +349,7 @@ Options
|
|||
*-R*, *--rotate* 'DIR' '90|270|180'::
|
||||
Rotate the tree holding the edge located in the given direction in relation to the selected window.
|
||||
|
||||
*-t*, *--toggle* floating|fullscreen|locked|sticky|private[=on|off]::
|
||||
*-t*, *--toggle* floating|fullscreen|pseudo_tiled|locked|sticky|private[=on|off]::
|
||||
Set or toggle the given state for the selected window.
|
||||
|
||||
*-c*, *--close*::
|
||||
|
@ -538,7 +541,7 @@ rule 'OPTIONS'
|
|||
Options
|
||||
^^^^^^^
|
||||
|
||||
*-a*, *--add* <class_name>|<instance_name>|* [*-o*|*--one-shot*] [desktop=DESKTOP_SEL|monitor=MONITOR_SEL] [(floating|fullscreen|locked|sticky|private|center|lower|follow|manage|focus)=(true|false)]::
|
||||
*-a*, *--add* <class_name>|<instance_name>|* [*-o*|*--one-shot*] [desktop=DESKTOP_SEL|monitor=MONITOR_SEL] [(floating|fullscreen|pseudo_tiled|locked|sticky|private|center|lower|follow|manage|focus)=(true|false)]::
|
||||
Create a new rule.
|
||||
|
||||
*-r*, *--remove* ^<n>|head|tail|<class_name>|<instance_name>|*...::
|
||||
|
|
11
events.c
11
events.c
|
@ -120,6 +120,9 @@ void configure_request(xcb_generic_event_t *evt)
|
|||
evt.override_redirect = false;
|
||||
|
||||
xcb_send_event(dpy, false, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *) &evt);
|
||||
|
||||
if (loc.node->client->pseudo_tiled)
|
||||
arrange(loc.monitor, loc.desktop);
|
||||
} else {
|
||||
uint16_t mask = 0;
|
||||
uint32_t values[7];
|
||||
|
@ -170,8 +173,12 @@ void configure_request(xcb_generic_event_t *evt)
|
|||
|
||||
xcb_configure_window(dpy, e->window, mask, values);
|
||||
}
|
||||
if (is_managed)
|
||||
translate_client(monitor_from_client(loc.node->client), loc.monitor, loc.node->client);
|
||||
|
||||
if (is_managed) {
|
||||
monitor_t *m = monitor_from_client(loc.node->client);
|
||||
if (m != NULL && m != loc.monitor)
|
||||
transfer_node(loc.monitor, loc.desktop, loc.node, m, m->desk, m->desk->focus);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_notify(xcb_generic_event_t *evt)
|
||||
|
|
|
@ -83,3 +83,9 @@ double distance(xcb_point_t a, xcb_point_t b)
|
|||
{
|
||||
return hypot(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
void center_rectangle(xcb_rectangle_t *src, xcb_rectangle_t dst)
|
||||
{
|
||||
src->x = dst.x + (dst.width - src->width) / 2;
|
||||
src->y = dst.y + (dst.height - src->height) / 2;
|
||||
}
|
||||
|
|
|
@ -56,9 +56,9 @@
|
|||
#endif
|
||||
|
||||
void warn(char *fmt, ...);
|
||||
__attribute__((noreturn))
|
||||
void err(char *fmt, ...);
|
||||
bool get_color(char *col, xcb_window_t win, uint32_t *pxl);
|
||||
double distance(xcb_point_t a, xcb_point_t b);
|
||||
void center_rectangle(xcb_rectangle_t *src, xcb_rectangle_t dst);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -204,6 +204,9 @@ bool cmd_window(char **args, int num)
|
|||
if (streq("fullscreen", key)) {
|
||||
set_fullscreen(trg.node, (a == ALTER_SET ? b : !trg.node->client->fullscreen));
|
||||
dirty = true;
|
||||
} else if (streq("pseudo_tiled", key)) {
|
||||
set_pseudo_tiled(trg.node, (a == ALTER_SET ? b : !trg.node->client->pseudo_tiled));
|
||||
dirty = true;
|
||||
} else if (streq("floating", key)) {
|
||||
set_floating(trg.node, (a == ALTER_SET ? b : !trg.node->client->floating));
|
||||
dirty = true;
|
||||
|
|
24
pointer.c
24
pointer.c
|
@ -69,12 +69,12 @@ void grab_pointer(pointer_action_t pac)
|
|||
case ACTION_MOVE:
|
||||
case ACTION_RESIZE_SIDE:
|
||||
case ACTION_RESIZE_CORNER:
|
||||
if (is_tiled(c)) {
|
||||
frozen_pointer->rectangle = c->tiled_rectangle;
|
||||
frozen_pointer->is_tiled = true;
|
||||
} else if (is_floating(c)) {
|
||||
if (is_floating(c)) {
|
||||
frozen_pointer->rectangle = c->floating_rectangle;
|
||||
frozen_pointer->is_tiled = false;
|
||||
} else if (is_tiled(c)) {
|
||||
frozen_pointer->rectangle = c->tiled_rectangle;
|
||||
frozen_pointer->is_tiled = true;
|
||||
} else {
|
||||
frozen_pointer->action = ACTION_NONE;
|
||||
return;
|
||||
|
@ -254,7 +254,7 @@ void track_pointer(int root_x, int root_y)
|
|||
sr = MIN(1, sr);
|
||||
horizontal_fence->split_ratio = sr;
|
||||
}
|
||||
arrange(mon, mon->desk);
|
||||
arrange(m, d);
|
||||
} else {
|
||||
if (pac == ACTION_RESIZE_SIDE) {
|
||||
switch (frozen_pointer->side) {
|
||||
|
@ -283,11 +283,6 @@ void track_pointer(int root_x, int root_y)
|
|||
h = rect.height;
|
||||
break;
|
||||
}
|
||||
width = MAX(1, w);
|
||||
height = MAX(1, h);
|
||||
window_move_resize(win, x, y, width, height);
|
||||
c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
|
||||
window_draw_border(n, d->focus == n, mon == m);
|
||||
} else if (pac == ACTION_RESIZE_CORNER) {
|
||||
switch (frozen_pointer->corner) {
|
||||
case CORNER_TOP_LEFT:
|
||||
|
@ -315,12 +310,11 @@ void track_pointer(int root_x, int root_y)
|
|||
h = rect.height + delta_y;
|
||||
break;
|
||||
}
|
||||
width = MAX(1, w);
|
||||
height = MAX(1, h);
|
||||
window_move_resize(win, x, y, width, height);
|
||||
c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
|
||||
window_draw_border(n, d->focus == n, mon == m);
|
||||
}
|
||||
width = MAX(1, w);
|
||||
height = MAX(1, h);
|
||||
window_move_resize(win, x, y, width, height);
|
||||
c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
|
||||
}
|
||||
break;
|
||||
case ACTION_FOCUS:
|
||||
|
|
2
query.c
2
query.c
|
@ -90,7 +90,7 @@ void query_tree(desktop_t *d, node_t *n, char *rsp, unsigned int depth)
|
|||
|
||||
if (is_leaf(n)) {
|
||||
client_t *c = n->client;
|
||||
snprintf(line, sizeof(line), "%c %s 0x%X %u %ux%u%+i%+i %c %c%c%c%c%c%c%c%c", (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), c->class_name, c->window, c->border_width, c->floating_rectangle.width, c->floating_rectangle.height, c->floating_rectangle.x, c->floating_rectangle.y, (n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))), (c->floating ? 'f' : '-'), (c->transient ? 't' : '-'), (c->fullscreen ? 'F' : '-'), (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->private ? 'i' : '-'), (n->split_mode ? 'p' : '-'));
|
||||
snprintf(line, sizeof(line), "%c %s 0x%X %u %ux%u%+i%+i %c %c%c%c%c%c%c%c%c%c", (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), c->class_name, c->window, c->border_width, c->floating_rectangle.width, c->floating_rectangle.height, c->floating_rectangle.x, c->floating_rectangle.y, (n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))), (c->floating ? 'f' : '-'), (c->pseudo_tiled ? 'd' : '-'), (c->transient ? 't' : '-'), (c->fullscreen ? 'F' : '-'), (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->private ? 'i' : '-'), (n->split_mode ? 'p' : '-'));
|
||||
} else {
|
||||
snprintf(line, sizeof(line), "%c %c %lf", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'), (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), n->split_ratio);
|
||||
}
|
||||
|
|
|
@ -134,9 +134,10 @@ void restore_tree(char *file_path)
|
|||
} else {
|
||||
client_t *c = make_client(XCB_NONE);
|
||||
num_clients++;
|
||||
char floating, transient, fullscreen, urgent, locked, sticky, private, sd, sm, end = 0;
|
||||
sscanf(line + level, "%c %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c %c", &br, c->class_name, &c->window, &c->border_width, &c->floating_rectangle.width, &c->floating_rectangle.height, &c->floating_rectangle.x, &c->floating_rectangle.y, &sd, &floating, &transient, &fullscreen, &urgent, &locked, &sticky, &private, &sm, &end);
|
||||
char floating, pseudo_tiled, transient, fullscreen, urgent, locked, sticky, private, sd, sm, end = 0;
|
||||
sscanf(line + level, "%c %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c%c %c", &br, c->class_name, &c->window, &c->border_width, &c->floating_rectangle.width, &c->floating_rectangle.height, &c->floating_rectangle.x, &c->floating_rectangle.y, &sd, &floating, &pseudo_tiled, &transient, &fullscreen, &urgent, &locked, &sticky, &private, &sm, &end);
|
||||
c->floating = (floating == '-' ? false : true);
|
||||
c->pseudo_tiled = (pseudo_tiled == '-' ? false : true);
|
||||
c->transient = (transient == '-' ? false : true);
|
||||
c->fullscreen = (fullscreen == '-' ? false : true);
|
||||
c->urgent = (urgent == '-' ? false : true);
|
||||
|
|
1
rule.c
1
rule.c
|
@ -276,6 +276,7 @@ void parse_key_value(char *key, char *value, rule_consequence_t *csq)
|
|||
#define SETCSQ(name) \
|
||||
else if (streq(#name, key)) \
|
||||
csq->name = v;
|
||||
SETCSQ(pseudo_tiled)
|
||||
SETCSQ(fullscreen)
|
||||
SETCSQ(locked)
|
||||
SETCSQ(sticky)
|
||||
|
|
27
tree.c
27
tree.c
|
@ -70,17 +70,18 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
|
|||
xcb_rectangle_t r;
|
||||
if (!n->client->fullscreen) {
|
||||
if (!n->client->floating) {
|
||||
/* tiled clients */
|
||||
if (d->layout == LAYOUT_TILED)
|
||||
if (n->client->pseudo_tiled) {
|
||||
/* pseudo-tiled clients */
|
||||
r = n->client->floating_rectangle;
|
||||
center_rectangle(&r, rect);
|
||||
} else {
|
||||
/* tiled clients */
|
||||
r = rect;
|
||||
else if (d->layout == LAYOUT_MONOCLE)
|
||||
r = root_rect;
|
||||
else
|
||||
return;
|
||||
int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
|
||||
int bleed = wg + 2 * n->client->border_width;
|
||||
r.width = (bleed < r.width ? r.width - bleed : 1);
|
||||
r.height = (bleed < r.height ? r.height - bleed : 1);
|
||||
int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
|
||||
int bleed = wg + 2 * n->client->border_width;
|
||||
r.width = (bleed < r.width ? r.width - bleed : 1);
|
||||
r.height = (bleed < r.height ? r.height - bleed : 1);
|
||||
}
|
||||
n->client->tiled_rectangle = r;
|
||||
} else {
|
||||
/* floating clients */
|
||||
|
@ -99,7 +100,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
|
|||
xcb_rectangle_t first_rect;
|
||||
xcb_rectangle_t second_rect;
|
||||
|
||||
if (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;
|
||||
|
@ -360,8 +361,8 @@ client_t *make_client(xcb_window_t win)
|
|||
snprintf(c->class_name, sizeof(c->class_name), "%s", MISSING_VALUE);
|
||||
c->border_width = BORDER_WIDTH;
|
||||
c->window = win;
|
||||
c->floating = c->transient = c->fullscreen = c->locked = c->sticky = c->urgent = false;
|
||||
c->private = c->icccm_focus = false;
|
||||
c->pseudo_tiled = c->floating = c->transient = c->fullscreen = false;
|
||||
c->locked = c->sticky = c->urgent = c->private = c->icccm_focus = false;
|
||||
xcb_icccm_get_wm_protocols_reply_t protocols;
|
||||
if (xcb_icccm_get_wm_protocols_reply(dpy, xcb_icccm_get_wm_protocols(dpy, win, ewmh->WM_PROTOCOLS), &protocols, NULL) == 1) {
|
||||
if (has_proto(WM_TAKE_FOCUS, &protocols))
|
||||
|
|
2
types.h
2
types.h
|
@ -155,6 +155,7 @@ typedef struct {
|
|||
xcb_window_t window;
|
||||
char class_name[SMALEN];
|
||||
unsigned int border_width;
|
||||
bool pseudo_tiled;
|
||||
bool floating;
|
||||
bool transient; /* transient window are always floating */
|
||||
bool fullscreen;
|
||||
|
@ -260,6 +261,7 @@ typedef struct {
|
|||
char instance_name[SMALEN];
|
||||
char desktop_desc[MAXLEN];
|
||||
char monitor_desc[MAXLEN];
|
||||
bool pseudo_tiled;
|
||||
bool floating;
|
||||
bool transient;
|
||||
bool fullscreen;
|
||||
|
|
11
window.c
11
window.c
|
@ -118,6 +118,7 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
|
|||
insert_node(m, d, n, d->focus);
|
||||
|
||||
disable_floating_atom(c->window);
|
||||
set_pseudo_tiled(n, csq->pseudo_tiled);
|
||||
set_floating(n, csq->floating);
|
||||
set_locked(m, d, n, csq->locked);
|
||||
set_sticky(m, d, n, csq->sticky);
|
||||
|
@ -360,6 +361,16 @@ void set_fullscreen(node_t *n, bool value)
|
|||
stack(n, STACK_ABOVE);
|
||||
}
|
||||
|
||||
void set_pseudo_tiled(node_t *n, bool value)
|
||||
{
|
||||
if (n == NULL || n->client->transient || n->client->pseudo_tiled == value)
|
||||
return;
|
||||
|
||||
PRINTF("pseudo-tiled %X: %s\n", n->client->window, BOOLSTR(value));
|
||||
|
||||
n->client->pseudo_tiled = value;
|
||||
}
|
||||
|
||||
void set_floating(node_t *n, bool value)
|
||||
{
|
||||
if (n == NULL || n->client->transient || n->client->fullscreen || n->client->floating == value)
|
||||
|
|
1
window.h
1
window.h
|
@ -43,6 +43,7 @@ void adopt_orphans(void);
|
|||
void window_close(node_t *n);
|
||||
void window_kill(monitor_t *m, desktop_t *d, node_t *n);
|
||||
void set_fullscreen(node_t *n, bool value);
|
||||
void set_pseudo_tiled(node_t *n, bool value);
|
||||
void set_floating(node_t *n, bool value);
|
||||
void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value);
|
||||
void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value);
|
||||
|
|
Loading…
Add table
Reference in a new issue