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.
This commit is contained in:
Aldo Cortesi 2007-12-23 10:54:59 +11:00 committed by Julien Danjou
parent 51379e065b
commit 5f079ef73e
11 changed files with 187 additions and 192 deletions

View File

@ -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,
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,
area = get_display_area(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);
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)

View File

@ -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
{

View File

@ -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,

View File

@ -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,
Area area = get_screen_area(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,
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,
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,
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

View File

@ -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,
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

View File

@ -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

View File

@ -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

21
mouse.c
View File

@ -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,7 +54,7 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused)))
else
restack(screen);
si = get_screen_info(c->screen,
area = get_screen_area(c->screen,
globalconf.screens[screen].statusbar,
&globalconf.screens[screen].padding);
@ -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;
}

140
screen.c
View File

@ -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++)
if (statusbar)
switch(statusbar->position)
{
case BarTop:
si[i].y_org += statusbar->height;
area.y += statusbar->height;
case BarBot:
si[i].height -= statusbar->height;
area.height -= statusbar->height;
break;
case BarLeft:
si[i].x_org += statusbar->height;
area.x += statusbar->height;
case BarRight:
si[i].width -= statusbar->height;
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);
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);
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);
/* 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;
}
return si;
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);
}

View File

@ -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);

View File

@ -110,7 +110,7 @@ statusbar_init(int screen)
{
XSetWindowAttributes wa;
int phys_screen = get_phys_screen(screen);
ScreenInfo *si = get_screen_info(screen,
Area area = get_screen_area(screen,
NULL,
&globalconf.screens[screen].padding);
Statusbar *statusbar = globalconf.screens[screen].statusbar;
@ -118,11 +118,9 @@ statusbar_init(int screen)
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,7 +179,7 @@ statusbar_update_position(int screen)
{
XEvent ev;
Statusbar *statusbar = globalconf.screens[screen].statusbar;
ScreenInfo *si = get_screen_info(statusbar->screen,
Area area = get_screen_area(statusbar->screen,
NULL,
&globalconf.screens[screen].padding);
@ -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));
}