From 5f079ef73e14872dd0aa23a2108891c8bc251824 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 23 Dec 2007 10:54:59 +1100 Subject: [PATCH] Clean get_screen_info and get_display_info. Besides making these functions much nicer to use, this fixes a number of things: - Clients now don't have to free the returned structures. - The ScreenInfo allocated by XineramaQueryScreens should be freed with XFree, not p_delete. This patch also introduces an abstract Area type that will be very useful. --- client.c | 53 +++++++------- config.h | 10 +++ event.c | 7 +- layout.c | 36 +++++----- layouts/fibonacci.c | 17 +++-- layouts/max.c | 11 +-- layouts/tile.c | 15 ++-- mouse.c | 25 ++++--- screen.c | 168 ++++++++++++++++++++++---------------------- screen.h | 4 +- statusbar.c | 33 ++++----- 11 files changed, 187 insertions(+), 192 deletions(-) diff --git a/client.c b/client.c index d572eeeab..5ec16338f 100644 --- a/client.c +++ b/client.c @@ -257,7 +257,7 @@ client_manage(Window w, XWindowAttributes *wa, int screen) Window trans; Status rettrans; XWindowChanges wc; - ScreenInfo *screen_info; + Area area, darea; Tag *tag; c = p_new(Client, 1); @@ -282,36 +282,32 @@ client_manage(Window w, XWindowAttributes *wa, int screen) if(!client_loadprops(c, screen)) tag_client_with_rules(c); - screen_info = get_screen_info(screen, NULL, NULL); + area = get_screen_area(screen, NULL, NULL); /* if window request fullscreen mode */ - if(c->w == screen_info[screen].width && c->h == screen_info[screen].height) + if(c->w == area.width && c->h == area.height) { - c->x = screen_info[screen].x_org; - c->y = screen_info[screen].y_org; - + c->x = area.x; + c->y = area.y; c->border = wa->border_width; } else { - ScreenInfo *display_info = get_display_info(c->phys_screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); + darea = get_display_area(c->phys_screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); - if(c->x + c->w + 2 * c->border > display_info->x_org + display_info->width) - c->x = c->rx = display_info->x_org + display_info->width - c->w - 2 * c->border; - if(c->y + c->h + 2 * c->border > display_info->y_org + display_info->height) - c->y = c->ry = display_info->y_org + display_info->height - c->h - 2 * c->border; - if(c->x < display_info->x_org) - c->x = c->rx = display_info->x_org; - if(c->y < display_info->y_org) - c->y = c->ry = display_info->y_org; + if(c->x + c->w + 2 * c->border > darea.x + darea.width) + c->x = c->rx = darea.x + darea.width - c->w - 2 * c->border; + if(c->y + c->h + 2 * c->border > darea.y + darea.height) + c->y = c->ry = darea.y + darea.height - c->h - 2 * c->border; + if(c->x < darea.x) + c->x = c->rx = darea.x; + if(c->y < darea.y) + c->y = c->ry = darea.y; c->border = globalconf.screens[screen].borderpx; - - p_delete(&display_info); } - p_delete(&screen_info); /* set borders */ wc.border_width = c->border; @@ -368,7 +364,7 @@ client_resize(Client *c, int x, int y, int w, int h, { double dx, dy, max, min, ratio; XWindowChanges wc; - ScreenInfo *si; + Area area; if(sizehints) { @@ -413,14 +409,13 @@ client_resize(Client *c, int x, int y, int w, int h, if(w <= 0 || h <= 0) return; /* offscreen appearance fixes */ - si = get_display_info(c->phys_screen, - NULL, - &globalconf.screens[c->screen].padding); - if(x > si->width) - x = si->width - w - 2 * c->border; - if(y > si->height) - y = si->height - h - 2 * c->border; - p_delete(&si); + area = get_display_area(c->phys_screen, + NULL, + &globalconf.screens[c->screen].padding); + if(x > area.width) + x = area.width - w - 2 * c->border; + if(y > area.height) + y = area.height - h - 2 * c->border; if(x + w + 2 * c->border < 0) x = 0; if(y + h + 2 * c->border < 0) diff --git a/config.h b/config.h index 2b326f086..b661f3ceb 100644 --- a/config.h +++ b/config.h @@ -51,6 +51,16 @@ struct Rule typedef struct AwesomeConf AwesomeConf; +typedef struct Area Area; +struct Area +{ + /* Co-ords of upper left corner */ + int x; + int y; + int width; + int height; +}; + typedef struct Layout Layout; struct Layout { diff --git a/event.c b/event.c index 80b86fe9d..6f2780c3c 100644 --- a/event.c +++ b/event.c @@ -188,7 +188,7 @@ handle_event_configurenotify(XEvent * e) { XConfigureEvent *ev = &e->xconfigure; int screen; - ScreenInfo *si; + Area area; for(screen = 0; screen < ScreenCount(e->xany.display); screen++) if(ev->window == RootWindow(e->xany.display, screen) @@ -199,9 +199,8 @@ handle_event_configurenotify(XEvent * e) DisplayHeight(e->xany.display, screen) = ev->height; /* update statusbar */ - si = get_screen_info(screen, NULL, &globalconf.screens[screen].padding); - globalconf.screens[screen].statusbar->width = si[screen].width; - p_delete(&si); + area = get_screen_area(screen, NULL, &globalconf.screens[screen].padding); + globalconf.screens[screen].statusbar->width = area.width; XResizeWindow(e->xany.display, globalconf.screens[screen].statusbar->window, diff --git a/layout.c b/layout.c index d96389c4b..7370298bc 100644 --- a/layout.c +++ b/layout.c @@ -300,15 +300,13 @@ maximize(int x, int y, int w, int h, int screen) void uicb_client_togglemax(int screen, char *arg __attribute__ ((unused))) { - ScreenInfo *si = get_screen_info(screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); - - maximize(si[screen].x_org, si[screen].y_org, - si[screen].width - 2 * globalconf.screens[screen].borderpx, - si[screen].height - 2 * globalconf.screens[screen].borderpx, + Area area = get_screen_area(screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); + maximize(area.x, area.y, + area.width - 2 * globalconf.screens[screen].borderpx, + area.height - 2 * globalconf.screens[screen].borderpx, screen); - p_delete(&si); } /** Toggle vertical maximize for client @@ -320,17 +318,16 @@ void uicb_client_toggleverticalmax(int screen, char *arg __attribute__ ((unused))) { Client *sel = globalconf.focus->client; - ScreenInfo *si = get_screen_info(screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); + Area area = get_screen_area(screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); if(sel) maximize(sel->x, - si[screen].y_org, + area.y, sel->w, - si[screen].height - 2 * globalconf.screens[screen].borderpx, + area.height - 2 * globalconf.screens[screen].borderpx, screen); - p_delete(&si); } @@ -343,17 +340,16 @@ void uicb_client_togglehorizontalmax(int screen, char *arg __attribute__ ((unused))) { Client *sel = globalconf.focus->client; - ScreenInfo *si = get_screen_info(screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); + Area area = get_screen_area(screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); if(sel) - maximize(si[screen].x_org, + maximize(area.x, sel->y, - si[screen].height - 2 * globalconf.screens[screen].borderpx, + area.height - 2 * globalconf.screens[screen].borderpx, sel->h, screen); - p_delete(&si); } /** Zoom client diff --git a/layouts/fibonacci.c b/layouts/fibonacci.c index f5304d77d..89b6faac6 100644 --- a/layouts/fibonacci.c +++ b/layouts/fibonacci.c @@ -31,14 +31,14 @@ layout_fibonacci(int screen, int shape) { int n = 0, i = 0, nx, ny, nw, nh; Client *c; - ScreenInfo *si = get_screen_info(screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); + Area area = get_screen_area(screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); - nx = si[screen].x_org; - ny = si[screen].y_org; - nw = si[screen].width; - nh = si[screen].height; + nx = area.x; + ny = area.y; + nw = area.width; + nh = area.height; for(c = globalconf.clients; c; c = c->next) if(IS_TILED(c, screen)) @@ -80,13 +80,12 @@ layout_fibonacci(int screen, int shape) nx -= nw; } if(i == 0) - ny = si[screen].y_org; + ny = area.y; i++; } client_resize(c, nx, ny, nw - 2 * c->border, nh - 2 * c->border, globalconf.screens[screen].resize_hints, False); } - p_delete(&si); } void diff --git a/layouts/max.c b/layouts/max.c index 95083b76c..082502327 100644 --- a/layouts/max.c +++ b/layouts/max.c @@ -30,13 +30,14 @@ void layout_max(int screen) { Client *c; - ScreenInfo *si = get_screen_info(screen, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); + Area area = get_screen_area(screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); for(c = globalconf.clients; c; c = c->next) if(IS_TILED(c, screen)) - client_resize(c, si[screen].x_org, si[screen].y_org, - si[screen].width - 2 * c->border, - si[screen].height - 2 * c->border, globalconf.screens[screen].resize_hints, False); - p_delete(&si); + client_resize(c, area.x, area.y, + area.width - 2 * c->border, + area.height - 2 * c->border, globalconf.screens[screen].resize_hints, False); } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/layouts/tile.c b/layouts/tile.c index e1e745a27..739062d11 100644 --- a/layouts/tile.c +++ b/layouts/tile.c @@ -99,20 +99,22 @@ _tile(int screen, const Bool right) unsigned int mw = 0, mh = 0; int n, i, masterwin = 0, otherwin = 0; int real_ncol = 1, win_by_col = 1, current_col = 0; - ScreenInfo *screens_info = NULL; + Area area; Client *c; Tag *curtag = get_current_tag(screen); - screens_info = get_screen_info(screen, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); + area = get_screen_area(screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); for(n = 0, c = globalconf.clients; c; c = c->next) if(IS_TILED(c, screen)) n++; - wah = screens_info[screen].height; - waw = screens_info[screen].width; - wax = screens_info[screen].x_org; - way = screens_info[screen].y_org; + wah = area.height; + waw = area.width; + wax = area.x; + way = area.y; masterwin = MIN(n, curtag->nmaster); @@ -171,7 +173,6 @@ _tile(int screen, const Bool right) } i++; } - p_delete(&screens_info); } void diff --git a/mouse.c b/mouse.c index f6a8c6374..b628f252f 100644 --- a/mouse.c +++ b/mouse.c @@ -42,7 +42,7 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) unsigned int dui; Window dummy; XEvent ev; - ScreenInfo *si; + Area area; Client *c = globalconf.focus->client; if(!c) @@ -54,9 +54,9 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) else restack(screen); - si = get_screen_info(c->screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); + area = get_screen_area(c->screen, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); ocx = nx = c->x; ocy = ny = c->y; @@ -75,7 +75,6 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) { case ButtonRelease: XUngrabPointer(c->display, CurrentTime); - p_delete(&si); return; case ConfigureRequest: handle_event_configurerequest(&ev); @@ -90,14 +89,14 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) XSync(c->display, False); nx = ocx + (ev.xmotion.x - x1); ny = ocy + (ev.xmotion.y - y1); - if(abs(nx) < globalconf.screens[screen].snap + si[c->screen].x_org && nx > si[c->screen].x_org) - nx = si[c->screen].x_org; - else if(abs((si[c->screen].x_org + si[c->screen].width) - (nx + c->w + 2 * c->border)) < globalconf.screens[screen].snap) - nx = si[c->screen].x_org + si[c->screen].width - c->w - 2 * c->border; - if(abs(ny) < globalconf.screens[screen].snap + si[c->screen].y_org && ny > si[c->screen].y_org) - ny = si[c->screen].y_org; - else if(abs((si[c->screen].y_org + si[c->screen].height) - (ny + c->h + 2 * c->border)) < globalconf.screens[screen].snap) - ny = si[c->screen].y_org + si[c->screen].height - c->h - 2 * c->border; + if(abs(nx) < globalconf.screens[screen].snap + area.x && nx > area.x) + nx = area.x; + else if(abs((area.x + area.width) - (nx + c->w + 2 * c->border)) < globalconf.screens[screen].snap) + nx = area.x + area.width - c->w - 2 * c->border; + if(abs(ny) < globalconf.screens[screen].snap + area.y && ny > area.y) + ny = area.y; + else if(abs((area.y + area.height) - (ny + c->h + 2 * c->border)) < globalconf.screens[screen].snap) + ny = area.y + area.height - c->h - 2 * c->border; client_resize(c, nx, ny, c->w, c->h, False, False); break; } diff --git a/screen.c b/screen.c index f821f9d90..25f078ddd 100644 --- a/screen.c +++ b/screen.c @@ -31,85 +31,88 @@ extern AwesomeConf globalconf; /** Get screens info * \param screen Screen number * \param statusbar statusbar - * \return ScreenInfo struct array with all screens info + * \return Area * \param padding Padding */ -ScreenInfo * -get_screen_info(int screen, Statusbar *statusbar, Padding *padding) +Area +get_screen_area(int screen, Statusbar *statusbar, Padding *padding) { - int i, screen_number = 0; + int screen_number = 0; ScreenInfo *si; + Area area; - if(XineramaIsActive(globalconf.display)) + if(XineramaIsActive(globalconf.display)){ si = XineramaQueryScreens(globalconf.display, &screen_number); - else + if (screen_number < screen) + eprint("Info request for unknown screen."); + area.x = si[screen].x_org; + area.y = si[screen].y_org; + area.width = si[screen].width; + area.height = si[screen].height; + XFree(si); + } else { /* emulate Xinerama info but only fill the screen we want */ - si = p_new(ScreenInfo, screen + 1); - si[screen].width = DisplayWidth(globalconf.display, screen); - si[screen].height = DisplayHeight(globalconf.display, screen); - si[screen].x_org = 0; - si[screen].y_org = 0; - screen_number = screen + 1; + area.x = 0; + area.y = 0; + area.width = DisplayWidth(globalconf.display, screen); + area.height = DisplayHeight(globalconf.display, screen); } /* make padding corrections */ if(padding) { - si[screen].x_org += padding->left; - si[screen].y_org += padding->top; - si[screen].width -= padding->left + padding->right; - si[screen].height -= padding->top + padding->bottom; + area.x += padding->left; + area.y += padding->top; + area.width -= padding->left + padding->right; + area.height -= padding->top + padding->bottom; } - if(statusbar) - for(i = 0; i < screen_number; i++) - switch(statusbar->position) - { - case BarTop: - si[i].y_org += statusbar->height; - case BarBot: - si[i].height -= statusbar->height; - break; - case BarLeft: - si[i].x_org += statusbar->height; - case BarRight: - si[i].width -= statusbar->height; - break; - } + if (statusbar) + switch(statusbar->position) + { + case BarTop: + area.y += statusbar->height; + case BarBot: + area.height -= statusbar->height; + break; + case BarLeft: + area.x += statusbar->height; + case BarRight: + area.width -= statusbar->height; + break; + } - return si; + return area; } /** Get display info * \param screen Screen number * \param statusbar the statusbar * \param padding Padding - * \return ScreenInfo struct pointer with all display info + * \return Area */ -ScreenInfo * -get_display_info(int screen, Statusbar *statusbar, Padding *padding) +Area +get_display_area(int screen, Statusbar *statusbar, Padding *padding) { - ScreenInfo *si; + Area area; - si = p_new(ScreenInfo, 1); + area.x = 0; + area.y = statusbar && statusbar->position == BarTop ? statusbar->height : 0; + area.width = DisplayWidth(globalconf.display, screen); + area.height = DisplayHeight(globalconf.display, screen) - + (statusbar && + (statusbar->position == BarTop || statusbar->position == BarBot) ? statusbar->height : 0); - si->x_org = 0; - si->y_org = statusbar && statusbar->position == BarTop ? statusbar->height : 0; - si->width = DisplayWidth(globalconf.display, screen); - si->height = DisplayHeight(globalconf.display, screen) - - (statusbar && (statusbar->position == BarTop || statusbar->position == BarBot) ? statusbar->height : 0); - - /* make padding corrections */ - if(padding) - { - si[screen].x_org+=padding->left; - si[screen].y_org+=padding->top; - si[screen].width-=padding->left+padding->right; - si[screen].height-=padding->top+padding->bottom; - } - - return si; + /* make padding corrections */ + if(padding) + { + area.x += padding->left; + area.y += padding->top; + area.width -= padding->left + padding->right; + area.height -= padding->top + padding->bottom; + } + return area; } /** Return the Xinerama screen number where the coordinates belongs to @@ -120,24 +123,20 @@ get_display_info(int screen, Statusbar *statusbar, Padding *padding) int get_screen_bycoord(int x, int y) { - ScreenInfo *si; int i; + Area area; /* don't waste our time */ if(!XineramaIsActive(globalconf.display)) return DefaultScreen(globalconf.display); - si = get_screen_info(0, NULL, NULL); - for(i = 0; i < get_screen_count(); i++) - if((x < 0 || (x >= si[i].x_org && x < si[i].x_org + si[i].width)) - && (y < 0 || (y >= si[i].y_org && y < si[i].y_org + si[i].height))) - { - p_delete(&si); + for(i = 0; i < get_screen_count(); i++){ + area = get_screen_area(i, NULL, NULL); + if((x < 0 || (x >= area.x && x < area.x + area.width)) + && (y < 0 || (y >= area.y && y < area.y + area.height))) return i; - } - - p_delete(&si); + } return DefaultScreen(globalconf.display); } @@ -181,6 +180,7 @@ move_client_to_screen(Client *c, int new_screen, Bool doresize) { Tag *tag; int old_screen = c->screen; + Area from, to; for(tag = globalconf.screens[old_screen].tags; tag; tag = tag->next) untag_client(c, tag, old_screen); @@ -192,28 +192,23 @@ move_client_to_screen(Client *c, int new_screen, Bool doresize) if(doresize && old_screen != c->screen) { - ScreenInfo *si, *si_old; - - si = get_screen_info(c->screen, NULL, NULL); - si_old = get_screen_info(old_screen, NULL, NULL); + to = get_screen_area(c->screen, NULL, NULL); + from = get_screen_area(old_screen, NULL, NULL); /* compute new coords in new screen */ - c->rx = (c->rx - si_old[old_screen].x_org) + si[c->screen].x_org; - c->ry = (c->ry - si_old[old_screen].y_org) + si[c->screen].y_org; + c->rx = (c->rx - from.x) + to.x; + c->ry = (c->ry - from.y) + to.y; /* check that new coords are still in the screen */ - if(c->rw > si[c->screen].width) - c->rw = si[c->screen].width; - if(c->rh > si[c->screen].height) - c->rh = si[c->screen].height; - if(c->rx + c->rw >= si[c->screen].x_org + si[c->screen].width) - c->rx = si[c->screen].x_org + si[c->screen].width - c->rw - 2 * c->border; - if(c->ry + c->rh >= si[c->screen].y_org + si[c->screen].height) - c->ry = si[c->screen].y_org + si[c->screen].height - c->rh - 2 * c->border; + if(c->rw > to.width) + c->rw = to.width; + if(c->rh > to.height) + c->rh = to.height; + if(c->rx + c->rw >= to.x + to.width) + c->rx = to.x + to.width - c->rw - 2 * c->border; + if(c->ry + c->rh >= to.y + to.height) + c->ry = to.y + to.height - c->rh - 2 * c->border; client_resize(c, c->rx, c->ry, c->rw, c->rh, True, False); - - p_delete(&si); - p_delete(&si_old); } focus(c, True, c->screen); @@ -231,12 +226,17 @@ move_mouse_pointer_to_screen(int screen) { if(XineramaIsActive(globalconf.display)) { - ScreenInfo *si = get_screen_info(screen, NULL, NULL); - XWarpPointer(globalconf.display, None, DefaultRootWindow(globalconf.display), 0, 0, 0, 0, si[screen].x_org, si[screen].y_org); - p_delete(&si); + Area area = get_screen_area(screen, NULL, NULL); + XWarpPointer(globalconf.display, + None, + DefaultRootWindow(globalconf.display), + 0, 0, 0, 0, area.x, area.y); } else - XWarpPointer(globalconf.display, None, RootWindow(globalconf.display, screen), 0, 0, 0, 0, 0, 0); + XWarpPointer(globalconf.display, + None, + RootWindow(globalconf.display, screen), + 0, 0, 0, 0, 0, 0); } diff --git a/screen.h b/screen.h index cc32c9ce9..2a264e588 100644 --- a/screen.h +++ b/screen.h @@ -28,8 +28,8 @@ typedef XineramaScreenInfo ScreenInfo; -ScreenInfo * get_screen_info(int, Statusbar *, Padding *); -ScreenInfo * get_display_info(int, Statusbar *, Padding *); +Area get_screen_area(int, Statusbar *, Padding *); +Area get_display_area(int, Statusbar *, Padding *); int get_screen_bycoord(int, int); int get_screen_count(void); int get_phys_screen(int); diff --git a/statusbar.c b/statusbar.c index 2928e2e2d..098bcbedf 100644 --- a/statusbar.c +++ b/statusbar.c @@ -110,19 +110,17 @@ statusbar_init(int screen) { XSetWindowAttributes wa; int phys_screen = get_phys_screen(screen); - ScreenInfo *si = get_screen_info(screen, - NULL, - &globalconf.screens[screen].padding); + Area area = get_screen_area(screen, + NULL, + &globalconf.screens[screen].padding); Statusbar *statusbar = globalconf.screens[screen].statusbar; statusbar->height = globalconf.screens[screen].font->height * 1.5; if(statusbar->position == BarRight || statusbar->position == BarLeft) - statusbar->width = si[screen].height; + statusbar->width = area.height; else - statusbar->width = si[screen].width; - - p_delete(&si); + statusbar->width = area.width; statusbar->screen = screen; @@ -181,9 +179,9 @@ statusbar_update_position(int screen) { XEvent ev; Statusbar *statusbar = globalconf.screens[screen].statusbar; - ScreenInfo *si = get_screen_info(statusbar->screen, - NULL, - &globalconf.screens[screen].padding); + Area area = get_screen_area(statusbar->screen, + NULL, + &globalconf.screens[screen].padding); XMapRaised(globalconf.display, statusbar->window); switch (statusbar->position) @@ -191,28 +189,25 @@ statusbar_update_position(int screen) default: XMoveWindow(globalconf.display, statusbar->window, - si[statusbar->screen].x_org, - si[statusbar->screen].y_org); + area.x, + area.y); break; case BarRight: XMoveWindow(globalconf.display, statusbar->window, - si[statusbar->screen].x_org + - (si[statusbar->screen].width - - statusbar->height), - si[statusbar->screen].y_org); + area.x + (area.width - statusbar->height), + area.y); break; case BarBot: XMoveWindow(globalconf.display, statusbar->window, - si[statusbar->screen].x_org, - si[statusbar->screen].height - statusbar->height); + area.x, + area.height - statusbar->height); break; case BarOff: XUnmapWindow(globalconf.display, statusbar->window); break; } - p_delete(&si); XSync(globalconf.display, False); while(XCheckMaskEvent(globalconf.display, EnterWindowMask, &ev)); }