From af708d2fbc2dea0fc1fa9bfd82bbed288e3d3249 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Sun, 6 Jan 2008 14:40:23 +0100 Subject: [PATCH] Rewrite everything about client geoemtry, resize, etc. --- client.c | 119 +++++++++++++++++++++++--------------------- client.h | 3 +- event.c | 44 ++++++++-------- ewmh.c | 27 ++++++++-- layouts/fibonacci.c | 2 +- layouts/floating.c | 2 +- layouts/max.c | 2 +- layouts/tile.c | 8 +-- mouse.c | 5 +- screen.c | 49 ++++++++++++------ tag.c | 10 ++-- 11 files changed, 155 insertions(+), 116 deletions(-) diff --git a/client.c b/client.c index c0bafee5..231069cb 100644 --- a/client.c +++ b/client.c @@ -434,13 +434,15 @@ client_manage(Window w, XWindowAttributes *wa, int screen) * \param h height * \param sizehints respect size hints * \param volatile_coords register coords in rx/ry/rw/rh + * \param return True if resize has been done */ -void -client_resize(Client *c, Area geometry, Bool sizehints, Bool volatile_coords) +Bool +client_resize(Client *c, Area geometry, Bool sizehints) { + int new_screen; double dx, dy, max, min, ratio; Area area; - Tag **curtags; + XWindowChanges wc; if(sizehints) { @@ -484,7 +486,7 @@ client_resize(Client *c, Area geometry, Bool sizehints, Bool volatile_coords) geometry.height -= (geometry.height - c->baseh) % c->inch; } if(geometry.width <= 0 || geometry.height <= 0) - return; + return False; /* offscreen appearance fixes */ area = get_display_area(get_phys_screen(c->screen), NULL, @@ -497,33 +499,35 @@ client_resize(Client *c, Area geometry, Bool sizehints, Bool volatile_coords) geometry.x = 0; if(geometry.y + geometry.height + 2 * c->border < 0) geometry.y = 0; + if(c->geometry.x != geometry.x || c->geometry.y != geometry.y || c->geometry.width != geometry.width || c->geometry.height != geometry.height) { - c->geometry.x = geometry.x; - c->geometry.y = geometry.y; - c->geometry.width = geometry.width; - c->geometry.height = geometry.height; - curtags = get_current_tags(c->screen); - if(!volatile_coords && (c->isfloating - || curtags[0]->layout->arrange == layout_floating)) - { - c->f_geometry.x = geometry.x; - c->f_geometry.y = geometry.y; - c->f_geometry.width = geometry.width; - c->f_geometry.height = geometry.height; - } - p_delete(&curtags); - XMoveResizeWindow(globalconf.display, c->win, geometry.x, geometry.y, - geometry.width, geometry.height); - window_configure(c->win, geometry, c->border); if(XineramaIsActive(globalconf.display)) - { - int new_screen = get_screen_bycoord(geometry.x, geometry.y); - if(c->screen != new_screen) - move_client_to_screen(c, new_screen, False); - } + new_screen = get_screen_bycoord(geometry.x, geometry.y); + else + new_screen = c->screen; + + c->geometry.x = wc.x = geometry.x; + c->geometry.y = wc.y = geometry.y; + c->geometry.width = wc.width = geometry.width; + c->geometry.height = wc.height = geometry.height; + wc.border_width = c->border; + + if(c->isfloating || + get_current_layout(new_screen)->arrange == layout_floating) + c->f_geometry = geometry; + + XConfigureWindow(globalconf.display, c->win, + CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc); + window_configure(c->win, geometry, c->border); + + if(c->screen != new_screen) + move_client_to_screen(c, new_screen, False); + + return True; } + return False; } /** Save client properties as an X property @@ -819,7 +823,7 @@ uicb_client_moveresize(int screen, char *arg) RootWindow(globalconf.display, get_phys_screen(screen)), &dummy, &dummy, &mx, &my, &dx, &dy, &dui); - client_resize(sel, area, True, False); + client_resize(sel, area, True); if (xqp && ox <= mx && (ox + ow) >= mx && oy <= my && (oy + oh) >= my) { nmx = mx - ox + sel->geometry.width - ow - 1 < 0 ? 0 : mx - ox + sel->geometry.width - ow - 1; @@ -864,36 +868,30 @@ uicb_client_kill(int screen __attribute__ ((unused)), char *arg __attribute__ (( client_kill(sel); } -void -client_maximize(Client *c, int x, int y, int w, int h, Bool borders) +static void +client_maximize(Client *c, Area geometry) { - Area area; - - area.x = x; - area.y = y; - area.width = w; - area.height = h; - + if((c->ismax = !c->ismax)) { - if(borders) - { - c->oldborder = c->border; - c->border = 0; - } c->wasfloating = c->isfloating; + c->m_geometry = c->geometry; + client_resize(c, geometry, False); + /* set floating after resizing so it won't save + * coords */ c->isfloating = True; - client_resize(c, area, False, True); } else if(c->wasfloating) - client_resize(c, c->f_geometry, True, False); + { + c->isfloating = True; + client_resize(c, c->m_geometry, False); + } else + { c->isfloating = False; - - if(borders) - c->border = c->oldborder; - - arrange(c->screen); + arrange(c->screen); + } + statusbar_draw_all(c->screen); } /** Toggle maximize for client @@ -908,10 +906,13 @@ uicb_client_togglemax(int screen, char *arg __attribute__ ((unused))) Area area = get_screen_area(screen, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); + if(sel) - client_maximize(sel, area.x, area.y, - area.width - 2 * sel->border, - area.height - 2 * sel->border, False); + { + area.width -= 2 * sel->border; + area.height -= 2 * sel->border; + client_maximize(sel, area); + } } /** Toggle vertical maximize for client @@ -928,9 +929,11 @@ uicb_client_toggleverticalmax(int screen, char *arg __attribute__ ((unused))) &globalconf.screens[screen].padding); if(sel) - client_maximize(sel, sel->geometry.x, area.y, - sel->geometry.width, - area.height - 2 * sel->border, False); + { + area.x = sel->geometry.x; + area.height -= 2 * sel->border; + client_maximize(sel, area); + } } @@ -948,9 +951,11 @@ uicb_client_togglehorizontalmax(int screen, char *arg __attribute__ ((unused))) &globalconf.screens[screen].padding); if(sel) - client_maximize(sel, area.x, sel->geometry.y, - area.height - 2 * sel->border, - sel->geometry.height, False); + { + area.y = sel->geometry.y; + area.width -= 2 * sel->border; + client_maximize(sel, area); + } } /** Zoom client diff --git a/client.h b/client.h index 1a33c953..04d50c52 100644 --- a/client.h +++ b/client.h @@ -32,7 +32,7 @@ void client_detach(Client *); void client_ban(Client *); void focus(Client *, Bool, int); void client_manage(Window, XWindowAttributes *, int); -void client_resize(Client *, Area, Bool, Bool); +Bool client_resize(Client *, Area, Bool); void client_unban(Client *); void client_unmanage(Client *, long); void client_updatewmhints(Client *); @@ -40,7 +40,6 @@ void client_updatesizehints(Client *); void client_updatetitle(Client *); void client_saveprops(Client *); void client_kill(Client *); -void client_maximize(Client *c, int, int, int, int, Bool); Uicb uicb_client_kill; Uicb uicb_client_moveresize; diff --git a/event.c b/event.c index 5361f6d0..e7fefb4c 100644 --- a/event.c +++ b/event.c @@ -139,39 +139,41 @@ handle_event_configurerequest(XEvent * e) Client *c; XConfigureRequestEvent *ev = &e->xconfigurerequest; XWindowChanges wc; - int old_screen; + int old_screen, new_screen; + Area geometry; if((c = get_client_bywin(globalconf.clients, ev->window))) { - if(c->isfixed) + geometry = c->geometry; + + if(ev->value_mask & CWX) + geometry.x = ev->x; + if(ev->value_mask & CWY) + geometry.y = ev->y; + if(ev->value_mask & CWWidth) + geometry.width = ev->width; + if(ev->value_mask & CWHeight) + geometry.height = ev->height; + + if(geometry.x != c->geometry.x || geometry.y != c->geometry.y + || geometry.width != c->geometry.width || geometry.height != c->geometry.height) { - if(ev->value_mask & CWX) - c->f_geometry.x = c->geometry.x = ev->x - c->border; - if(ev->value_mask & CWY) - c->f_geometry.y = c->f_geometry.y = ev->y - c->border; - if(ev->value_mask & CWWidth) - c->f_geometry.width = c->geometry.width = ev->width; - if(ev->value_mask & CWHeight) - c->f_geometry.height = c->geometry.height = ev->height; - if((ev->value_mask & (CWX | CWY)) && !(ev->value_mask & (CWWidth | CWHeight))) - window_configure(c->win, c->geometry, c->border); - /* recompute screen */ old_screen = c->screen; - c->screen = get_screen_bycoord(c->geometry.x, c->geometry.y); + + if(get_current_layout(c->screen)->arrange != layout_floating) + c->isfloating = True; + client_resize(c, geometry, False); + if(old_screen != c->screen) { - move_client_to_screen(c, c->screen, False); statusbar_draw_all(old_screen); - statusbar_draw_all(c->screen); + arrange(old_screen); } - tag_client_with_rules(c); - XMoveResizeWindow(e->xany.display, c->win, c->f_geometry.x, c->f_geometry.y, - c->f_geometry.width, c->f_geometry.height); - window_configure(c->win, c->f_geometry, c->border); + statusbar_draw_all(c->screen); arrange(c->screen); } else - window_configure(c->win, c->geometry, c->border); + window_configure(c->win, geometry, c->border); } else { diff --git a/ewmh.c b/ewmh.c index 767a5740..ad889159 100644 --- a/ewmh.c +++ b/ewmh.c @@ -28,6 +28,7 @@ #include "focus.h" #include "screen.h" #include "client.h" +#include "statusbar.h" extern AwesomeConf globalconf; @@ -241,13 +242,29 @@ ewmh_process_state_atom(Client *c, Atom state, int set) } else if(state == net_wm_state_fullscreen) { - Area area = get_screen_area(c->screen, NULL, NULL); - /* reset max attribute */ + Area geometry; if(set == _NET_WM_STATE_REMOVE) - c->ismax = True; - else if(set == _NET_WM_STATE_ADD) + { + /* restore geometry */ + geometry = c->m_geometry; + c->border = c->oldborder; c->ismax = False; - client_maximize(c, area.x, area.y, area.width, area.height, True); + c->isfloating = c->wasfloating; + } + else if(set == _NET_WM_STATE_ADD) + { + geometry = get_screen_area(c->screen, NULL, NULL); + /* save geometry */ + c->m_geometry = c->geometry; + c->wasfloating = c->isfloating; + c->oldborder = c->border; + c->border = 0; + c->ismax = True; + c->isfloating = True; + } + statusbar_draw_all(c->screen); + client_resize(c, geometry, False); + XRaiseWindow(globalconf.display, c->win); } } diff --git a/layouts/fibonacci.c b/layouts/fibonacci.c index e2ab7c80..3e8626e4 100644 --- a/layouts/fibonacci.c +++ b/layouts/fibonacci.c @@ -82,7 +82,7 @@ layout_fibonacci(int screen, int shape) } geometry.width -= 2 * c->border; geometry.height -= 2 * c->border; - client_resize(c, geometry, globalconf.screens[screen].resize_hints, False); + client_resize(c, geometry, globalconf.screens[screen].resize_hints); } } diff --git a/layouts/floating.c b/layouts/floating.c index 782b2f59..9933f3ff 100644 --- a/layouts/floating.c +++ b/layouts/floating.c @@ -32,6 +32,6 @@ layout_floating(int screen) for(c = globalconf.clients; c; c = c->next) if(client_isvisible(c, screen) && !c->ismax) - client_resize(c, c->f_geometry, True, False); + client_resize(c, c->f_geometry, True); } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/layouts/max.c b/layouts/max.c index 0959e01c..28115ed4 100644 --- a/layouts/max.c +++ b/layouts/max.c @@ -40,7 +40,7 @@ layout_max(int screen) { area.width -= 2 * c->border; area.height -= 2 * c->border; - client_resize(c, area, globalconf.screens[screen].resize_hints, False); + client_resize(c, area, globalconf.screens[screen].resize_hints); area.width += 2 * c->border; area.height += 2 * c->border; } diff --git a/layouts/tile.c b/layouts/tile.c index b843339a..369de296 100644 --- a/layouts/tile.c +++ b/layouts/tile.c @@ -145,15 +145,15 @@ _tile(int screen, const Bool right) c->ismax = False; if(i < curtags[0]->nmaster) - { /* master */ + { geometry.y = way + i * mh; geometry.x = wax + (right ? 0 : waw - mw); geometry.width = mw - 2 * c->border; geometry.height = mh - 2 * c->border; - client_resize(c, geometry, globalconf.screens[screen].resize_hints, False); + client_resize(c, geometry, globalconf.screens[screen].resize_hints); } else - { /* tile window */ + { if(real_ncol) win_by_col = otherwin / real_ncol; @@ -176,7 +176,7 @@ _tile(int screen, const Bool right) geometry.y = way + ((i - curtags[0]->nmaster) % win_by_col) * (geometry.height + 2 * c->border); geometry.x = wax + current_col * (geometry.width + 2 * c->border) + (right ? mw : 0); - client_resize(c, geometry, globalconf.screens[screen].resize_hints, False); + client_resize(c, geometry, globalconf.screens[screen].resize_hints); } i++; } diff --git a/mouse.c b/mouse.c index 1a4548ef..c5663338 100644 --- a/mouse.c +++ b/mouse.c @@ -109,7 +109,7 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) geometry.y = area.y + area.height - c->geometry.height - 2 * c->border; geometry.width = c->geometry.width; geometry.height = c->geometry.height; - client_resize(c, geometry, False, False); + client_resize(c, geometry, False); while(XCheckMaskEvent(globalconf.display, PointerMotionMask, &ev)); break; } @@ -199,7 +199,7 @@ uicb_client_resizemouse(int screen, char *arg __attribute__ ((unused))) geometry.height = 1; geometry.x = c->geometry.x; geometry.y = c->geometry.y; - client_resize(c, geometry, True, False); + client_resize(c, geometry, True); } else if(curtags[0]->layout->arrange == layout_tile || curtags[0]->layout->arrange == layout_tileleft) @@ -225,5 +225,4 @@ uicb_client_resizemouse(int screen, char *arg __attribute__ ((unused))) p_delete(&curtags); } - // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/screen.c b/screen.c index 50e99c00..dd4ba276 100644 --- a/screen.c +++ b/screen.c @@ -27,6 +27,7 @@ #include "focus.h" #include "statusbar.h" #include "client.h" +#include "layouts/floating.h" extern AwesomeConf globalconf; @@ -142,7 +143,6 @@ get_screen_bycoord(int x, int y) if(!XineramaIsActive(globalconf.display)) return DefaultScreen(globalconf.display); - for(i = 0; i < get_screen_count(); i++) { area = get_screen_area(i, NULL, NULL); @@ -203,25 +203,46 @@ move_client_to_screen(Client *c, int new_screen, Bool doresize) /* tag client with new screen tags */ tag_client_with_current_selected(c); + /* resize the windows if it's floating */ if(doresize && old_screen != c->screen) { + Area new_f_geometry = c->f_geometry; + to = get_screen_area(c->screen, NULL, NULL); from = get_screen_area(old_screen, NULL, NULL); - + /* compute new coords in new screen */ - c->f_geometry.x = (c->f_geometry.x - from.x) + to.x; - c->f_geometry.y = (c->f_geometry.y - from.y) + to.y; - /* check that new coords are still in the screen */ - if(c->f_geometry.width > to.width) - c->f_geometry.width = to.width; - if(c->f_geometry.height > to.height) - c->f_geometry.height = to.height; - if(c->f_geometry.x + c->f_geometry.width >= to.x + to.width) - c->f_geometry.x = to.x + to.width - c->f_geometry.width - 2 * c->border; - if(c->f_geometry.y + c->f_geometry.height >= to.y + to.height) - c->f_geometry.y = to.y + to.height - c->f_geometry.height - 2 * c->border; + new_f_geometry.x = (c->f_geometry.x - from.x) + to.x; + new_f_geometry.y = (c->f_geometry.y - from.y) + to.y; - client_resize(c, c->f_geometry, True, False); + /* check that new coords are still in the screen */ + if(new_f_geometry.width > to.width) + new_f_geometry.width = to.width; + if(new_f_geometry.height > to.height) + new_f_geometry.height = to.height; + if(new_f_geometry.x + new_f_geometry.width >= to.x + to.width) + new_f_geometry.x = to.x + to.width - new_f_geometry.width - 2 * c->border; + if(new_f_geometry.y + new_f_geometry.height >= to.y + to.height) + new_f_geometry.y = to.y + to.height - new_f_geometry.height - 2 * c->border; + + if(c->ismax) + { + /* compute new coords for max in new screen */ + c->m_geometry.x = (c->m_geometry.x - from.x) + to.x; + c->m_geometry.y = (c->m_geometry.y - from.y) + to.y; + + /* check that new coords are still in the screen */ + if(c->m_geometry.width > to.width) + c->m_geometry.width = to.width; + if(c->m_geometry.height > to.height) + c->m_geometry.height = to.height; + if(c->m_geometry.x + c->m_geometry.width >= to.x + to.width) + c->m_geometry.x = to.x + to.width - c->m_geometry.width - 2 * c->border; + if(c->m_geometry.y + c->m_geometry.height >= to.y + to.height) + c->m_geometry.y = to.y + to.height - c->m_geometry.height - 2 * c->border; + } + + client_resize(c, new_f_geometry, False); } focus(c, True, c->screen); diff --git a/tag.c b/tag.c index 1bfde36d..66386950 100644 --- a/tag.c +++ b/tag.c @@ -206,19 +206,15 @@ uicb_client_tag(int screen, char *arg) * \ingroup ui_callback */ void -uicb_client_togglefloating(int screen, char *arg __attribute__ ((unused))) +uicb_client_togglefloating(int screen, char *arg __attribute__((unused))) { Client *sel = globalconf.focus->client; if(!sel) return; - sel->isfloating = !sel->isfloating; - - if (arg == NULL) - client_resize(sel, sel->f_geometry, True, False); - else - client_resize(sel, sel->geometry, True, True); + if((sel->isfloating = !sel->isfloating)) + client_resize(sel, sel->f_geometry, True); client_saveprops(sel); arrange(screen);