X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=types.c;h=96a389186019babb13baaced8cfca306392ac281;hb=cc4492d9ca51c4291fb5e4c59cfa80b7070f93c7;hp=67328f0e9b88aeaf3ed085b75e34fa5ca2c92a00;hpb=c0970551e53e24932c9db7c36f8b3ca12228cc09;p=bspwm.git diff --git a/types.c b/types.c index 67328f0..96a3891 100644 --- a/types.c +++ b/types.c @@ -15,23 +15,21 @@ node_t *make_node(void) node_t *n = malloc(sizeof(node_t)); n->parent = n->first_child = n->second_child = NULL; n->split_ratio = split_ratio; + n->split_mode = MODE_AUTOMATIC; n->split_type = TYPE_VERTICAL; - n->birth_rotation = ROTATE_IDENTITY; + n->birth_rotation = 0; n->client = NULL; n->vacant = false; return n; } -monitor_t *make_monitor(xcb_rectangle_t *rect) +monitor_t *make_monitor(xcb_rectangle_t rect) { monitor_t *m = malloc(sizeof(monitor_t)); snprintf(m->name, sizeof(m->name), "%s%02d", DEFAULT_MON_NAME, ++monitor_uid); m->prev = m->next = NULL; m->desk = m->last_desk = NULL; - if (rect != NULL) - m->rectangle = *rect; - else - warn("no rectangle was given for monitor '%s'\n", m->name); + m->rectangle = rect; m->top_padding = m->right_padding = m->bottom_padding = m->left_padding = 0; m->wired = true; return m; @@ -40,7 +38,7 @@ monitor_t *make_monitor(xcb_rectangle_t *rect) monitor_t *find_monitor(char *name) { for (monitor_t *m = mon_head; m != NULL; m = m->next) - if (strcmp(m->name, name) == 0) + if (streq(m->name, name)) return m; return NULL; } @@ -53,7 +51,7 @@ monitor_t *get_monitor_by_id(xcb_randr_output_t id) return NULL; } -monitor_t *add_monitor(xcb_rectangle_t *rect) +monitor_t *add_monitor(xcb_rectangle_t rect) { monitor_t *m = make_monitor(rect); if (mon == NULL) { @@ -85,8 +83,17 @@ void remove_monitor(monitor_t *m) mon_tail = prev; if (last_mon == m) last_mon = NULL; - if (mon == m) - mon = (last_mon == NULL ? (prev == NULL ? next : prev) : last_mon); + if (pri_mon == m) + pri_mon = NULL; + if (mon == m) { + monitor_t *mm = (last_mon == NULL ? (prev == NULL ? next : prev) : last_mon); + if (mm != NULL) { + focus_node(mm, mm->desk, mm->desk->focus); + last_mon = NULL; + } else { + mon = NULL; + } + } free(m); num_monitors--; put_status(); @@ -94,23 +101,31 @@ void remove_monitor(monitor_t *m) void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d) { + if (ms == md) + return; + desktop_t *dd = ms->desk; unlink_desktop(ms, d); insert_desktop(md, d); + if (d == dd) { if (ms->desk != NULL) desktop_show(ms->desk); if (md->desk != d) desktop_hide(d); } + for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) fit_monitor(md, n->client); arrange(md, d); if (d != dd && md->desk == d) { desktop_show(d); } - put_status(); + + ewmh_update_wm_desktops(); ewmh_update_desktop_names(); + ewmh_update_current_desktop(); + put_status(); } void merge_monitors(monitor_t *ms, monitor_t *md) @@ -125,6 +140,45 @@ void merge_monitors(monitor_t *ms, monitor_t *md) } } +void swap_monitors(monitor_t *m1, monitor_t *m2) +{ + if (m1 == NULL || m2 == NULL || m1 == m2) + return; + + if (mon_head == m1) + mon_head = m2; + else if (mon_head == m2) + mon_head = m1; + if (mon_tail == m1) + mon_tail = m2; + else if (mon_tail == m2) + mon_tail = m1; + + monitor_t *p1 = m1->prev; + monitor_t *n1 = m1->next; + monitor_t *p2 = m2->prev; + monitor_t *n2 = m2->next; + + if (p1 != NULL && p1 != m2) + p1->next = m2; + if (n1 != NULL && n1 != m2) + n1->prev = m2; + if (p2 != NULL && p2 != m1) + p2->next = m1; + if (n2 != NULL && n2 != m1) + n2->prev = m1; + + m1->prev = p2 == m1 ? m2 : p2; + m1->next = n2 == m1 ? m2 : n2; + m2->prev = p1 == m2 ? m1 : p1; + m2->next = n1 == m2 ? m1 : n1; + + ewmh_update_wm_desktops(); + ewmh_update_desktop_names(); + ewmh_update_current_desktop(); + put_status(); +} + desktop_t *make_desktop(const char *name) { desktop_t *d = malloc(sizeof(desktop_t)); @@ -136,6 +190,7 @@ desktop_t *make_desktop(const char *name) d->prev = d->next = NULL; d->root = d->focus = NULL; d->history = make_focus_history(); + d->window_gap = WINDOW_GAP; return d; } @@ -193,7 +248,6 @@ void remove_desktop(monitor_t *m, desktop_t *d) { PRINTF("remove desktop %s\n", d->name); - prune_rules(d); unlink_desktop(m, d); empty_desktop(d); free(d); @@ -203,14 +257,59 @@ void remove_desktop(monitor_t *m, desktop_t *d) put_status(); } +void swap_desktops(monitor_t *m, desktop_t *d1, desktop_t *d2) +{ + if (d1 == NULL || d2 == NULL || d1 == d2) + return; + + if (m->desk_head == d1) + m->desk_head = d2; + else if (m->desk_head == d2) + m->desk_head = d1; + if (m->desk_tail == d1) + m->desk_tail = d2; + else if (m->desk_tail == d2) + m->desk_tail = d1; + + desktop_t *p1 = d1->prev; + desktop_t *n1 = d1->next; + desktop_t *p2 = d2->prev; + desktop_t *n2 = d2->next; + + if (p1 != NULL && p1 != d2) + p1->next = d2; + if (n1 != NULL && n1 != d2) + n1->prev = d2; + if (p2 != NULL && p2 != d1) + p2->next = d1; + if (n2 != NULL && n2 != d1) + n2->prev = d1; + + d1->prev = p2 == d1 ? d2 : p2; + d1->next = n2 == d1 ? d2 : n2; + d2->prev = p1 == d2 ? d1 : p1; + d2->next = n1 == d2 ? d1 : n1; + + ewmh_update_wm_desktops(); + ewmh_update_desktop_names(); + ewmh_update_current_desktop(); + put_status(); +} + client_t *make_client(xcb_window_t win) { client_t *c = malloc(sizeof(client_t)); strncpy(c->class_name, MISSING_VALUE, sizeof(c->class_name)); - c->uid = ++client_uid; c->border_width = border_width; c->window = win; c->floating = c->transient = c->fullscreen = c->locked = c->urgent = false; + 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)) + c->icccm_focus = true; + xcb_icccm_get_wm_protocols_reply_wipe(&protocols); + } return c; } @@ -220,8 +319,10 @@ rule_t *make_rule(void) r->uid = ++rule_uid; r->effect.floating = false; r->effect.follow = false; - r->effect.monitor = NULL; - r->effect.desktop = NULL; + r->effect.focus = false; + r->effect.unmanage = false; + r->one_shot = false; + r->effect.desc[0] = '\0'; r->prev = NULL; r->next = NULL; return r; @@ -329,3 +430,27 @@ node_t *history_get(focus_history_t *f, int i) else return a->node; } + +node_t *history_last(focus_history_t *f, node_t *n, client_select_t sel) +{ + for (node_list_t *a = f->head; a != NULL; a = a->next) { + if (!a->latest || a->node == n || !node_matches(n, a->node, sel)) + continue; + return a->node; + } + return NULL; +} + +int history_rank(focus_history_t *f, node_t *n) +{ + int i = 0; + node_list_t *a = f->head; + while (a != NULL && (!a->latest || a->node != n)) { + a = a->next; + i++; + } + if (a == NULL) + return -1; + else + return i; +}