From c989aa7efc698a8e4024c8c7b2e729e67935994f Mon Sep 17 00:00:00 2001 From: Bastien Dejean Date: Sun, 27 Oct 2013 11:25:34 +0100 Subject: [PATCH] Merge translate_position and translate_client - Expand `underlying_monitor` into `monitor_from_client` to avoid passing a NULL pointer to `translate_client`. - Remove the `fit_monitor` setting (use the `--center` rule effect instead). - Don't remap a window in it's last location (node invisibility would be the proper way to do this). - Call `translate_client` after configure requests. --- Sourcedeps | 2 +- contrib/bash_completion | 2 +- contrib/zsh_completion | 2 +- desktop.c | 6 +-- doc/bspwm.1 | 11 ++--- doc/bspwm.1.txt | 5 +-- events.c | 2 + messages.c | 4 +- monitor.c | 98 +++++++++++++++++++++-------------------- monitor.h | 6 ++- pointer.c | 1 + rule.c | 7 ++- rule.h | 2 +- settings.c | 1 - settings.h | 2 - tree.c | 6 +-- types.h | 3 +- window.c | 57 ++++++++---------------- window.h | 4 +- 19 files changed, 101 insertions(+), 120 deletions(-) diff --git a/Sourcedeps b/Sourcedeps index 60f87d8..10dfd82 100644 --- a/Sourcedeps +++ b/Sourcedeps @@ -7,7 +7,7 @@ helpers.o: helpers.c bspwm.h helpers.h types.h history.o: history.c bspwm.h helpers.h query.h tree.h types.h messages.o: messages.c bspwm.h desktop.h ewmh.h helpers.h history.h messages.h monitor.h pointer.h query.h restore.h rule.h settings.h tree.h types.h window.h monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h tree.h types.h window.h -pointer.o: pointer.c bspwm.h helpers.h pointer.h query.h settings.h stack.h tree.h types.h window.h +pointer.o: pointer.c bspwm.h helpers.h monitor.h pointer.h query.h settings.h stack.h tree.h types.h window.h query.o: query.c bspwm.h desktop.h helpers.h history.h messages.h monitor.h query.h tree.h types.h restore.o: restore.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h restore.h settings.h stack.h tree.h types.h window.h rule.o: rule.c bspwm.h ewmh.h helpers.h messages.h query.h rule.h types.h window.h diff --git a/contrib/bash_completion b/contrib/bash_completion index 777134d..64b29d4 100644 --- a/contrib/bash_completion +++ b/contrib/bash_completion @@ -1,7 +1,7 @@ _bspc() { local commands='window desktop monitor query pointer rule restore control config quit' - local settings='focused_border_color active_border_color normal_border_color presel_border_color focused_locked_border_color active_locked_border_color normal_locked_border_color focused_sticky_border_color normal_sticky_border_color focused_private_border_color active_private_border_color normal_private_border_color urgent_border_color focused_frame_opacity active_frame_opacity normal_frame_opacity border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio growth_factor borderless_monocle gapless_monocle focus_follows_pointer pointer_follows_monitor apply_floating_atom auto_alternate auto_cancel history_aware_focus ignore_ewmh_focus fit_monitor' + local settings='focused_border_color active_border_color normal_border_color presel_border_color focused_locked_border_color active_locked_border_color normal_locked_border_color focused_sticky_border_color normal_sticky_border_color focused_private_border_color active_private_border_color normal_private_border_color urgent_border_color focused_frame_opacity active_frame_opacity normal_frame_opacity border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio growth_factor borderless_monocle gapless_monocle focus_follows_pointer pointer_follows_monitor apply_floating_atom auto_alternate auto_cancel history_aware_focus ignore_ewmh_focus' COMPREPLY=() diff --git a/contrib/zsh_completion b/contrib/zsh_completion index d0e5c66..cbd2eef 100644 --- a/contrib/zsh_completion +++ b/contrib/zsh_completion @@ -3,7 +3,7 @@ _bspc() { local -a commands settings commands=('window' 'desktop' 'monitor' 'query' 'pointer' 'rule' 'restore' 'control' 'config' 'quit') - settings=('focused_border_color' 'active_border_color' 'normal_border_color' 'presel_border_color' 'focused_locked_border_color' 'active_locked_border_color' 'normal_locked_border_color' 'focused_sticky_border_color' 'normal_sticky_border_color' 'focused_private_border_color' 'active_private_border_color' 'normal_private_border_color' 'urgent_border_color' 'focused_frame_opacity' 'active_frame_opacity' 'normal_frame_opacity' 'border_width' 'window_gap' 'top_padding' 'right_padding' 'bottom_padding' 'left_padding' 'split_ratio' 'growth_factor' 'borderless_monocle' 'gapless_monocle' 'focus_follows_pointer' 'pointer_follows_monitor' 'apply_floating_atom' 'auto_alternate' 'auto_cancel' 'history_aware_focus' 'ignore_ewmh_focus' 'fit_monitor') + settings=('focused_border_color' 'active_border_color' 'normal_border_color' 'presel_border_color' 'focused_locked_border_color' 'active_locked_border_color' 'normal_locked_border_color' 'focused_sticky_border_color' 'normal_sticky_border_color' 'focused_private_border_color' 'active_private_border_color' 'normal_private_border_color' 'urgent_border_color' 'focused_frame_opacity' 'active_frame_opacity' 'normal_frame_opacity' 'border_width' 'window_gap' 'top_padding' 'right_padding' 'bottom_padding' 'left_padding' 'split_ratio' 'growth_factor' 'borderless_monocle' 'gapless_monocle' 'focus_follows_pointer' 'pointer_follows_monitor' 'apply_floating_atom' 'auto_alternate' 'auto_cancel' 'history_aware_focus' 'ignore_ewmh_focus') if (( CURRENT == 2 )) ; then _values 'command' "$commands[@]" elif (( CURRENT == 3 )) ; then diff --git a/desktop.c b/desktop.c index 072f09a..87f2f9f 100644 --- a/desktop.c +++ b/desktop.c @@ -93,7 +93,7 @@ void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d) } for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) - translate_position(ms, md, n); + translate_client(ms, md, n->client); arrange(md, d); @@ -252,9 +252,9 @@ void swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2) if (m1 != m2) { for (node_t *n = first_extrema(d1->root); n != NULL; n = next_leaf(n, d1->root)) - translate_position(m1, m2, n); + translate_client(m1, m2, n->client); for (node_t *n = first_extrema(d2->root); n != NULL; n = next_leaf(n, d2->root)) - translate_position(m2, m1, n); + translate_client(m2, m1, n->client); history_swap_desktops(m1, d1, m2, d2); arrange(m1, d2); arrange(m2, d1); diff --git a/doc/bspwm.1 b/doc/bspwm.1 index d37c4fe..4b003e7 100644 --- a/doc/bspwm.1 +++ b/doc/bspwm.1 @@ -2,12 +2,12 @@ .\" Title: bspwm .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 10/26/2013 +.\" Date: 10/27/2013 .\" Manual: Bspwm Manual .\" Source: Bspwm 0.8.6 .\" Language: English .\" -.TH "BSPWM" "1" "10/26/2013" "Bspwm 0\&.8\&.6" "Bspwm Manual" +.TH "BSPWM" "1" "10/27/2013" "Bspwm 0\&.8\&.6" "Bspwm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -850,7 +850,7 @@ rule \fIOPTIONS\fR \fBOptions\fR .RS 4 .PP -\fB\-a\fR, \fB\-\-add\fR | [\-d \fIDESKTOP_SEL\fR [\-\-follow]] [\-\-floating] [\-\-fullscreen] [\-\-locked] [\-\-sticky] [\-\-focus] [\-\-frame] [\-\-private] [\-\-unmanage] [\-\-one\-shot] +\fB\-a\fR, \fB\-\-add\fR | [\-d \fIDESKTOP_SEL\fR [\-\-follow]] [\-\-floating] [\-\-fullscreen] [\-\-locked] [\-\-sticky] [\-\-focus] [\-\-frame] [\-\-private] [\-\-center] [\-\-unmanage] [\-\-one\-shot] .RS 4 Create a new rule\&. .RE @@ -1053,11 +1053,6 @@ atom of each window according to its floating state\&. .RS 4 Ignore EWMH requests to focus a window\&. .RE -.PP -\fIfit_monitor\fR -.RS 4 -Keep floating windows inside their monitor\&. -.RE .SS "Monitor Settings" .PP \fItop_padding\fR, \fIright_padding\fR, \fIbottom_padding\fR, \fIleft_padding\fR diff --git a/doc/bspwm.1.txt b/doc/bspwm.1.txt index b767d5b..a468043 100644 --- a/doc/bspwm.1.txt +++ b/doc/bspwm.1.txt @@ -519,7 +519,7 @@ rule 'OPTIONS' Options ^^^^^^^ -*-a*, *--add* | [-d 'DESKTOP_SEL' [--follow]] [--floating] [--fullscreen] [--locked] [--sticky] [--focus] [--frame] [--private] [--unmanage] [--one-shot]:: +*-a*, *--add* | [-d 'DESKTOP_SEL' [--follow]] [--floating] [--fullscreen] [--locked] [--sticky] [--focus] [--frame] [--private] [--center] [--unmanage] [--one-shot]:: Create a new rule. *-r*, *--remove* |^|tail|head...:: @@ -639,9 +639,6 @@ Global Settings 'ignore_ewmh_focus':: Ignore EWMH requests to focus a window. -'fit_monitor':: - Keep floating windows inside their monitor. - Monitor Settings ~~~~~~~~~~~~~~~~ diff --git a/events.c b/events.c index df29386..9106cda 100644 --- a/events.c +++ b/events.c @@ -173,6 +173,8 @@ 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); } void destroy_notify(xcb_generic_event_t *evt) diff --git a/messages.c b/messages.c index 0e1035d..3e3f100 100644 --- a/messages.c +++ b/messages.c @@ -637,6 +637,8 @@ bool cmd_rule(char **args, int num, char *rsp) rule->effect.frame = true; } else if (streq("--private", *args)) { rule->effect.private = true; + } else if (streq("--center", *args)) { + rule->effect.center = true; } else if (streq("--unmanage", *args)) { rule->effect.unmanage = true; } else if (streq("--one-shot", *args)) { @@ -931,7 +933,6 @@ bool set_setting(coordinates_t loc, char *name, char *value) SETBOOL(auto_cancel) SETBOOL(history_aware_focus) SETBOOL(ignore_ewmh_focus) - SETBOOL(fit_monitor) #undef SETBOOL } else { return false; @@ -1005,7 +1006,6 @@ bool get_setting(coordinates_t loc, char *name, char* rsp) GETBOOL(auto_cancel) GETBOOL(history_aware_focus) GETBOOL(ignore_ewmh_focus) - GETBOOL(fit_monitor) #undef GETBOOL else return false; diff --git a/monitor.c b/monitor.c index e1315ca..178b293 100644 --- a/monitor.c +++ b/monitor.c @@ -71,60 +71,27 @@ monitor_t *get_monitor_by_id(xcb_randr_output_t id) return NULL; } -void translate_position(monitor_t *ms, monitor_t *md, node_t *n) +void translate_client(monitor_t *ms, monitor_t *md, client_t *c) { - if (frozen_pointer->action != ACTION_NONE) + if (frozen_pointer->action != ACTION_NONE || ms == md) return; - xcb_rectangle_t a = ms->rectangle; - xcb_rectangle_t b = md->rectangle; - xcb_rectangle_t *r = &n->client->floating_rectangle; + int dx_s = c->floating_rectangle.x - ms->rectangle.x; + int dy_s = c->floating_rectangle.y - ms->rectangle.y; - if (ms != md) { - double w = b.width; - double h = b.height; - int dx = (r->x - a.x) * (w / a.width); - int dy = (r->y - a.y) * (h / a.height); - r->x = b.x + dx; - r->y = b.y + dy; - } + int nume_x = dx_s * (md->rectangle.width - c->floating_rectangle.width); + int nume_y = dy_s * (md->rectangle.height - c->floating_rectangle.height); - if (fit_monitor) { - if (r->x <= b.x || (r->x + r->width) >= (b.x + b.width)) { - if (r->width >= b.width) - r->x = b.x; - else - r->x = b.x + (b.width - r->width) / 2; - } - if (r->y <= b.y || (r->y + r->height) >= (b.y + b.height)) { - if (r->height >= b.height) - r->y = b.y; - else - r->y = b.y + (b.height - r->height) / 2; - } - } + int deno_x = ms->rectangle.width - c->floating_rectangle.width; + int deno_y = ms->rectangle.height - c->floating_rectangle.height; + + int dx_d = (deno_x == 0 ? 0 : nume_x / deno_x); + int dy_d = (deno_y == 0 ? 0 : nume_y / deno_y); + + c->floating_rectangle.x = md->rectangle.x + dx_d; + c->floating_rectangle.y = md->rectangle.y + dy_d; } -void translate_client(monitor_t *ms, monitor_t *md, client_t *c) { - - int xoff = c->floating_rectangle.x - ms->rectangle.x; - int yoff = c->floating_rectangle.y - ms->rectangle.y; - - int xnum = xoff*(md->rectangle.width - c->floating_rectangle.width); - int ynum = yoff*(md->rectangle.height - c->floating_rectangle.height); - - int xden = ms->rectangle.width - c->floating_rectangle.width; - int yden = ms->rectangle.height - c->floating_rectangle.height; - - /* xden and yden can be zero if the window is fullscreen */ - int xoff_new = xden == 0 ? 0 : xnum/xden; - int yoff_new = yden == 0 ? 0 : ynum/yden; - - c->floating_rectangle.x = md->rectangle.x + xoff_new; - c->floating_rectangle.y = md->rectangle.y + yoff_new; -} - - void update_root(monitor_t *m) { xcb_rectangle_t rect = m->rectangle; @@ -263,6 +230,41 @@ monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel) return NULL; } +bool is_inside_monitor(monitor_t *m, xcb_point_t pt) +{ + xcb_rectangle_t r = m->rectangle; + return (r.x <= pt.x && pt.x < (r.x + r.width) + && r.y <= pt.y && pt.y < (r.y + r.height)); +} + +monitor_t *monitor_from_point(xcb_point_t pt) +{ + for (monitor_t *m = mon_head; m != NULL; m = m->next) + if (is_inside_monitor(m, pt)) + return m; + return NULL; +} + +monitor_t *monitor_from_client(client_t *c) +{ + xcb_point_t pt = {c->floating_rectangle.x, c->floating_rectangle.y}; + monitor_t *nearest = monitor_from_point(pt); + if (nearest == NULL) { + int x = (c->floating_rectangle.x + c->floating_rectangle.width) / 2; + int y = (c->floating_rectangle.y + c->floating_rectangle.height) / 2; + int dmin = INT_MAX; + for (monitor_t *m = mon_head; m != NULL; m = m->next) { + xcb_rectangle_t r = m->rectangle; + int d = abs((r.x + r.width / 2) - x) + abs((r.y + r.height / 2) - y); + if (d < dmin) { + dmin = d; + nearest = m; + } + } + } + return nearest; +} + monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel) { int dmin = INT_MAX; @@ -322,7 +324,7 @@ bool import_monitors(void) update_root(mm); for (desktop_t *d = mm->desk_head; d != NULL; d = d->next) for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) - translate_position(mm, mm, n); + translate_client(mm, mm, n->client); arrange(mm, mm->desk); mm->wired = true; PRINTF("update monitor %s (0x%X)\n", mm->name, mm->id); diff --git a/monitor.h b/monitor.h index a020698..babe480 100644 --- a/monitor.h +++ b/monitor.h @@ -30,8 +30,7 @@ monitor_t *make_monitor(xcb_rectangle_t rect); monitor_t *find_monitor(char *name); monitor_t *get_monitor_by_id(xcb_randr_output_t id); -void translate_position(monitor_t *ms, monitor_t *md, node_t *n); -void translate_client(monitor_t *ms, monitor_t *md, client_t *n); +void translate_client(monitor_t *ms, monitor_t *md, client_t *c); void update_root(monitor_t *m); void focus_monitor(monitor_t *m); monitor_t *add_monitor(xcb_rectangle_t rect); @@ -39,6 +38,9 @@ void remove_monitor(monitor_t *m); void merge_monitors(monitor_t *ms, monitor_t *md); void swap_monitors(monitor_t *m1, monitor_t *m2); monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel); +bool is_inside_monitor(monitor_t *m, xcb_point_t pt); +monitor_t *monitor_from_point(xcb_point_t pt); +monitor_t *monitor_from_client(client_t *c); monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel); bool import_monitors(void); diff --git a/pointer.c b/pointer.c index a2e46dd..19e9144 100644 --- a/pointer.c +++ b/pointer.c @@ -27,6 +27,7 @@ #include "settings.h" #include "stack.h" #include "tree.h" +#include "monitor.h" #include "window.h" #include "pointer.h" diff --git a/rule.c b/rule.c index 06294b6..d98e04a 100644 --- a/rule.c +++ b/rule.c @@ -42,6 +42,7 @@ rule_t *make_rule(void) r->effect.focus = false; r->effect.frame = false; r->effect.private = false; + r->effect.center = false; r->effect.unmanage = false; r->one_shot = false; r->effect.desc[0] = '\0'; @@ -114,7 +115,7 @@ bool is_match(rule_t *r, xcb_window_t win) return false; } -void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *private, bool *manage) +void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *private, bool *center, bool *manage) { xcb_ewmh_get_atoms_reply_t win_type; @@ -182,6 +183,8 @@ void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating *takes_focus = true; if (efc.frame) *frame = true; + if (efc.center) + *center = true; if (efc.private) *private = private; if (efc.unmanage) @@ -232,6 +235,8 @@ void list_rules(char *pattern, char *rsp) strncat(rsp, " --frame", REMLEN(rsp)); if (r->effect.private) strncat(rsp, " --private", REMLEN(rsp)); + if (r->effect.center) + strncat(rsp, " --center", REMLEN(rsp)); if (r->effect.unmanage) strncat(rsp, " --unmanage", REMLEN(rsp)); if (r->one_shot) diff --git a/rule.h b/rule.h index 24a5d29..1081606 100644 --- a/rule.h +++ b/rule.h @@ -34,7 +34,7 @@ void remove_rule(rule_t *r); void remove_rule_by_name(char *name); bool remove_rule_by_index(int idx); bool is_match(rule_t *r, xcb_window_t win); -void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *private, bool *manage); +void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *private, bool *center, bool *manage); void list_rules(char *pattern, char *rsp); #endif diff --git a/settings.c b/settings.c index e1db6eb..21c2463 100644 --- a/settings.c +++ b/settings.c @@ -77,5 +77,4 @@ void load_settings(void) auto_cancel = AUTO_CANCEL; history_aware_focus = HISTORY_AWARE_FOCUS; ignore_ewmh_focus = IGNORE_EWMH_FOCUS; - fit_monitor = FIT_MONITOR; } diff --git a/settings.h b/settings.h index 275c420..64e6daf 100644 --- a/settings.h +++ b/settings.h @@ -62,7 +62,6 @@ #define AUTO_CANCEL false #define APPLY_FLOATING_ATOM false #define IGNORE_EWMH_FOCUS false -#define FIT_MONITOR false char focused_border_color[MAXLEN]; char active_border_color[MAXLEN]; @@ -95,7 +94,6 @@ bool auto_alternate; bool auto_cancel; bool history_aware_focus; bool ignore_ewmh_focus; -bool fit_monitor; void run_config(void); void load_settings(void); diff --git a/tree.c b/tree.c index 8dfcb05..f33cfb4 100644 --- a/tree.c +++ b/tree.c @@ -966,8 +966,8 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop d2->focus = n1; if (m1 != m2) { - translate_position(m2, m1, n2); - translate_position(m1, m2, n1); + translate_client(m2, m1, n2->client); + translate_client(m1, m2, n1->client); } ewmh_set_wm_desktop(n1, d2); @@ -1005,7 +1005,7 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk insert_node(md, dd, ns, nd); if (md != ms) - translate_position(ms, md, ns); + translate_client(ms, md, ns->client); if (ds != dd) { ewmh_set_wm_desktop(ns, dd); diff --git a/types.h b/types.h index b5201dd..57e1387 100644 --- a/types.h +++ b/types.h @@ -249,9 +249,10 @@ typedef struct { bool sticky; bool follow; bool focus; - bool unmanage; bool frame; bool private; + bool center; + bool unmanage; char desc[MAXLEN]; } rule_effect_t; diff --git a/window.c b/window.c index 2ec68ca..a86750c 100644 --- a/window.c +++ b/window.c @@ -48,19 +48,8 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win) if (override_redirect || locate_window(win, &loc)) return; - bool fresh = true; - uint32_t idx; - if (xcb_ewmh_get_wm_desktop_reply(ewmh, xcb_ewmh_get_wm_desktop(ewmh, win), &idx, NULL) == 1) { - coordinates_t loc; - if (ewmh_locate_desktop(idx, &loc)) { - m = loc.monitor; - d = loc.desktop; - } - fresh = false; - } - - bool floating = false, fullscreen = false, locked = false, sticky = false, follow = false, transient = false, takes_focus = true, frame = false, private = false, manage = true; - handle_rules(win, &m, &d, &floating, &fullscreen, &locked, &sticky, &follow, &transient, &takes_focus, &frame, &private, &manage); + bool floating = false, fullscreen = false, locked = false, sticky = false, follow = false, transient = false, takes_focus = true, frame = false, private = false, center = false, manage = true; + handle_rules(win, &m, &d, &floating, &fullscreen, &locked, &sticky, &follow, &transient, &takes_focus, &frame, &private, ¢er, &manage); if (!manage) { disable_floating_atom(win); @@ -72,9 +61,9 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win) client_t *c = make_client(win); update_floating_rectangle(c); - if (fresh) { - translate_client(underlying_monitor(c), m, c); - } + translate_client(monitor_from_client(c), m, c); + if (center) + window_center(m, c); c->frame = frame; xcb_icccm_get_wm_class_reply_t reply; @@ -90,7 +79,6 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win) n->client = c; insert_node(m, d, n, d->focus); - translate_position(m, m, n); disable_floating_atom(c->window); set_floating(n, floating); @@ -285,13 +273,6 @@ bool contains(xcb_rectangle_t a, xcb_rectangle_t b) && a.y <= b.y && (a.y + a.height) >= (b.y + b.height)); } -bool is_inside(monitor_t *m, xcb_point_t pt) -{ - xcb_rectangle_t r = m->rectangle; - return (r.x <= pt.x && pt.x < (r.x + r.width) - && r.y <= pt.y && pt.y < (r.y + r.height)); -} - xcb_rectangle_t get_rectangle(client_t *c) { if (is_tiled(c)) @@ -323,20 +304,6 @@ void get_side_handle(client_t *c, direction_t dir, xcb_point_t *pt) } } -monitor_t *monitor_from_point(xcb_point_t pt) -{ - for (monitor_t *m = mon_head; m != NULL; m = m->next) - if (is_inside(m, pt)) - return m; - return NULL; -} - -monitor_t *underlying_monitor(client_t *c) -{ - xcb_point_t pt = (xcb_point_t) {c->floating_rectangle.x, c->floating_rectangle.y}; - return monitor_from_point(pt); -} - void adopt_orphans(void) { xcb_query_tree_reply_t *qtr = xcb_query_tree_reply(dpy, xcb_query_tree(dpy, root), NULL); @@ -614,6 +581,20 @@ void window_raise(xcb_window_t win) xcb_configure_window(dpy, win, XCB_CONFIG_WINDOW_STACK_MODE, values); } +void window_center(monitor_t *m, client_t *c) +{ + xcb_rectangle_t *r = &c->floating_rectangle; + xcb_rectangle_t a = m->rectangle; + if (r->width >= a.width) + r->x = a.x; + else + r->x = a.x + (a.width - r->width) / 2; + if (r->height >= a.height) + r->y = a.y; + else + r->y = a.y + (a.height - r->height) / 2; +} + void window_stack(xcb_window_t w1, xcb_window_t w2, uint32_t mode) { if (w2 == XCB_NONE) diff --git a/window.h b/window.h index f7ee5ed..bcedecc 100644 --- a/window.h +++ b/window.h @@ -36,11 +36,8 @@ void window_draw_border(node_t *n, bool focused_window, bool focused_monitor); void draw_frame_background(node_t *n, bool focused_window, bool focused_monitor); pointer_state_t *make_pointer_state(void); bool contains(xcb_rectangle_t a, xcb_rectangle_t b); -bool is_inside(monitor_t *m, xcb_point_t pt); xcb_rectangle_t get_rectangle(client_t *c); void get_side_handle(client_t *c, direction_t dir, xcb_point_t *pt); -monitor_t *monitor_from_point(xcb_point_t pt); -monitor_t *underlying_monitor(client_t *c); void adopt_orphans(void); void window_close(node_t *n); void window_kill(monitor_t *m, desktop_t *d, node_t *n); @@ -62,6 +59,7 @@ void window_move(xcb_window_t win, int16_t x, int16_t y); void window_resize(xcb_window_t win, uint16_t w, uint16_t h); void window_move_resize(xcb_window_t win, int16_t x, int16_t y, uint16_t w, uint16_t h); void window_raise(xcb_window_t win); +void window_center(monitor_t *m, client_t *c); void window_stack(xcb_window_t w1, xcb_window_t w2, uint32_t mode); void window_above(xcb_window_t w1, xcb_window_t w2); void window_below(xcb_window_t w1, xcb_window_t w2);