Enlightenment CVS committal Author : kwo Project : e16 Module : e
Dir : e16/e/src Modified Files: arrange.c Log Message: New window placement algorithm. Should be better at handling crowded desktops and windows with never_use_area attribute. =================================================================== RCS file: /cvs/e/e16/e/src/arrange.c,v retrieving revision 1.100 retrieving revision 1.101 diff -u -3 -r1.100 -r1.101 --- arrange.c 29 Sep 2007 19:13:21 -0000 1.100 +++ arrange.c 27 Jan 2008 18:41:55 -0000 1.101 @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors - * Copyright (C) 2004-2007 Kim Woelders + * Copyright (C) 2004-2008 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -36,6 +36,12 @@ int p; } RectBox; +typedef struct +{ + int x, y; + int p; +} RectInfo; + static int ArrangeAddToList(int *array, int current_size, int value) { @@ -133,8 +139,7 @@ { for (x = x1; x <= x2; x++) { - if (Filled(x, y) <= sorted[j].p) - Filled(x, y) = sorted[j].p + 1; + Filled(x, y) += sorted[j].p; } } } @@ -155,92 +160,111 @@ } static void -ArrangeFindSpaces(const int *xarray, int xsize, const int *yarray, int ysize, - unsigned char *filled, RectBox * spaces, int *ns, - RectBox * fit, int must_fit) +ArrangeFindSpace(const int *xarray, int xsize, const int *yarray, int ysize, + unsigned char *filled, RectInfo * spaces, int *ns, + int wx, int wy, int ww, int wh) { - int i, j, x, y, x1, y1, xbest, ybest; - int num_spaces; - unsigned int a, abest; + int i, j, w, h, fw, fh, z1, z2; + unsigned int a; + int num_spaces = *ns; - /* create list of all "spaces" */ - num_spaces = 0; - for (y = 0; y < ysize - 1; y++) - { - for (x = 0; x < xsize - 1; x++) - { - /* if the square is empty "grow" the space */ - if (Filled(x, y) > fit->p) - continue; + if (wx < xarray[0] || (wx != xarray[0] && wx + ww > xarray[xsize - 1])) + return; + if (wy < yarray[0] || (wy != yarray[0] && wy + wh > yarray[ysize - 1])) + return; - xbest = x; - ybest = y; - abest = 0; - x1 = xsize - 1; -#if DEBUG_ARRANGE - Eprintf("Check %d,%d: %d,%d\n", x, y, xarray[x], yarray[y]); -#endif - for (j = y; j < ysize - 1;) - { - for (i = x; i < x1; i++) - { - if (Filled(i, j) > fit->p) - break; - } - x1 = i; - j++; - if (x1 <= x) - break; - if (must_fit && (xarray[x1] - xarray[x] < fit->w)) - continue; - for (; j < ysize - 1; j++) - { - for (i = x; i < x1; i++) - { - if (Filled(i, j) > fit->p) - goto got_one; - } - } - got_one: - y1 = j; - if (must_fit && (yarray[y1] - yarray[y] < fit->h)) - continue; - a = (xarray[x1] - xarray[x]) * (yarray[y1] - yarray[y]); + a = 0; + fh = wh; #if DEBUG_ARRANGE - Eprintf("Got %4d,%4d %4dx%4d: %d\n", xarray[x], - yarray[y], xarray[x1] - xarray[x], - yarray[y1] - yarray[y], a); + Eprintf("Check %d,%d %dx%d\n", wx, wy, ww, wh); #endif - if (a > abest) - { - xbest = x1; - ybest = y1; - abest = a; - } - } - if (abest == 0) + for (j = 0; j < ysize - 1; j++) + { + z2 = yarray[j + 1]; + if (z2 <= wy) + continue; + + z1 = wy > yarray[j] ? wy : yarray[j]; + z2 = wy + wh < z2 ? wy + wh : z2; + h = z2 - z1; + fw = ww; + for (i = 0; i < xsize - 1; i++) + { + z2 = xarray[i + 1]; + if (z2 < wx) continue; - spaces[num_spaces].x = xarray[x]; - spaces[num_spaces].y = yarray[y]; - spaces[num_spaces].w = xarray[xbest] - xarray[x]; - spaces[num_spaces].h = yarray[ybest] - yarray[y]; -#if 0 - spaces[num_spaces].p = spaces[num_spaces].w >= fit->w && - spaces[num_spaces].h >= fit->h; -#else - spaces[num_spaces].p = 1; -#endif - num_spaces++; + z1 = wx > xarray[i] ? wx : xarray[i]; + z2 = wx + ww < z2 ? wx + ww : z2; + w = z2 - z1; +#if DEBUG_ARRANGE > 1 + Eprintf("Add [%d,%d] %3dx%3d: %2d\n", i, j, w, h, Filled(i, j)); +#endif + a += w * h * Filled(i, j); + fw -= w; + if (fw <= 0) + break; + } + fh -= h; + if (fh <= 0) + break; + } + + spaces[num_spaces].x = wx; + spaces[num_spaces].y = wy; + spaces[num_spaces].p = a; + num_spaces++; + *ns = num_spaces; +} + +static void +ArrangeFindSpaces(const int *xarray, int xsize, const int *yarray, int ysize, + unsigned char *filled, RectInfo * spaces, int *ns, + RectBox * fit) +{ + int ix, iy, fx, fy, fw, fh, ns_max; + + /* create list of all "spaces" */ + *ns = 0; + ns_max = xsize > ysize ? xsize : ysize; + ns_max *= ns_max; + fw = fit->w; + fh = fit->h; + for (iy = 0; iy < ysize; iy++) + { + fy = yarray[iy]; + + for (ix = 0; ix < xsize; ix++) + { + fx = xarray[ix]; + + ArrangeFindSpace(xarray, xsize, yarray, ysize, filled, spaces, ns, + fx, fy, fw, fh); + if (*ns >= ns_max) + goto done; + ArrangeFindSpace(xarray, xsize, yarray, ysize, filled, spaces, ns, + fx - fw, fy, fw, fh); + if (*ns >= ns_max) + goto done; + ArrangeFindSpace(xarray, xsize, yarray, ysize, filled, spaces, ns, + fx, fy - fh, fw, fh); + if (*ns >= ns_max) + goto done; + ArrangeFindSpace(xarray, xsize, yarray, ysize, filled, spaces, ns, + fx - fw, fy - fh, fw, fh); + if (*ns >= ns_max) + goto done; } } + + done: + ; #if DEBUG_ARRANGE - for (j = 0; j < num_spaces; j++) + for (ix = 0; ix < *ns; ix++) Eprintf("Spaces: x,y=%4d,%4d wxh=%3dx%3d p=%2d\n", - spaces[j].x, spaces[j].y, spaces[j].w, spaces[j].h, spaces[j].p); + spaces[ix].x, spaces[ix].y, spaces[ix].w, spaces[ix].h, + spaces[ix].p); #endif - - *ns = num_spaces; } static void @@ -273,10 +297,9 @@ int num_sorted; int xsize = 0, ysize = 0; int *xarray, *yarray; - int *leftover; int i, j, k; unsigned char *filled; - RectBox *spaces; + RectInfo *spaces; int num_spaces; int sort; int a1, a2; @@ -351,10 +374,7 @@ yarray = EMALLOC(int, i); filled = EMALLOC(unsigned char, i * i); - spaces = EMALLOC(RectBox, i * i); - leftover = NULL; - if (floating_count) - leftover = EMALLOC(int, floating_count); + spaces = EMALLOC(RectInfo, i * i); if (!xarray || !yarray || !filled || !spaces) goto done; @@ -372,141 +392,26 @@ /* create list of all "spaces" */ ArrangeFindSpaces(xarray, xsize, yarray, ysize, filled, - spaces, &num_spaces, floating + i, 1); + spaces, &num_spaces, floating + i); /* find the first space that fits */ - k = -1; - sort = 0x7fffffff; - for (j = 0; j < num_spaces; j++) - { - if ((spaces[j].w < floating[i].w) || - (spaces[j].h < floating[i].h) || - (spaces[j].x < startx) || - (spaces[j].x + spaces[j].w > width) || - (spaces[j].y < starty) || (spaces[j].y + spaces[j].h > height)) - continue; - - if (policy == ARRANGE_BY_POSITION) - { - a1 = (spaces[j].x + (spaces[j].w >> 1)) - - (floating[i].x + (floating[i].w >> 1)); - a2 = (spaces[j].y + (spaces[j].h >> 1)) - - (floating[i].y + (floating[i].h >> 1)); - if (a1 < 0) - a1 = -a1; - if (a2 < 0) - a2 = -a2; - if ((a1 + a2) < sort) - { - sort = a1 + a2; - k = j; - } - } - else - { - k = j; - break; - } - } - - if (k >= 0) - { - if (policy == ARRANGE_BY_POSITION) - { - a1 = (spaces[k].x + (spaces[k].w >> 1)) - (floating[i].x + - (floating[i].w >> - 1)); - a2 = (spaces[k].y + (spaces[k].h >> 1)) - (floating[i].y + - (floating[i].h >> - 1)); - if (a1 >= 0) - { - sorted[num_sorted].x = spaces[k].x; - } - else - { - sorted[num_sorted].x = - spaces[k].x + spaces[k].w - floating[i].w; - } - if (a2 >= 0) - { - sorted[num_sorted].y = spaces[k].y; - } - else - { - sorted[num_sorted].y = - spaces[k].y + spaces[k].h - floating[i].h; - } - } - else - { - sorted[num_sorted].x = spaces[k].x; - sorted[num_sorted].y = spaces[k].y; - } - sorted[num_sorted].data = floating[i].data; - sorted[num_sorted].w = floating[i].w; - sorted[num_sorted].h = floating[i].h; - sorted[num_sorted].p = floating[i].p; - num_sorted++; - } - else - leftover[num_leftover++] = i; - } - -#if DEBUG_ARRANGE - Eprintf("Leftovers: %d\n", num_leftover); -#endif - /* ok we cant fit everything in this baby.... time to fit */ - /* the leftovers into the leftover space */ - for (i = 0; i < num_leftover; i++) - { - ArrangeMakeFillLists(startx, width, starty, height, sorted, num_sorted, - xarray, &xsize, yarray, &ysize, filled); - - /* create list of all "spaces" */ - ArrangeFindSpaces(xarray, xsize, yarray, ysize, filled, - spaces, &num_spaces, floating + leftover[i], 0); - - /* find the first space that fits */ - k = -1; - sort = 0x7fffffff; - a1 = floating[leftover[i]].w * floating[leftover[i]].h; - k = -1; - for (j = 0; j < num_spaces; j++) - { - a2 = spaces[j].w * spaces[j].h; - if ((a2 != 0) && ((a1 - a2) < sort) && (spaces[j].p)) - { - k = j; - sort = a1 - a2; - } - } - - if (k >= 0) + k = 0; + sort = 0x7fffffff; /* NB! Break at 0 == free space */ + for (j = 0; j < num_spaces && sort; j++) { - /* if there's a small space ... */ - sorted[num_sorted].x = spaces[k].x; - sorted[num_sorted].y = spaces[k].y; + if (spaces[j].p >= sort) + continue; + sort = spaces[j].p; + k = j; + if (sort == 0) + break; } - else - { - /* there is no room - put it centered */ - /* (but dont put top left off screen) */ - sorted[num_sorted].x = (width - floating[leftover[i]].w) / 2; - sorted[num_sorted].y = (height - floating[leftover[i]].h) / 2; - } - sorted[num_sorted].data = floating[leftover[i]].data; - sorted[num_sorted].w = floating[leftover[i]].w; - sorted[num_sorted].h = floating[leftover[i]].h; - sorted[num_sorted].p = floating[leftover[i]].p; - if ((sorted[num_sorted].x + sorted[num_sorted].w) > width) - sorted[num_sorted].x = width - sorted[num_sorted].w; - if ((sorted[num_sorted].y + sorted[num_sorted].h) > height) - sorted[num_sorted].y = height - sorted[num_sorted].h; - if (sorted[num_sorted].x < startx) - sorted[num_sorted].x = startx; - if (sorted[num_sorted].y < starty) - sorted[num_sorted].y = starty; + sorted[num_sorted].x = spaces[k].x; + sorted[num_sorted].y = spaces[k].y; + sorted[num_sorted].data = floating[i].data; + sorted[num_sorted].w = floating[i].w; + sorted[num_sorted].h = floating[i].h; + sorted[num_sorted].p = floating[i].p; num_sorted++; } @@ -514,7 +419,7 @@ for (i = 0; i < num_sorted; i++) Eprintf("Sorted: x,y=%4d,%4d wxh=%3dx%3d p=%2d: %s\n", sorted[i].x, sorted[i].y, sorted[i].w, sorted[i].h, sorted[i].p, - (sorted[i].data) ? ((EObj *) sorted[i].data)->name : "?"); + (sorted[i].data) ? EobjGetName((EObj *) sorted[i].data) : "?"); #endif done: @@ -527,8 +432,6 @@ Efree(filled); if (spaces) Efree(spaces); - if (leftover) - Efree(leftover); } void @@ -834,7 +737,8 @@ rb->p = EoGetLayer(ew); #if DEBUG_ARRANGE Eprintf("Add float: x,y=%4d,%4d wxh=%3dx%3d p=%2d: %s\n", - rb->x, rb->y, rb->w, rb->h, rb->p, eo->name); + rb->x, rb->y, rb->w, rb->h, rb->p, + EobjGetName(eo)); #endif continue; } @@ -843,7 +747,7 @@ rb->data = ew; if (ew->props.never_use_area) - rb->p = 50; + rb->p = 100; else rb->p = EoGetLayer(ew); } @@ -890,7 +794,7 @@ rb->h = h; #if DEBUG_ARRANGE Eprintf("Add fixed: x,y=%4d,%4d wxh=%3dx%3d p=%2d: %s\n", rb->x, rb->y, - rb->w, rb->h, rb->p, eo->name); + rb->w, rb->h, rb->p, EobjGetName(eo)); #endif nfix++; ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs