Fix a few regressions, and add numerous minor cosmetic improvements.
handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[1], e->data.data32[0]);
handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[2], e->data.data32[0]);
} else if (e->type == ewmh->_NET_ACTIVE_WINDOW) {
- if (loc.desktop->focus->client->fullscreen && loc.desktop->focus != loc.node) {
- toggle_fullscreen(loc.monitor, loc.desktop->focus->client);
- arrange(loc.monitor, loc.desktop);
- }
+ if (loc.desktop->focus->client->fullscreen && loc.desktop->focus != loc.node)
+ toggle_fullscreen(loc.monitor, loc.desktop, loc.desktop->focus);
focus_node(loc.monitor, loc.desktop, loc.node);
}
}
bool fs = n->client->fullscreen;
if (action == XCB_EWMH_WM_STATE_TOGGLE
|| (fs && action == XCB_EWMH_WM_STATE_REMOVE)
- || (!fs && action == XCB_EWMH_WM_STATE_ADD)) {
- toggle_fullscreen(m, n->client);
- arrange(m, d);
- }
+ || (!fs && action == XCB_EWMH_WM_STATE_ADD))
+ toggle_fullscreen(m, d, n);
} else if (state == ewmh->_NET_WM_STATE_DEMANDS_ATTENTION) {
if (action == XCB_EWMH_WM_STATE_ADD)
set_urgency(m, d, n, true);
}
}
transfer_node(m, d, loc.monitor, loc.desktop, n);
- arrange(m, d);
- arrange(loc.monitor, loc.desktop);
frozen_pointer->monitor = loc.monitor;
frozen_pointer->desktop = loc.desktop;
}
update_floating_rectangle(frozen_pointer->client);
monitor_t *m = underlying_monitor(frozen_pointer->client);
- if (m != NULL && m != frozen_pointer->monitor) {
+ if (m != NULL && m != frozen_pointer->monitor)
transfer_node(frozen_pointer->monitor, frozen_pointer->desktop, m, m->desk, frozen_pointer->node);
- focus_node(m, m->desk, m->desk->focus);
- }
}
void ewmh_update_desktop_names(void)
{
char names[MAXLEN];
- monitor_t *m = mon_head;
unsigned int pos, i;
pos = i = 0;
- while (m != NULL) {
- desktop_t *d = m->desk_head;
-
- while (d != NULL && i < num_desktops) {
+ for (monitor_t *m = mon_head; m != NULL; m = m->next)
+ for (desktop_t *d = m->desk_head; d != NULL && i < num_desktops; d = d->next) {
for (unsigned int j = 0; j < strlen(d->name); j++)
names[pos + j] = d->name[j];
pos += strlen(d->name);
names[pos] = '\0';
- pos++;
- d = d->next;
- i++;
+ pos++, i++;
}
- m = m->next;
- }
-
if (i != num_desktops)
return;
-
pos--;
xcb_ewmh_set_desktop_names(ewmh, default_screen, pos, names);
if (parse_pointer_action(pac, &a))
grab_pointer(a);
}
+ return;
} else if (strcmp(cmd, "track_pointer") == 0) {
char *arg1 = strtok(NULL, TOK_SEP);
- if (arg1 == NULL)
- return;
char *arg2 = strtok(NULL, TOK_SEP);
- if (arg2 == NULL)
+ if (arg1 == NULL || arg2 == NULL)
return;
int root_x, root_y;
if (sscanf(arg1, "%i", &root_x) == 1 && sscanf(arg2, "%i", &root_y) == 1)
return;
} else if (strcmp(cmd, "ungrab_pointer") == 0) {
ungrab_pointer();
+ return;
} else if (strcmp(cmd, "layout") == 0) {
char *lyt = strtok(NULL, TOK_SEP);
if (lyt != NULL) {
}
} else if (strcmp(cmd, "toggle_fullscreen") == 0) {
if (mon->desk->focus != NULL)
- toggle_fullscreen(mon, mon->desk->focus->client);
+ toggle_fullscreen(mon, mon->desk, mon->desk->focus);
+ return;
} else if (strcmp(cmd, "toggle_floating") == 0) {
- split_mode = MODE_AUTOMATIC;
- toggle_floating(mon->desk->focus);
+ toggle_floating(mon->desk, mon->desk->focus);
} else if (strcmp(cmd, "toggle_locked") == 0) {
if (mon->desk->focus != NULL)
- toggle_locked(mon->desk->focus->client);
+ toggle_locked(mon, mon->desk, mon->desk->focus);
+ return;
} else if (strcmp(cmd, "toggle_visibility") == 0) {
toggle_visibility();
+ return;
} else if (strcmp(cmd, "pad") == 0) {
char *name = strtok(NULL, TOK_SEP);
if (name != NULL) {
}
return;
} else if (strcmp(cmd, "ratio") == 0) {
- char *value = strtok(NULL, TOK_SEP);
- if (value != NULL && mon->desk->focus != NULL)
- sscanf(value, "%lf", &mon->desk->focus->split_ratio);
+ char *value;
+ if (mon->desk->focus == NULL || (value = strtok(NULL, TOK_SEP)) == NULL ||
+ sscanf(value, "%lf", &mon->desk->focus->split_ratio) != 1)
+ return;
} else if (strcmp(cmd, "cancel") == 0) {
split_mode = MODE_AUTOMATIC;
window_draw_border(mon->desk->focus, true, true);
if (dir != NULL) {
fence_move_t m;
direction_t d;
- if (parse_fence_move(cmd, &m) && parse_direction(dir, &d)) {
+ if (parse_fence_move(cmd, &m) && parse_direction(dir, &d))
move_fence(mon->desk->focus, d, m);
- }
}
} else if (strcmp(cmd, "drop_to_monitor") == 0) {
char *dir = strtok(NULL, TOK_SEP);
else
m = ((mon->prev == NULL ? mon_tail : mon->prev));
transfer_node(mon, mon->desk, m, m->desk, mon->desk->focus);
- arrange(m, m->desk);
char *opt = strtok(NULL, TOK_SEP);
send_option_t o;
if (parse_send_option(opt, &o) && o == SEND_OPTION_FOLLOW)
focus_node(m, m->desk, m->desk->focus);
}
}
+ return;
} else if (strcmp(cmd, "send_to_monitor") == 0) {
char *name = strtok(NULL, TOK_SEP);
if (name != NULL) {
monitor_t *m = find_monitor(name);
if (m != NULL && m != mon) {
transfer_node(mon, mon->desk, m, m->desk, mon->desk->focus);
- arrange(m, m->desk);
char *opt = strtok(NULL, TOK_SEP);
send_option_t o;
if (parse_send_option(opt, &o) && o == SEND_OPTION_FOLLOW)
focus_node(m, m->desk, m->desk->focus);
}
}
+ return;
} else if (strcmp(cmd, "drop_to") == 0) {
char *dir = strtok(NULL, TOK_SEP);
if (dir != NULL) {
focus_node(mon, d, d->focus);
}
}
+ return;
} else if (strcmp(cmd, "send_to") == 0) {
char *name = strtok(NULL, TOK_SEP);
if (name != NULL) {
desktop_location_t loc;
if (locate_desktop(name, &loc)) {
transfer_node(mon, mon->desk, loc.monitor, loc.desktop, mon->desk->focus);
- if (mon != loc.monitor && loc.monitor->desk == loc.desktop)
- arrange(loc.monitor, loc.desktop);
char *opt = strtok(NULL, TOK_SEP);
send_option_t o;
if (parse_send_option(opt, &o) && o == SEND_OPTION_FOLLOW)
focus_node(loc.monitor, loc.desktop, loc.desktop->focus);
}
}
+ return;
} else if (strcmp(cmd, "rename_monitor") == 0) {
char *cur_name = strtok(NULL, TOK_SEP);
if (cur_name != NULL) {
desktop_hide(d);
transfer_desktop(mon, m, d);
desktop_show(mon->desk);
+ arrange(m, d);
if (o == SEND_OPTION_FOLLOW) {
- arrange(m, d);
focus_node(m, d, d->focus);
} else if (o == SEND_OPTION_DONT_FOLLOW) {
update_current();
+ put_status();
}
}
}
window_draw_border(n, true, true);
}
- if (mon != m || m->desk != d) {
- select_desktop(m, d);
- put_status();
- }
+ select_desktop(m, d);
if (n == NULL) {
ewmh_update_active_window();
void remove_node(desktop_t *d, node_t *n)
{
- if (d == NULL || n == NULL)
+ if (n == NULL)
return;
PRINTF("remove node %X\n", n->client->window);
void transfer_node(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd, node_t *n)
{
- if (n == NULL || (ms == md && dd == ds))
+ if (n == NULL || dd == ds)
return;
PRINTF("transfer node %X\n", n->client->window);
if (md->desk == dd)
stack(dd, n);
+ arrange(ms, ds);
+ arrange(md, dd);
+
if (ds == ms->desk || dd == md->desk)
update_current();
}
center_pointer(m);
ewmh_update_current_desktop();
+ put_status();
}
void select_desktop(monitor_t *m, desktop_t *d)
mon->desk = d;
ewmh_update_current_desktop();
+ put_status();
}
void cycle_monitor(cycle_dir_t dir)
&& r.y <= pt.y && pt.y < (r.y + r.height));
}
+xcb_rectangle_t get_rectangle(client_t *c)
+{
+ if (is_tiled(c))
+ return c->tiled_rectangle;
+ else
+ return c->floating_rectangle;
+}
+
void get_side_handle(client_t *c, direction_t dir, xcb_point_t *pt)
{
- xcb_rectangle_t rect = (is_tiled(c) ? c->tiled_rectangle : c->floating_rectangle);
+ xcb_rectangle_t rect = get_rectangle(c);
switch (dir) {
case DIR_RIGHT:
pt->x = rect.x + rect.width;
if (c->transient)
floating = true;
- node_t *birth = make_node();
- birth->client = c;
+ node_t *n = make_node();
+ n->client = c;
- insert_node(m, d, birth);
+ insert_node(m, d, n);
disable_shadow(c->window);
if (floating)
- toggle_floating(birth);
+ toggle_floating(d, n);
if (d->focus != NULL && d->focus->client->fullscreen)
- toggle_fullscreen(m, d->focus->client);
+ toggle_fullscreen(m, d, d->focus);
if (fullscreen)
- toggle_fullscreen(m, birth->client);
+ toggle_fullscreen(m, d, n);
if (is_tiled(c))
window_lower(c->window);
bool give_focus = takes_focus && (d == mon->desk || follow);
if (give_focus)
- focus_node(m, d, birth);
+ focus_node(m, d, n);
else if (takes_focus)
- pseudo_focus(d, birth);
+ pseudo_focus(d, n);
- xcb_rectangle_t *frect = &birth->client->floating_rectangle;
+ xcb_rectangle_t *frect = &n->client->floating_rectangle;
if (frect->x == 0 && frect->y == 0)
center(m->rectangle, frect);
- fit_monitor(m, birth->client);
+ fit_monitor(m, n->client);
arrange(m, d);
xcb_change_window_attributes(dpy, c->window, XCB_CW_EVENT_MASK, values);
num_clients++;
- ewmh_set_wm_desktop(birth, d);
+ ewmh_set_wm_desktop(n, d);
ewmh_update_client_list();
}
if (split_mode == MODE_AUTOMATIC || !focused_monitor || !focused_window) {
xcb_change_window_attributes(dpy, win, XCB_CW_BORDER_PIXEL, &border_color_pxl);
} else {
- xcb_rectangle_t actual_rectangle = (is_tiled(n->client) ? n->client->tiled_rectangle : n->client->floating_rectangle);
+ xcb_rectangle_t actual_rectangle = get_rectangle(n->client);
uint16_t width = actual_rectangle.width;
uint16_t height = actual_rectangle.height;
if (n == NULL)
return;
- PRINTF("kill window %X\n", n->client->window);
+ xcb_window_t win = n->client->window;
+ PRINTF("kill window %X\n", win);
- xcb_kill_client(dpy, n->client->window);
+ xcb_kill_client(dpy, win);
remove_node(d, n);
}
-void toggle_fullscreen(monitor_t *m, client_t *c)
+void toggle_fullscreen(monitor_t *m, desktop_t *d, node_t *n)
{
+ client_t *c = n->client;
+
PRINTF("toggle fullscreen %X\n", c->window);
if (c->fullscreen) {
c->fullscreen = false;
xcb_atom_t values[] = {XCB_NONE};
xcb_ewmh_set_wm_state(ewmh, c->window, LENGTH(values), values);
- if (is_tiled(c))
- window_lower(c->window);
+ xcb_rectangle_t rect = get_rectangle(c);
+ window_border_width(c->window, c->border_width);
+ window_move_resize(c->window, rect.x, rect.y, rect.width, rect.height);
+ window_draw_border(n, d->focus == n, mon == m);
+ stack(d, n);
} else {
c->fullscreen = true;
xcb_atom_t values[] = {ewmh->_NET_WM_STATE_FULLSCREEN};
xcb_ewmh_set_wm_state(ewmh, c->window, LENGTH(values), values);
window_raise(c->window);
window_border_width(c->window, 0);
- xcb_rectangle_t r = m->rectangle;
- window_move_resize(c->window, r.x, r.y, r.width, r.height);
+ xcb_rectangle_t rect = m->rectangle;
+ window_move_resize(c->window, rect.x, rect.y, rect.width, rect.height);
}
- update_current();
}
-void toggle_floating(node_t *n)
+void toggle_floating(desktop_t *d, node_t *n)
{
if (n == NULL || n->client->transient || n->client->fullscreen)
return;
PRINTF("toggle floating %X\n", n->client->window);
+ split_mode = MODE_AUTOMATIC;
client_t *c = n->client;
c->floating = !c->floating;
n->vacant = !n->vacant;
update_vacant_state(n->parent);
if (c->floating) {
- window_raise(c->window);
enable_shadow(c->window);
unrotate_brother(n);
} else {
- window_lower(c->window);
disable_shadow(c->window);
rotate_brother(n);
}
- update_current();
+ stack(d, n);
}
-void toggle_locked(client_t *c)
+void toggle_locked(monitor_t *m, desktop_t *d, node_t *n)
{
+ client_t *c = n->client;
+
PRINTF("toggle locked %X\n", c->window);
c->locked = !c->locked;
+ window_draw_border(n, d->focus == n, m == mon);
}
void set_urgency(monitor_t *m, desktop_t *d, node_t *n, bool value)
bool locate_window(xcb_window_t, window_location_t *);
bool locate_desktop(char *, desktop_location_t *);
bool is_inside(monitor_t *, xcb_point_t);
+xcb_rectangle_t get_rectangle(client_t *);
void get_side_handle(client_t *, direction_t, xcb_point_t *);
monitor_t *monitor_from_point(xcb_point_t);
monitor_t *underlying_monitor(client_t *);
void list_windows(char *);
void window_close(node_t *);
void window_kill(desktop_t *, node_t *);
-void toggle_fullscreen(monitor_t *, client_t *);
-void toggle_floating(node_t *);
-void toggle_locked(client_t *);
+void toggle_fullscreen(monitor_t *, desktop_t *, node_t *);
+void toggle_floating(desktop_t *, node_t *);
+void toggle_locked(monitor_t *, desktop_t *, node_t *);
void set_urgency(monitor_t *, desktop_t *, node_t *, bool);
void set_shadow(xcb_window_t, uint32_t);
void enable_shadow(xcb_window_t);