summaryrefslogtreecommitdiff
path: root/beryl-plugins/src/place.c
diff options
context:
space:
mode:
authorracarr <racarr@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-12-18 04:22:26 +0000
committerracarr <racarr@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-12-18 04:22:26 +0000
commit1c73601946ee1779c0a7a49373dd7cb6df88e16f (patch)
treedab16d079da0deb046b18eecd47f1e51bb704495 /beryl-plugins/src/place.c
parent348bae4cdd40a155c87ce7be92e8752ffa74a5aa (diff)
downloadmarex-dev-1c73601946ee1779c0a7a49373dd7cb6df88e16f.tar.gz
marex-dev-1c73601946ee1779c0a7a49373dd7cb6df88e16f.tar.bz2
Run indent.sh on beryl-plugins most of the files had such mixed coding styles it was a real pain to work with
git-svn-id: file:///beryl/trunk@1849 d7aaf104-2d23-0410-ae22-9d23157bf5a3
Diffstat (limited to 'beryl-plugins/src/place.c')
-rw-r--r--beryl-plugins/src/place.c2116
1 files changed, 1093 insertions, 1023 deletions
diff --git a/beryl-plugins/src/place.c b/beryl-plugins/src/place.c
index e7dbd08..331dd74 100644
--- a/beryl-plugins/src/place.c
+++ b/beryl-plugins/src/place.c
@@ -36,30 +36,34 @@
static int displayPrivateIndex;
-typedef struct _PlaceDisplay {
- int screenPrivateIndex;
- // HandleEventProc handleEvent;
+typedef struct _PlaceDisplay
+{
+ int screenPrivateIndex;
+ // HandleEventProc handleEvent;
} PlaceDisplay;
#define PLACE_SCREEN_OPTION_WORKAROUND 0
#define PLACE_SCREEN_OPTION_MODE 1
#define PLACE_SCREEN_OPTION_NUM 2
-typedef struct _PlaceScreen {
- CompOption opt[PLACE_SCREEN_OPTION_NUM];
+typedef struct _PlaceScreen
+{
+ CompOption opt[PLACE_SCREEN_OPTION_NUM];
- DamageWindowRectProc damageWindowRect;
- int placeMode;
+ DamageWindowRectProc damageWindowRect;
+ int placeMode;
} PlaceScreen;
-typedef enum _PlaceMode{
- PlaceModeCascade,
- PlaceModeCentered,
- PlaceModeRandom,
- PlaceModeIntelligent,
- } PlaceMode;
+typedef enum _PlaceMode
+{
+ PlaceModeCascade,
+ PlaceModeCentered,
+ PlaceModeRandom,
+ PlaceModeIntelligent,
+} PlaceMode;
-char *placeModes[] = { N_("Cascade"),N_("Centered"),N_("Random"),N_("Intelligent") };
+char *placeModes[] =
+ { N_("Cascade"), N_("Centered"), N_("Random"), N_("Intelligent") };
#define PLACE_MODE_DEFAULT PlaceModeIntelligent
#define NUM_PLACE_MODES 4
@@ -79,564 +83,601 @@ char *placeModes[] = { N_("Cascade"),N_("Centered"),N_("Random"),N_("Intelligent
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
static Bool
-placeSetScreenOption(CompScreen * screen,
- char *name, CompOptionValue * value)
+placeSetScreenOption (CompScreen * screen,
+ char *name, CompOptionValue * value)
{
- CompOption *o;
- int index;
-
- PLACE_SCREEN(screen);
-
- o = compFindOption(ps->opt, NUM_OPTIONS(ps), name, &index);
- if (!o)
- return FALSE;
-
- switch (index) {
- case PLACE_SCREEN_OPTION_WORKAROUND:
- if (compSetBoolOption(o, value))
- return TRUE;
- break;
- case PLACE_SCREEN_OPTION_MODE:
- if (compSetStringOption (o,value))
- {
- int i;
- for (i = 0; i < NUM_PLACE_MODES; i++)
- if (strcmp (placeModes[i], o->value.s)==0)
- ps->placeMode = (PlaceMode) i;
- }
- default:
- break;
- }
-
- return FALSE;
+ CompOption *o;
+ int index;
+
+ PLACE_SCREEN (screen);
+
+ o = compFindOption (ps->opt, NUM_OPTIONS (ps), name, &index);
+ if (!o)
+ return FALSE;
+
+ switch (index)
+ {
+ case PLACE_SCREEN_OPTION_WORKAROUND:
+ if (compSetBoolOption (o, value))
+ return TRUE;
+ break;
+ case PLACE_SCREEN_OPTION_MODE:
+ if (compSetStringOption (o, value))
+ {
+ int i;
+ for (i = 0; i < NUM_PLACE_MODES; i++)
+ if (strcmp (placeModes[i], o->value.s) == 0)
+ ps->placeMode = (PlaceMode) i;
+ }
+ default:
+ break;
+ }
+
+ return FALSE;
}
-static void placeScreenInitOptions(PlaceScreen * ps)
+static void
+placeScreenInitOptions (PlaceScreen * ps)
{
- CompOption *o;
-
- o = &ps->opt[PLACE_SCREEN_OPTION_WORKAROUND];
- o->name = "workarounds";
- o->group = N_("");
- o->subGroup = N_("");
- o->displayHints = "";
- o->shortDesc = N_("Workarounds");
- o->longDesc = N_("Window placement workarounds");
- o->type = CompOptionTypeBool;
- o->value.b = PLACE_WORKAROUND_DEFAULT;
-
- o = &ps->opt[PLACE_SCREEN_OPTION_MODE];
- o->name = "place_mode";
- o->shortDesc = N_("Placement Mode");
- o->longDesc = N_("Cascade, Random or Centered");
- o->type = CompOptionTypeString;
- o->value.s = strdup (placeModes[PLACE_MODE_DEFAULT]);
- o->rest.s.string = placeModes;
- o->rest.s.nString = NUM_PLACE_MODES;
-
- o = &ps->opt[PLACE_SCREEN_OPTION_MODE];
- o->name = "place_mode";
- o->group = N_("");
- o->subGroup = N_("");
- o->displayHints = "";
- o->shortDesc = N_("Placement Mode");
- o->longDesc = N_("Window placement technique");
- o->type = CompOptionTypeString;
- o->value.s = strdup(placeModes[PLACE_MODE_DEFAULT]);
- o->rest.s.string = placeModes;
- o->rest.s.nString = NUM_PLACE_MODES;
-
+ CompOption *o;
+
+ o = &ps->opt[PLACE_SCREEN_OPTION_WORKAROUND];
+ o->name = "workarounds";
+ o->group = N_("");
+ o->subGroup = N_("");
+ o->displayHints = "";
+ o->shortDesc = N_("Workarounds");
+ o->longDesc = N_("Window placement workarounds");
+ o->type = CompOptionTypeBool;
+ o->value.b = PLACE_WORKAROUND_DEFAULT;
+
+ o = &ps->opt[PLACE_SCREEN_OPTION_MODE];
+ o->name = "place_mode";
+ o->shortDesc = N_("Placement Mode");
+ o->longDesc = N_("Cascade, Random or Centered");
+ o->type = CompOptionTypeString;
+ o->value.s = strdup (placeModes[PLACE_MODE_DEFAULT]);
+ o->rest.s.string = placeModes;
+ o->rest.s.nString = NUM_PLACE_MODES;
+
+ o = &ps->opt[PLACE_SCREEN_OPTION_MODE];
+ o->name = "place_mode";
+ o->group = N_("");
+ o->subGroup = N_("");
+ o->displayHints = "";
+ o->shortDesc = N_("Placement Mode");
+ o->longDesc = N_("Window placement technique");
+ o->type = CompOptionTypeString;
+ o->value.s = strdup (placeModes[PLACE_MODE_DEFAULT]);
+ o->rest.s.string = placeModes;
+ o->rest.s.nString = NUM_PLACE_MODES;
+
}
-static CompOption *placeGetScreenOptions(CompScreen * screen, int *count)
+static CompOption *
+placeGetScreenOptions (CompScreen * screen, int *count)
{
- if (screen) {
- PLACE_SCREEN(screen);
-
- *count = NUM_OPTIONS(ps);
- return ps->opt;
- } else {
- PlaceScreen *ps = malloc(sizeof(PlaceScreen));
- placeScreenInitOptions(ps);
- *count = NUM_OPTIONS(ps);
- return ps->opt;
- }
+ if (screen)
+ {
+ PLACE_SCREEN (screen);
+
+ *count = NUM_OPTIONS (ps);
+ return ps->opt;
+ }
+ else
+ {
+ PlaceScreen *ps = malloc (sizeof (PlaceScreen));
+ placeScreenInitOptions (ps);
+ *count = NUM_OPTIONS (ps);
+ return ps->opt;
+ }
}
-typedef enum {
- PlaceLeft,
- PlaceRight,
- PlaceTop,
- PlaceBottom
+typedef enum
+{
+ PlaceLeft,
+ PlaceRight,
+ PlaceTop,
+ PlaceBottom
} PlaceWindowDirection;
static Bool
-rectangleIntersect(XRectangle * src1, XRectangle * src2, XRectangle * dest)
+rectangleIntersect (XRectangle * src1, XRectangle * src2, XRectangle * dest)
{
- int dest_x, dest_y;
- int dest_w, dest_h;
- int return_val;
-
- g_return_val_if_fail(src1 != NULL, FALSE);
- g_return_val_if_fail(src2 != NULL, FALSE);
- g_return_val_if_fail(dest != NULL, FALSE);
-
- return_val = FALSE;
-
- dest_x = MAX(src1->x, src2->x);
- dest_y = MAX(src1->y, src2->y);
- dest_w =
- MIN(src1->x + src1->width, src2->x + src2->width) - dest_x;
- dest_h =
- MIN(src1->y + src1->height, src2->y + src2->height) - dest_y;
-
- if (dest_w > 0 && dest_h > 0) {
- dest->x = dest_x;
- dest->y = dest_y;
- dest->width = dest_w;
- dest->height = dest_h;
- return_val = TRUE;
- } else {
- dest->width = 0;
- dest->height = 0;
- }
-
- return return_val;
+ int dest_x, dest_y;
+ int dest_w, dest_h;
+ int return_val;
+
+ g_return_val_if_fail (src1 != NULL, FALSE);
+ g_return_val_if_fail (src2 != NULL, FALSE);
+ g_return_val_if_fail (dest != NULL, FALSE);
+
+ return_val = FALSE;
+
+ dest_x = MAX (src1->x, src2->x);
+ dest_y = MAX (src1->y, src2->y);
+ dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
+ dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
+
+ if (dest_w > 0 && dest_h > 0)
+ {
+ dest->x = dest_x;
+ dest->y = dest_y;
+ dest->width = dest_w;
+ dest->height = dest_h;
+ return_val = TRUE;
+ }
+ else
+ {
+ dest->width = 0;
+ dest->height = 0;
+ }
+
+ return return_val;
}
-static gint northwestcmp(gconstpointer a, gconstpointer b)
+static gint
+northwestcmp (gconstpointer a, gconstpointer b)
{
- CompWindow *aw = (gpointer) a;
- CompWindow *bw = (gpointer) b;
- int from_origin_a;
- int from_origin_b;
- int ax, ay, bx, by;
-
- ax = aw->attrib.x - aw->input.left;
- ay = aw->attrib.y - aw->input.top;
-
- bx = bw->attrib.x - bw->input.left;
- by = bw->attrib.y - bw->input.top;
-
- /* probably there's a fast good-enough-guess we could use here. */
- from_origin_a = sqrt(ax * ax + ay * ay);
- from_origin_b = sqrt(bx * bx + by * by);
-
- if (from_origin_a < from_origin_b)
- return -1;
- else if (from_origin_a > from_origin_b)
- return 1;
- else
- return 0;
+ CompWindow *aw = (gpointer) a;
+ CompWindow *bw = (gpointer) b;
+ int from_origin_a;
+ int from_origin_b;
+ int ax, ay, bx, by;
+
+ ax = aw->attrib.x - aw->input.left;
+ ay = aw->attrib.y - aw->input.top;
+
+ bx = bw->attrib.x - bw->input.left;
+ by = bw->attrib.y - bw->input.top;
+
+ /* probably there's a fast good-enough-guess we could use here. */
+ from_origin_a = sqrt (ax * ax + ay * ay);
+ from_origin_b = sqrt (bx * bx + by * by);
+
+ if (from_origin_a < from_origin_b)
+ return -1;
+ else if (from_origin_a > from_origin_b)
+ return 1;
+ else
+ return 0;
}
static void
-get_workarea_of_current_output_device(CompScreen * s, XRectangle * area)
+get_workarea_of_current_output_device (CompScreen * s, XRectangle * area)
{
- int head;
+ int head;
- head = screenGetCurrentOutputDev(s);
- screenGetOutputDevWorkArea(s, head, area);
+ head = screenGetCurrentOutputDev (s);
+ screenGetOutputDevWorkArea (s, head, area);
}
-static void placeCentered(CompWindow *window, int *x, int *y){
- *x = window->screen->workArea.x + (window->screen->workArea.width
- - GET_WINDOW_WIDTH(window)) /2;
- *y = window->screen->workArea.y + (window->screen->workArea.height
- - GET_WINDOW_HEIGHT(window)) /2;
+static void
+placeCentered (CompWindow * window, int *x, int *y)
+{
+ *x = window->screen->workArea.x + (window->screen->workArea.width
+ - GET_WINDOW_WIDTH (window)) / 2;
+ *y = window->screen->workArea.y + (window->screen->workArea.height
+ - GET_WINDOW_HEIGHT (window)) / 2;
}
-static void placeRandom(CompWindow *window, int *x, int *y){
- *x = rand() % (window->screen->workArea.width - window->screen->workArea.x);
- *y = rand() % (window->screen->workArea.height - window->screen->workArea.y);
+static void
+placeRandom (CompWindow * window, int *x, int *y)
+{
+ *x = rand () % (window->screen->workArea.width -
+ window->screen->workArea.x);
+ *y = rand () % (window->screen->workArea.height -
+ window->screen->workArea.y);
}
-
-
+
+
static void
-find_next_cascade(CompWindow * window,
- GList * windows, int x, int y, int *new_x, int *new_y)
+find_next_cascade (CompWindow * window,
+ GList * windows, int x, int y, int *new_x, int *new_y)
{
- GList *tmp;
- GList *sorted;
- int cascade_x, cascade_y;
- int x_threshold, y_threshold;
- int window_width, window_height;
- int cascade_stage;
- XRectangle work_area;
-
- sorted = g_list_copy(windows);
- sorted = g_list_sort(sorted, northwestcmp);
-
- /* This is a "fuzzy" cascade algorithm.
- * For each window in the list, we find where we'd cascade a
- * new window after it. If a window is already nearly at that
- * position, we move on.
- */
-
- /* arbitrary-ish threshold, honors user attempts to
- * manually cascade.
- */
+ GList *tmp;
+ GList *sorted;
+ int cascade_x, cascade_y;
+ int x_threshold, y_threshold;
+ int window_width, window_height;
+ int cascade_stage;
+ XRectangle work_area;
+
+ sorted = g_list_copy (windows);
+ sorted = g_list_sort (sorted, northwestcmp);
+
+ /* This is a "fuzzy" cascade algorithm.
+ * For each window in the list, we find where we'd cascade a
+ * new window after it. If a window is already nearly at that
+ * position, we move on.
+ */
+
+ /* arbitrary-ish threshold, honors user attempts to
+ * manually cascade.
+ */
#define CASCADE_FUZZ 15
- x_threshold = MAX(window->input.left, CASCADE_FUZZ);
- y_threshold = MAX(window->input.top, CASCADE_FUZZ);
-
- /* Find furthest-SE origin of all workspaces.
- * cascade_x, cascade_y are the target position
- * of NW corner of window frame.
- */
-
- get_workarea_of_current_output_device(window->screen, &work_area);
-
- cascade_x = MAX(0, work_area.x);
- cascade_y = MAX(0, work_area.y);
-
- /* Find first cascade position that's not used. */
-
- window_width = GET_WINDOW_WIDTH(window) + window->input.left +
- window->input.right;
- window_height = GET_WINDOW_HEIGHT(window) + window->input.top +
- window->input.bottom;
-
- cascade_stage = 0;
- tmp = sorted;
- while (tmp != NULL) {
- CompWindow *w;
- int wx, wy;
-
- w = tmp->data;
-
- /* we want frame position, not window position */
- wx = w->attrib.x - w->input.left;
- wy = w->attrib.y - w->input.top;
-
- if (ABS(wx - cascade_x) < x_threshold &&
- ABS(wy - cascade_y) < y_threshold) {
- /* This window is "in the way", move to next cascade
- * point. The new window frame should go at the origin
- * of the client window we're stacking above.
- */
- wx = w->attrib.x;
- wy = w->attrib.y;
-
- cascade_x = wx;
- cascade_y = wy;
-
- /* If we go off the screen, start over with a new cascade */
- if (((cascade_x + window_width) >
- (work_area.x + work_area.width)) ||
- ((cascade_y + window_height) >
- (work_area.y + work_area.height))) {
- cascade_x = MAX(0, work_area.x);
- cascade_y = MAX(0, work_area.y);
-
-#define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */
-
- cascade_stage += 1;
- cascade_x +=
- CASCADE_INTERVAL * cascade_stage;
-
- /* start over with a new cascade translated to the right,
- * unless we are out of space
- */
- if ((cascade_x + window_width) <
- (work_area.x + work_area.width)) {
- tmp = sorted;
- continue;
- } else {
- /* All out of space, this cascade_x won't work */
- cascade_x = MAX(0, work_area.x);
- break;
- }
- }
- } else {
- /* Keep searching for a further-down-the-diagonal window. */
- }
-
- tmp = tmp->next;
- }
-
- /* cascade_x and cascade_y will match the last window in the list
- * that was "in the way" (in the approximate cascade diagonal)
- */
-
- g_list_free(sorted);
-
- /* Convert coords to position of window, not position of frame. */
- *new_x = cascade_x + window->input.left;
- *new_y = cascade_y + window->input.top;
+ x_threshold = MAX (window->input.left, CASCADE_FUZZ);
+ y_threshold = MAX (window->input.top, CASCADE_FUZZ);
+
+ /* Find furthest-SE origin of all workspaces.
+ * cascade_x, cascade_y are the target position
+ * of NW corner of window frame.
+ */
+
+ get_workarea_of_current_output_device (window->screen, &work_area);
+
+ cascade_x = MAX (0, work_area.x);
+ cascade_y = MAX (0, work_area.y);
+
+ /* Find first cascade position that's not used. */
+
+ window_width = GET_WINDOW_WIDTH (window) + window->input.left +
+ window->input.right;
+ window_height = GET_WINDOW_HEIGHT (window) + window->input.top +
+ window->input.bottom;
+
+ cascade_stage = 0;
+ tmp = sorted;
+ while (tmp != NULL)
+ {
+ CompWindow *w;
+ int wx, wy;
+
+ w = tmp->data;
+
+ /* we want frame position, not window position */
+ wx = w->attrib.x - w->input.left;
+ wy = w->attrib.y - w->input.top;
+
+ if (ABS (wx - cascade_x) < x_threshold &&
+ ABS (wy - cascade_y) < y_threshold)
+ {
+ /* This window is "in the way", move to next cascade
+ * point. The new window frame should go at the origin
+ * of the client window we're stacking above.
+ */
+ wx = w->attrib.x;
+ wy = w->attrib.y;
+
+ cascade_x = wx;
+ cascade_y = wy;
+
+ /* If we go off the screen, start over with a new cascade */
+ if (((cascade_x + window_width) >
+ (work_area.x + work_area.width)) ||
+ ((cascade_y + window_height) >
+ (work_area.y + work_area.height)))
+ {
+ cascade_x = MAX (0, work_area.x);
+ cascade_y = MAX (0, work_area.y);
+
+#define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */
+
+ cascade_stage += 1;
+ cascade_x += CASCADE_INTERVAL * cascade_stage;
+
+ /* start over with a new cascade translated to the right,
+ * unless we are out of space
+ */
+ if ((cascade_x + window_width) <
+ (work_area.x + work_area.width))
+ {
+ tmp = sorted;
+ continue;
+ }
+ else
+ {
+ /* All out of space, this cascade_x won't work */
+ cascade_x = MAX (0, work_area.x);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Keep searching for a further-down-the-diagonal window. */
+ }
+
+ tmp = tmp->next;
+ }
+
+ /* cascade_x and cascade_y will match the last window in the list
+ * that was "in the way" (in the approximate cascade diagonal)
+ */
+
+ g_list_free (sorted);
+
+ /* Convert coords to position of window, not position of frame. */
+ *new_x = cascade_x + window->input.left;
+ *new_y = cascade_y + window->input.top;
}
static void
-find_most_freespace(CompWindow * window,
- CompWindow * focus_window,
- int x, int y, int *new_x, int *new_y)
+find_most_freespace (CompWindow * window,
+ CompWindow * focus_window,
+ int x, int y, int *new_x, int *new_y)
{
- PlaceWindowDirection side;
- int max_area;
- int max_width, max_height, left, right, top, bottom;
- int left_space, right_space, top_space, bottom_space;
- int frame_size_left, frame_size_top;
- XRectangle work_area;
- XRectangle avoid;
- XRectangle outer;
-
- frame_size_left = window->input.left;
- frame_size_top = window->input.top;
-
- get_workarea_of_current_output_device(window->screen, &work_area);
-
- getOuterRectOfWindow(focus_window, &avoid);
- getOuterRectOfWindow(window, &outer);
-
- /* Find the areas of choosing the various sides of the focus window */
- max_width = MIN(avoid.width, outer.width);
- max_height = MIN(avoid.height, outer.height);
- left_space = avoid.x - work_area.x;
- right_space =
- work_area.width - (avoid.x + avoid.width - work_area.x);
- top_space = avoid.y - work_area.y;
- bottom_space =
- work_area.height - (avoid.y + avoid.height - work_area.y);
- left = MIN(left_space, outer.width);
- right = MIN(right_space, outer.width);
- top = MIN(top_space, outer.height);
- bottom = MIN(bottom_space, outer.height);
-
- /* Find out which side of the focus_window can show the most of the
- * window
- */
- side = PlaceLeft;
- max_area = left * max_height;
- if (right * max_height > max_area) {
- side = PlaceRight;
- max_area = right * max_height;
- }
- if (top * max_width > max_area) {
- side = PlaceTop;
- max_area = top * max_width;
- }
- if (bottom * max_width > max_area) {
- side = PlaceBottom;
- max_area = bottom * max_width;
- }
-
- /* Give up if there's no where to put it
- * (i.e. focus window is maximized)
- */
- if (max_area == 0)
- return;
-
- /* Place the window on the relevant side; if the whole window fits,
- * make it adjacent to the focus window; if not, make sure the
- * window doesn't go off the edge of the screen.
- */
- switch (side) {
- case PlaceLeft:
- *new_y = avoid.y + frame_size_top;
- if (left_space > outer.width)
- *new_x = avoid.x - outer.width + frame_size_left;
- else
- *new_x = work_area.x + frame_size_left;
- break;
- case PlaceRight:
- *new_y = avoid.y + frame_size_top;
- if (right_space > outer.width)
- *new_x = avoid.x + avoid.width + frame_size_left;
- else
- *new_x =
- work_area.x + work_area.width - outer.width +
- frame_size_left;
- break;
- case PlaceTop:
- *new_x = avoid.x + frame_size_left;
- if (top_space > outer.height)
- *new_y = avoid.y - outer.height + frame_size_top;
- else
- *new_y = work_area.y + frame_size_top;
- break;
- case PlaceBottom:
- *new_x = avoid.x + frame_size_left;
- if (bottom_space > outer.height)
- *new_y = avoid.y + avoid.height + frame_size_top;
- else
- *new_y =
- work_area.y + work_area.height - outer.height +
- frame_size_top;
- break;
- }
+ PlaceWindowDirection side;
+ int max_area;
+ int max_width, max_height, left, right, top, bottom;
+ int left_space, right_space, top_space, bottom_space;
+ int frame_size_left, frame_size_top;
+ XRectangle work_area;
+ XRectangle avoid;
+ XRectangle outer;
+
+ frame_size_left = window->input.left;
+ frame_size_top = window->input.top;
+
+ get_workarea_of_current_output_device (window->screen, &work_area);
+
+ getOuterRectOfWindow (focus_window, &avoid);
+ getOuterRectOfWindow (window, &outer);
+
+ /* Find the areas of choosing the various sides of the focus window */
+ max_width = MIN (avoid.width, outer.width);
+ max_height = MIN (avoid.height, outer.height);
+ left_space = avoid.x - work_area.x;
+ right_space = work_area.width - (avoid.x + avoid.width - work_area.x);
+ top_space = avoid.y - work_area.y;
+ bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y);
+ left = MIN (left_space, outer.width);
+ right = MIN (right_space, outer.width);
+ top = MIN (top_space, outer.height);
+ bottom = MIN (bottom_space, outer.height);
+
+ /* Find out which side of the focus_window can show the most of the
+ * window
+ */
+ side = PlaceLeft;
+ max_area = left * max_height;
+ if (right * max_height > max_area)
+ {
+ side = PlaceRight;
+ max_area = right * max_height;
+ }
+ if (top * max_width > max_area)
+ {
+ side = PlaceTop;
+ max_area = top * max_width;
+ }
+ if (bottom * max_width > max_area)
+ {
+ side = PlaceBottom;
+ max_area = bottom * max_width;
+ }
+
+ /* Give up if there's no where to put it
+ * (i.e. focus window is maximized)
+ */
+ if (max_area == 0)
+ return;
+
+ /* Place the window on the relevant side; if the whole window fits,
+ * make it adjacent to the focus window; if not, make sure the
+ * window doesn't go off the edge of the screen.
+ */
+ switch (side)
+ {
+ case PlaceLeft:
+ *new_y = avoid.y + frame_size_top;
+ if (left_space > outer.width)
+ *new_x = avoid.x - outer.width + frame_size_left;
+ else
+ *new_x = work_area.x + frame_size_left;
+ break;
+ case PlaceRight:
+ *new_y = avoid.y + frame_size_top;
+ if (right_space > outer.width)
+ *new_x = avoid.x + avoid.width + frame_size_left;
+ else
+ *new_x =
+ work_area.x + work_area.width - outer.width + frame_size_left;
+ break;
+ case PlaceTop:
+ *new_x = avoid.x + frame_size_left;
+ if (top_space > outer.height)
+ *new_y = avoid.y - outer.height + frame_size_top;
+ else
+ *new_y = work_area.y + frame_size_top;
+ break;
+ case PlaceBottom:
+ *new_x = avoid.x + frame_size_left;
+ if (bottom_space > outer.height)
+ *new_y = avoid.y + avoid.height + frame_size_top;
+ else
+ *new_y =
+ work_area.y + work_area.height - outer.height +
+ frame_size_top;
+ break;
+ }
}
static void
-avoid_being_obscured_as_second_modal_dialog(CompWindow * window,
- int *x, int *y)
+avoid_being_obscured_as_second_modal_dialog (CompWindow * window,
+ int *x, int *y)
{
- /* We can't center this dialog if it was denied focus and it
- * overlaps with the focus window and this dialog is modal and this
- * dialog is in the same app as the focus window (*phew*...please
- * don't make me say that ten times fast). See bug 307875 comment 11
- * and 12 for details, but basically it means this is probably a
- * second modal dialog for some app while the focus window is the
- * first modal dialog. We should probably make them simultaneously
- * visible in general, but it becomes mandatory to do so due to
- * buggy apps (e.g. those using gtk+ *sigh*) because in those cases
- * this second modal dialog also happens to be modal to the first
- * dialog in addition to the main window, while it has only let us
- * know about the modal-to-the-main-window part.
- */
-
- CompWindow *focus_window;
-
- focus_window =
- findWindowAtDisplay(window->screen->display,
- window->screen->display->activeWindow);
+ /* We can't center this dialog if it was denied focus and it
+ * overlaps with the focus window and this dialog is modal and this
+ * dialog is in the same app as the focus window (*phew*...please
+ * don't make me say that ten times fast). See bug 307875 comment 11
+ * and 12 for details, but basically it means this is probably a
+ * second modal dialog for some app while the focus window is the
+ * first modal dialog. We should probably make them simultaneously
+ * visible in general, but it becomes mandatory to do so due to
+ * buggy apps (e.g. those using gtk+ *sigh*) because in those cases
+ * this second modal dialog also happens to be modal to the first
+ * dialog in addition to the main window, while it has only let us
+ * know about the modal-to-the-main-window part.
+ */
+
+ CompWindow *focus_window;
+
+ focus_window =
+ findWindowAtDisplay (window->screen->display,
+ window->screen->display->activeWindow);
}
static gboolean
-rectangle_overlaps_some_window(XRectangle * rect, GList * windows)
+rectangle_overlaps_some_window (XRectangle * rect, GList * windows)
{
- GList *tmp;
- XRectangle dest;
-
- tmp = windows;
- while (tmp != NULL) {
- CompWindow *other = tmp->data;
- XRectangle other_rect;
-
- switch (other->type) {
- case CompWindowTypeDockMask:
- case CompWindowTypeSplashMask:
- case CompWindowTypeDesktopMask:
- case CompWindowTypeDialogMask:
- case CompWindowTypeModalDialogMask:
- case CompWindowTypeFullscreenMask:
- case CompWindowTypeUnknownMask:
- break;
- case CompWindowTypeNormalMask:
- case CompWindowTypeUtilMask:
- case CompWindowTypeToolbarMask:
- case CompWindowTypeMenuMask:
- getOuterRectOfWindow(other, &other_rect);
-
- if (rectangleIntersect(rect, &other_rect, &dest))
- return TRUE;
- break;
- }
-
- tmp = tmp->next;
- }
-
- return FALSE;
+ GList *tmp;
+ XRectangle dest;
+
+ tmp = windows;
+ while (tmp != NULL)
+ {
+ CompWindow *other = tmp->data;
+ XRectangle other_rect;
+
+ switch (other->type)
+ {
+ case CompWindowTypeDockMask:
+ case CompWindowTypeSplashMask:
+ case CompWindowTypeDesktopMask:
+ case CompWindowTypeDialogMask:
+ case CompWindowTypeModalDialogMask:
+ case CompWindowTypeFullscreenMask:
+ case CompWindowTypeUnknownMask:
+ break;
+ case CompWindowTypeNormalMask:
+ case CompWindowTypeUtilMask:
+ case CompWindowTypeToolbarMask:
+ case CompWindowTypeMenuMask:
+ getOuterRectOfWindow (other, &other_rect);
+
+ if (rectangleIntersect (rect, &other_rect, &dest))
+ return TRUE;
+ break;
+ }
+
+ tmp = tmp->next;
+ }
+
+ return FALSE;
}
-static void placeIntelligent(CompWindow *w, int *x, int *y, GList *windows){
-
- XRectangle wRect = RECTANGLE_FROM_WINDOW(w);
- XRectangle sRect = {0,0,0,0};
- wRect.height+=w->serverBorderWidth;
-
- CompScreen *screen = w->screen;
-
- get_workarea_of_current_output_device(screen,&sRect);
-
-
- int xi; int yi;
-
- for (xi = 0; xi < (sRect.width-sRect.x); xi+=10){
- wRect.x=xi;
- for (yi = 0 ; yi < (sRect.height-sRect.y); yi+=10 ){
- wRect.y=yi;
-
- if (! rectangle_overlaps_some_window(&wRect,windows) ){
- if ( !(xi+w->serverWidth > sRect.width) || !(yi + w->serverHeight > sRect.height) ){
- *x=xi;
- *y=yi;
- return;
- }
- }
- }
- }
- if ( wRect.width > ((sRect.width-sRect.x)/2)){
- placeCentered(w,x,y);
- } else {
- placeRandom(w,x,y);
- }
- }
-
-static gint leftmost_cmp(gconstpointer a, gconstpointer b)
+static void
+placeIntelligent (CompWindow * w, int *x, int *y, GList * windows)
+{
+
+ XRectangle wRect = RECTANGLE_FROM_WINDOW (w);
+ XRectangle sRect = { 0, 0, 0, 0 };
+ wRect.height += w->serverBorderWidth;
+
+ CompScreen *screen = w->screen;
+
+ get_workarea_of_current_output_device (screen, &sRect);
+
+
+ int xi;
+ int yi;
+
+ for (xi = 0; xi < (sRect.width - sRect.x); xi += 10)
+ {
+ wRect.x = xi;
+ for (yi = 0; yi < (sRect.height - sRect.y); yi += 10)
+ {
+ wRect.y = yi;
+
+ if (!rectangle_overlaps_some_window (&wRect, windows))
+ {
+ if (!(xi + w->serverWidth > sRect.width)
+ || !(yi + w->serverHeight > sRect.height))
+ {
+ *x = xi;
+ *y = yi;
+ return;
+ }
+ }
+ }
+ }
+ if (wRect.width > ((sRect.width - sRect.x) / 2))
+ {
+ placeCentered (w, x, y);
+ }
+ else
+ {
+ placeRandom (w, x, y);
+ }
+}
+
+static gint
+leftmost_cmp (gconstpointer a, gconstpointer b)
{
- CompWindow *aw = (gpointer) a;
- CompWindow *bw = (gpointer) b;
- int ax, bx;
-
- ax = aw->attrib.x - aw->input.left;
- bx = bw->attrib.x - bw->input.left;
-
- if (ax < bx)
- return -1;
- else if (ax > bx)
- return 1;
- else
- return 0;
+ CompWindow *aw = (gpointer) a;
+ CompWindow *bw = (gpointer) b;
+ int ax, bx;
+
+ ax = aw->attrib.x - aw->input.left;
+ bx = bw->attrib.x - bw->input.left;
+
+ if (ax < bx)
+ return -1;
+ else if (ax > bx)
+ return 1;
+ else
+ return 0;
}
-static gint topmost_cmp(gconstpointer a, gconstpointer b)
+static gint
+topmost_cmp (gconstpointer a, gconstpointer b)
{
- CompWindow *aw = (gpointer) a;
- CompWindow *bw = (gpointer) b;
- int ay, by;
-
- ay = aw->attrib.y - aw->input.top;
- by = bw->attrib.y - bw->input.top;
-
- if (ay < by)
- return -1;
- else if (ay > by)
- return 1;
- else
- return 0;
+ CompWindow *aw = (gpointer) a;
+ CompWindow *bw = (gpointer) b;
+ int ay, by;
+
+ ay = aw->attrib.y - aw->input.top;
+ by = bw->attrib.y - bw->input.top;
+
+ if (ay < by)
+ return -1;
+ else if (ay > by)
+ return 1;
+ else
+ return 0;
}
static void
-center_tile_rect_in_area(XRectangle * rect, XRectangle * work_area)
+center_tile_rect_in_area (XRectangle * rect, XRectangle * work_area)
{
- int fluff;
-
- /* The point here is to tile a window such that "extra"
- * space is equal on either side (i.e. so a full screen
- * of windows tiled this way would center the windows
- * as a group)
- */
-
- fluff = (work_area->width % (rect->width + 1)) / 2;
- rect->x = work_area->x + fluff;
- fluff = (work_area->height % (rect->height + 1)) / 3;
- rect->y = work_area->y + fluff;
+ int fluff;
+
+ /* The point here is to tile a window such that "extra"
+ * space is equal on either side (i.e. so a full screen
+ * of windows tiled this way would center the windows
+ * as a group)
+ */
+
+ fluff = (work_area->width % (rect->width + 1)) / 2;
+ rect->x = work_area->x + fluff;
+ fluff = (work_area->height % (rect->height + 1)) / 3;
+ rect->y = work_area->y + fluff;
}
static gboolean
-rect_fits_in_work_area(XRectangle * work_area, XRectangle * rect)
+rect_fits_in_work_area (XRectangle * work_area, XRectangle * rect)
{
- return ((rect->x >= work_area->x) &&
- (rect->y >= work_area->y) &&
- (rect->x + rect->width <= work_area->x + work_area->width)
- && (rect->y + rect->height <=
- work_area->y + work_area->height));
+ return ((rect->x >= work_area->x) &&
+ (rect->y >= work_area->y) &&
+ (rect->x + rect->width <= work_area->x + work_area->width)
+ && (rect->y + rect->height <= work_area->y + work_area->height));
}
/* Find the leftmost, then topmost, empty area on the workspace
@@ -648,612 +689,641 @@ rect_fits_in_work_area(XRectangle * work_area, XRectangle * rect)
* don't want to create a 1x1 Emacs.
*/
static gboolean
-find_first_fit(CompWindow * window,
- GList * windows, int x, int y, int *new_x, int *new_y)
+find_first_fit (CompWindow * window,
+ GList * windows, int x, int y, int *new_x, int *new_y)
{
- /* This algorithm is limited - it just brute-force tries
- * to fit the window in a small number of locations that are aligned
- * with existing windows. It tries to place the window on
- * the bottom of each existing window, and then to the right
- * of each existing window, aligned with the left/top of the
- * existing window in each of those cases.
- */
- int retval;
- GList *below_sorted;
- GList *right_sorted;
- GList *tmp;
- XRectangle rect;
- XRectangle work_area;
+ /* This algorithm is limited - it just brute-force tries
+ * to fit the window in a small number of locations that are aligned
+ * with existing windows. It tries to place the window on
+ * the bottom of each existing window, and then to the right
+ * of each existing window, aligned with the left/top of the
+ * existing window in each of those cases.
+ */
+ int retval;
+ GList *below_sorted;
+ GList *right_sorted;
+ GList *tmp;
+ XRectangle rect;
+ XRectangle work_area;
- retval = FALSE;
+ retval = FALSE;
- /* Below each window */
- below_sorted = g_list_copy(windows);
- below_sorted = g_list_sort(below_sorted, leftmost_cmp);
- below_sorted = g_list_sort(below_sorted, topmost_cmp);
+ /* Below each window */
+ below_sorted = g_list_copy (windows);
+ below_sorted = g_list_sort (below_sorted, leftmost_cmp);
+ below_sorted = g_list_sort (below_sorted, topmost_cmp);
- /* To the right of each window */
- right_sorted = g_list_copy(windows);
- right_sorted = g_list_sort(right_sorted, topmost_cmp);
- right_sorted = g_list_sort(right_sorted, leftmost_cmp);
+ /* To the right of each window */
+ right_sorted = g_list_copy (windows);
+ right_sorted = g_list_sort (right_sorted, topmost_cmp);
+ right_sorted = g_list_sort (right_sorted, leftmost_cmp);
- getOuterRectOfWindow(window, &rect);
+ getOuterRectOfWindow (window, &rect);
- get_workarea_of_current_output_device(window->screen, &work_area);
+ get_workarea_of_current_output_device (window->screen, &work_area);
- work_area.x += (window->initialViewportX - window->screen->x) *
- window->screen->width;
- work_area.y += (window->initialViewportY - window->screen->y) *
- window->screen->height;
+ work_area.x += (window->initialViewportX - window->screen->x) *
+ window->screen->width;
+ work_area.y += (window->initialViewportY - window->screen->y) *
+ window->screen->height;
- center_tile_rect_in_area(&rect, &work_area);
+ center_tile_rect_in_area (&rect, &work_area);
- if (rect_fits_in_work_area(&work_area, &rect) &&
- !rectangle_overlaps_some_window(&rect, windows)) {
- *new_x = rect.x + window->input.left;
- *new_y = rect.y + window->input.top;
+ if (rect_fits_in_work_area (&work_area, &rect) &&
+ !rectangle_overlaps_some_window (&rect, windows))
+ {
+ *new_x = rect.x + window->input.left;
+ *new_y = rect.y + window->input.top;
- retval = TRUE;
+ retval = TRUE;
- goto out;
- }
+ goto out;
+ }
- /* try below each window */
- tmp = below_sorted;
- while (tmp != NULL) {
- CompWindow *w = tmp->data;
- XRectangle outer_rect;
+ /* try below each window */
+ tmp = below_sorted;
+ while (tmp != NULL)
+ {
+ CompWindow *w = tmp->data;
+ XRectangle outer_rect;
- getOuterRectOfWindow(w, &outer_rect);
+ getOuterRectOfWindow (w, &outer_rect);
- rect.x = outer_rect.x;
- rect.y = outer_rect.y + outer_rect.height;
+ rect.x = outer_rect.x;
+ rect.y = outer_rect.y + outer_rect.height;
- if (rect_fits_in_work_area(&work_area, &rect) &&
- !rectangle_overlaps_some_window(&rect, below_sorted)) {
- *new_x = rect.x + window->input.left;
- *new_y = rect.y + window->input.top;
+ if (rect_fits_in_work_area (&work_area, &rect) &&
+ !rectangle_overlaps_some_window (&rect, below_sorted))
+ {
+ *new_x = rect.x + window->input.left;
+ *new_y = rect.y + window->input.top;
- retval = TRUE;
+ retval = TRUE;
- goto out;
- }
+ goto out;
+ }
- tmp = tmp->next;
- }
+ tmp = tmp->next;
+ }
- /* try to the right of each window */
- tmp = right_sorted;
- while (tmp != NULL) {
- CompWindow *w = tmp->data;
- XRectangle outer_rect;
+ /* try to the right of each window */
+ tmp = right_sorted;
+ while (tmp != NULL)
+ {
+ CompWindow *w = tmp->data;
+ XRectangle outer_rect;
- getOuterRectOfWindow(w, &outer_rect);
+ getOuterRectOfWindow (w, &outer_rect);
- rect.x = outer_rect.x + outer_rect.width;
- rect.y = outer_rect.y;
+ rect.x = outer_rect.x + outer_rect.width;
+ rect.y = outer_rect.y;
- if (rect_fits_in_work_area(&work_area, &rect) &&
- !rectangle_overlaps_some_window(&rect, right_sorted)) {
- *new_x = rect.x + window->input.left;
- *new_y = rect.y + window->input.top;
+ if (rect_fits_in_work_area (&work_area, &rect) &&
+ !rectangle_overlaps_some_window (&rect, right_sorted))
+ {
+ *new_x = rect.x + window->input.left;
+ *new_y = rect.y + window->input.top;
- retval = TRUE;
+ retval = TRUE;
- goto out;
- }
+ goto out;
+ }
- tmp = tmp->next;
- }
+ tmp = tmp->next;
+ }
- out:
- g_list_free(below_sorted);
- g_list_free(right_sorted);
+ out:
+ g_list_free (below_sorted);
+ g_list_free (right_sorted);
- return retval;
+ return retval;
}
static void
-placeWindow(CompWindow * window, int x, int y, int *new_x, int *new_y)
+placeWindow (CompWindow * window, int x, int y, int *new_x, int *new_y)
{
- CompWindow *wi;
- GList *windows;
- XRectangle work_area;
- int x0 = (window->initialViewportX - window->screen->x) *
- window->screen->width;
- int y0 = (window->initialViewportY - window->screen->y) *
- window->screen->height;
- int window_width, window_height;
-
- PLACE_SCREEN(window->screen);
-
- window_width = GET_WINDOW_WIDTH(window);
- window_height = GET_WINDOW_HEIGHT(window);
-
- get_workarea_of_current_output_device(window->screen, &work_area);
-
- work_area.x += x0;
- work_area.y += y0;
-
- windows = NULL;
-
- switch (window->type) {
- case CompWindowTypeSplashMask:
- case CompWindowTypeDialogMask:
- case CompWindowTypeModalDialogMask:
- case CompWindowTypeNormalMask:
- /* Run placement algorithm on these. */
- break;
- case CompWindowTypeDockMask:
- case CompWindowTypeDesktopMask:
- case CompWindowTypeUtilMask:
- case CompWindowTypeToolbarMask:
- case CompWindowTypeMenuMask:
- case CompWindowTypeFullscreenMask:
- case CompWindowTypeUnknownMask:
- /* Assume the app knows best how to place these, no placement
- * algorithm ever (other than "leave them as-is")
- */
- goto done_no_constraints;
- break;
- }
-
- /* don't run placement algorithm on windows that can't be moved */
- if (!(window->actions & CompWindowActionMoveMask)) {
- goto done_no_constraints;
- }
-
- if (window->type & CompWindowTypeFullscreenMask) {
- x = x0;
- y = y0;
- goto done_no_constraints;
- }
-
- if (window->state & (CompWindowStateMaximizedVertMask |
- CompWindowStateMaximizedHorzMask)) {
- if (window->screen->nOutputDev == 1) {
- if (window->
- state & CompWindowStateMaximizedVertMask)
- y = work_area.y + window->input.top;
-
- if (window->
- state & CompWindowStateMaximizedHorzMask)
- x = work_area.x + window->input.left;
- } else {
- int head = screenGetOutputDevForWindow(window);
- XRectangle workArea;
-
- screenGetOutputDevWorkArea(window->screen, head,
- &workArea);
-
- if (window->
- state & CompWindowStateMaximizedVertMask)
- y = workArea.y + window->input.top;
-
- if (window->
- state & CompWindowStateMaximizedHorzMask)
- x = workArea.x + window->input.left;
- }
-
- goto done;
- }
-
- if (ps->opt[PLACE_SCREEN_OPTION_WORKAROUND].value.b) {
- /* workarounds enabled */
-
- if ((window->sizeHints.flags & PPosition) ||
- (window->sizeHints.flags & USPosition)) {
- avoid_being_obscured_as_second_modal_dialog(window,
- &x,
- &y);
- goto done;
- }
- } else {
- switch (window->type) {
- case CompWindowTypeNormalMask:
- /* Only accept USPosition on normal windows because the app is full
- * of shit claiming the user set -geometry for a dialog or dock
- */
- if (window->sizeHints.flags & USPosition) {
- /* don't constrain with placement algorithm */
- goto done;
- }
- break;
- case CompWindowTypeSplashMask:
- case CompWindowTypeDialogMask:
- case CompWindowTypeModalDialogMask:
- /* Ignore even USPosition on dialogs, splashscreen */
- break;
- case CompWindowTypeDockMask:
- case CompWindowTypeDesktopMask:
- case CompWindowTypeUtilMask:
- case CompWindowTypeToolbarMask:
- case CompWindowTypeMenuMask:
- case CompWindowTypeFullscreenMask:
- case CompWindowTypeUnknownMask:
- /* Assume the app knows best how to place these. */
- if (window->sizeHints.flags & PPosition) {
- goto done_no_constraints;
- }
- break;
- }
- }
-
- if ((window->type == CompWindowTypeDialogMask ||
- window->type == CompWindowTypeModalDialogMask) &&
- window->transientFor != None) {
- /* Center horizontally, at top of parent vertically */
-
- CompWindow *parent;
-
- parent = findWindowAtDisplay(window->screen->display,
- window->transientFor);
- if (parent) {
- int w;
-
- x = parent->attrib.x;
- y = parent->attrib.y;
-
- w = GET_WINDOW_WIDTH(parent);
-
- /* center of parent */
- x = x + w / 2 - window_width / 2;
-
- /* "visually" center window over parent, leaving twice as
- * much space below as on top.
- */
- y += (GET_WINDOW_HEIGHT(parent) -
- window_height) / 3 + window->input.top;
-
- /* clip to screen if parent is visible in current viewport */
- if (parent->attrib.x < parent->screen->width &&
- parent->attrib.x + parent->screen->width > 0) {
- XRectangle area;
-
- get_workarea_of_current_output_device
- (window->screen, &area);
-
- if (x + window_width > area.x + area.width)
- x = area.x + area.width -
- window_width;
- if (y + window_height >
- area.y + area.height)
- y = area.y + area.height -
- window_height;
- if (x < area.x)
- x = area.x;
- if (y < area.y)
- y = area.y;
- }
-
- avoid_being_obscured_as_second_modal_dialog(window,
- &x,
- &y);
-
- goto done_no_x_constraints;
- }
- }
-
- /* FIXME UTILITY with transient set should be stacked up
- * on the sides of the parent window or something.
- */
- if (window->type == CompWindowTypeDialogMask ||
- window->type == CompWindowTypeModalDialogMask ||
- window->type == CompWindowTypeSplashMask) {
- /* Center on screen */
- int head;
- XRectangle workArea;
-
- /* w = window->screen->width;
- h = window->screen->height;
-
- x = (w - window->width) / 2;
- y = (h - window->height) / 2;
- */
- head = screenGetCurrentOutputDev(window->screen);
- screenGetOutputDevWorkArea(window->screen, head,
- &workArea);
-
- x = (workArea.width - window_width) / 2;
- y = (workArea.height - window_height) / 2;
-
- goto done_check_denied_focus;
- }
-
- /* Find windows that matter (not minimized, on same workspace
- * as placed window, may be shaded - if shaded we pretend it isn't
- * for placement purposes)
- */
- for (wi = window->screen->windows; wi; wi = wi->next) {
- if (!wi->shaded && wi->attrib.map_state != IsViewable)
- continue;
-
- if (wi->attrib.x >= work_area.x + work_area.width ||
- wi->attrib.x + GET_WINDOW_WIDTH(wi) <= work_area.x ||
- wi->attrib.y >= work_area.y + work_area.height ||
- wi->attrib.y + GET_WINDOW_HEIGHT(wi) <= work_area.y)
- continue;
-
- if (wi->attrib.override_redirect)
- continue;
-
- if (wi->state & (CompWindowTypeDesktopMask |
- CompWindowTypeDockMask |
- CompWindowTypeFullscreenMask |
- CompWindowTypeUnknownMask))
- continue;
-
- if (wi != window)
- windows = g_list_prepend(windows, wi);
- }
-
- /* "Origin" placement algorithm */
- x = x0;
- y = y0;
-
- if (ps->placeMode == PlaceModeCascade){
- if (find_first_fit(window, windows, x, y, &x, &y))
- goto done_check_denied_focus;
-
- /* if the window wasn't placed at the origin of screen,
- * cascade it onto the current screen
- */
- find_next_cascade(window, windows, x, y, &x, &y);
- } else if (ps->placeMode == PlaceModeCentered) {
- placeCentered(window, &x, &y);
- } else if (ps->placeMode == PlaceModeRandom) {
- placeRandom(window, &x, &y);
- } else {
- placeIntelligent(window, &x, &y,windows);
- }
-
-
-
- done_check_denied_focus:
- /* If the window is being denied focus and isn't a transient of the
- * focus window, we do NOT want it to overlap with the focus window
- * if at all possible. This is guaranteed to only be called if the
- * focus_window is non-NULL, and we try to avoid that window.
- */
- if (0 /* window->denied_focus_and_not_transient */ ) {
- gboolean found_fit = FALSE;
- CompWindow *focus_window;
-
- focus_window =
- findWindowAtDisplay(window->screen->display,
- window->screen->display->
- activeWindow);
- if (focus_window) {
- XRectangle wr, fwr, overlap;
-
- getOuterRectOfWindow(window, &wr);
- getOuterRectOfWindow(focus_window, &fwr);
-
- /* No need to do anything if the window doesn't overlap at all */
- found_fit =
- !rectangleIntersect(&wr, &fwr, &overlap);
-
- /* Try to do a first fit again, this time only taking into
- * account the focus window.
- */
- if (!found_fit) {
- GList *focus_window_list;
-
- focus_window_list =
- g_list_prepend(NULL, focus_window);
-
- /* Reset x and y ("origin" placement algorithm) */
- x = 0;
- y = 0;
-
- found_fit =
- find_first_fit(window,
- focus_window_list, x, y,
- &x, &y);
-
- g_list_free(focus_window_list);
- }
- }
-
- /* If that still didn't work, just place it where we can see as much
- * as possible.
- */
- if (!found_fit)
- find_most_freespace(window, focus_window, x, y, &x,
- &y);
- }
-
- g_list_free(windows);
-
- done:
- if (((x + window_width + window->input.right < work_area.x +
- work_area.width) &&
- (x + window_width + window->input.right > work_area.x))
- ||
- ((x - window->input.left > work_area.x) &&
- (x - window->input.left < work_area.x + work_area.width))) {
- if (x + window_width + window->input.right >
- work_area.x + work_area.width)
- x = work_area.x + work_area.width
- - window_width - window->input.right;
-
- if (x - window->input.left < work_area.x)
- x = work_area.x + window->input.left;
- } else {
- //only use THIS code if the window is TOTALLY outside the viewport.
- while (x + window_width + window->input.right >
- work_area.x + work_area.width)
- x -= work_area.width;
-
-
- if (x - window->input.left < work_area.x)
- x = work_area.x + window->input.left;
- }
-
- done_no_x_constraints:
- if (window->screen->nOutputDev == 1) {
- if (y + window_height + window->input.bottom >
- work_area.y + work_area.height)
- y = work_area.y + work_area.height
- - window_height - window->input.bottom;
-
- if (y - window->input.top < work_area.y)
- y = work_area.y + window->input.top;
- } else {
- int head = screenGetOutputDevForWindow(window);
- XRectangle workArea;
-
- screenGetOutputDevWorkArea(window->screen, head,
- &workArea);
-
- if (y + window_height + window->input.bottom >
- workArea.y + workArea.height)
- y = workArea.y + workArea.height - window_height -
- window->input.bottom;
-
- if (y - window->input.top < workArea.y)
- y = workArea.y + window->input.top;
-
- }
-
- done_no_constraints:
- *new_x = x;
- *new_y = y;
+ CompWindow *wi;
+ GList *windows;
+ XRectangle work_area;
+ int x0 = (window->initialViewportX - window->screen->x) *
+ window->screen->width;
+ int y0 = (window->initialViewportY - window->screen->y) *
+ window->screen->height;
+ int window_width, window_height;
+
+ PLACE_SCREEN (window->screen);
+
+ window_width = GET_WINDOW_WIDTH (window);
+ window_height = GET_WINDOW_HEIGHT (window);
+
+ get_workarea_of_current_output_device (window->screen, &work_area);
+
+ work_area.x += x0;
+ work_area.y += y0;
+
+ windows = NULL;
+
+ switch (window->type)
+ {
+ case CompWindowTypeSplashMask:
+ case CompWindowTypeDialogMask:
+ case CompWindowTypeModalDialogMask:
+ case CompWindowTypeNormalMask:
+ /* Run placement algorithm on these. */
+ break;
+ case CompWindowTypeDockMask:
+ case CompWindowTypeDesktopMask:
+ case CompWindowTypeUtilMask:
+ case CompWindowTypeToolbarMask:
+ case CompWindowTypeMenuMask:
+ case CompWindowTypeFullscreenMask:
+ case CompWindowTypeUnknownMask:
+ /* Assume the app knows best how to place these, no placement
+ * algorithm ever (other than "leave them as-is")
+ */
+ goto done_no_constraints;
+ break;
+ }
+
+ /* don't run placement algorithm on windows that can't be moved */
+ if (!(window->actions & CompWindowActionMoveMask))
+ {
+ goto done_no_constraints;
+ }
+
+ if (window->type & CompWindowTypeFullscreenMask)
+ {
+ x = x0;
+ y = y0;
+ goto done_no_constraints;
+ }
+
+ if (window->state & (CompWindowStateMaximizedVertMask |
+ CompWindowStateMaximizedHorzMask))
+ {
+ if (window->screen->nOutputDev == 1)
+ {
+ if (window->state & CompWindowStateMaximizedVertMask)
+ y = work_area.y + window->input.top;
+
+ if (window->state & CompWindowStateMaximizedHorzMask)
+ x = work_area.x + window->input.left;
+ }
+ else
+ {
+ int head = screenGetOutputDevForWindow (window);
+ XRectangle workArea;
+
+ screenGetOutputDevWorkArea (window->screen, head, &workArea);
+
+ if (window->state & CompWindowStateMaximizedVertMask)
+ y = workArea.y + window->input.top;
+
+ if (window->state & CompWindowStateMaximizedHorzMask)
+ x = workArea.x + window->input.left;
+ }
+
+ goto done;
+ }
+
+ if (ps->opt[PLACE_SCREEN_OPTION_WORKAROUND].value.b)
+ {
+ /* workarounds enabled */
+
+ if ((window->sizeHints.flags & PPosition) ||
+ (window->sizeHints.flags & USPosition))
+ {
+ avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
+ goto done;
+ }
+ }
+ else
+ {
+ switch (window->type)
+ {
+ case CompWindowTypeNormalMask:
+ /* Only accept USPosition on normal windows because the app is full
+ * of shit claiming the user set -geometry for a dialog or dock
+ */
+ if (window->sizeHints.flags & USPosition)
+ {
+ /* don't constrain with placement algorithm */
+ goto done;
+ }
+ break;
+ case CompWindowTypeSplashMask:
+ case CompWindowTypeDialogMask:
+ case CompWindowTypeModalDialogMask:
+ /* Ignore even USPosition on dialogs, splashscreen */
+ break;
+ case CompWindowTypeDockMask:
+ case CompWindowTypeDesktopMask:
+ case CompWindowTypeUtilMask:
+ case CompWindowTypeToolbarMask:
+ case CompWindowTypeMenuMask:
+ case CompWindowTypeFullscreenMask:
+ case CompWindowTypeUnknownMask:
+ /* Assume the app knows best how to place these. */
+ if (window->sizeHints.flags & PPosition)
+ {
+ goto done_no_constraints;
+ }
+ break;
+ }
+ }
+
+ if ((window->type == CompWindowTypeDialogMask ||
+ window->type == CompWindowTypeModalDialogMask) &&
+ window->transientFor != None)
+ {
+ /* Center horizontally, at top of parent vertically */
+
+ CompWindow *parent;
+
+ parent = findWindowAtDisplay (window->screen->display,
+ window->transientFor);
+ if (parent)
+ {
+ int w;
+
+ x = parent->attrib.x;
+ y = parent->attrib.y;
+
+ w = GET_WINDOW_WIDTH (parent);
+
+ /* center of parent */
+ x = x + w / 2 - window_width / 2;
+
+ /* "visually" center window over parent, leaving twice as
+ * much space below as on top.
+ */
+ y += (GET_WINDOW_HEIGHT (parent) -
+ window_height) / 3 + window->input.top;
+
+ /* clip to screen if parent is visible in current viewport */
+ if (parent->attrib.x < parent->screen->width &&
+ parent->attrib.x + parent->screen->width > 0)
+ {
+ XRectangle area;
+
+ get_workarea_of_current_output_device (window->screen, &area);
+
+ if (x + window_width > area.x + area.width)
+ x = area.x + area.width - window_width;
+ if (y + window_height > area.y + area.height)
+ y = area.y + area.height - window_height;
+ if (x < area.x)
+ x = area.x;
+ if (y < area.y)
+ y = area.y;
+ }
+
+ avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
+
+ goto done_no_x_constraints;
+ }
+ }
+
+ /* FIXME UTILITY with transient set should be stacked up
+ * on the sides of the parent window or something.
+ */
+ if (window->type == CompWindowTypeDialogMask ||
+ window->type == CompWindowTypeModalDialogMask ||
+ window->type == CompWindowTypeSplashMask)
+ {
+ /* Center on screen */
+ int head;
+ XRectangle workArea;
+
+ /* w = window->screen->width;
+ h = window->screen->height;
+
+ x = (w - window->width) / 2;
+ y = (h - window->height) / 2;
+ */
+ head = screenGetCurrentOutputDev (window->screen);
+ screenGetOutputDevWorkArea (window->screen, head, &workArea);
+
+ x = (workArea.width - window_width) / 2;
+ y = (workArea.height - window_height) / 2;
+
+ goto done_check_denied_focus;
+ }
+
+ /* Find windows that matter (not minimized, on same workspace
+ * as placed window, may be shaded - if shaded we pretend it isn't
+ * for placement purposes)
+ */
+ for (wi = window->screen->windows; wi; wi = wi->next)
+ {
+ if (!wi->shaded && wi->attrib.map_state != IsViewable)
+ continue;
+
+ if (wi->attrib.x >= work_area.x + work_area.width ||
+ wi->attrib.x + GET_WINDOW_WIDTH (wi) <= work_area.x ||
+ wi->attrib.y >= work_area.y + work_area.height ||
+ wi->attrib.y + GET_WINDOW_HEIGHT (wi) <= work_area.y)
+ continue;
+
+ if (wi->attrib.override_redirect)
+ continue;
+
+ if (wi->state & (CompWindowTypeDesktopMask |
+ CompWindowTypeDockMask |
+ CompWindowTypeFullscreenMask |
+ CompWindowTypeUnknownMask))
+ continue;
+
+ if (wi != window)
+ windows = g_list_prepend (windows, wi);
+ }
+
+ /* "Origin" placement algorithm */
+ x = x0;
+ y = y0;
+
+ if (ps->placeMode == PlaceModeCascade)
+ {
+ if (find_first_fit (window, windows, x, y, &x, &y))
+ goto done_check_denied_focus;
+
+ /* if the window wasn't placed at the origin of screen,
+ * cascade it onto the current screen
+ */
+ find_next_cascade (window, windows, x, y, &x, &y);
+ }
+ else if (ps->placeMode == PlaceModeCentered)
+ {
+ placeCentered (window, &x, &y);
+ }
+ else if (ps->placeMode == PlaceModeRandom)
+ {
+ placeRandom (window, &x, &y);
+ }
+ else
+ {
+ placeIntelligent (window, &x, &y, windows);
+ }
+
+
+
+ done_check_denied_focus:
+ /* If the window is being denied focus and isn't a transient of the
+ * focus window, we do NOT want it to overlap with the focus window
+ * if at all possible. This is guaranteed to only be called if the
+ * focus_window is non-NULL, and we try to avoid that window.
+ */
+ if (0 /* window->denied_focus_and_not_transient */ )
+ {
+ gboolean found_fit = FALSE;
+ CompWindow *focus_window;
+
+ focus_window =
+ findWindowAtDisplay (window->screen->display,
+ window->screen->display->activeWindow);
+ if (focus_window)
+ {
+ XRectangle wr, fwr, overlap;
+
+ getOuterRectOfWindow (window, &wr);
+ getOuterRectOfWindow (focus_window, &fwr);
+
+ /* No need to do anything if the window doesn't overlap at all */
+ found_fit = !rectangleIntersect (&wr, &fwr, &overlap);
+
+ /* Try to do a first fit again, this time only taking into
+ * account the focus window.
+ */
+ if (!found_fit)
+ {
+ GList *focus_window_list;
+
+ focus_window_list = g_list_prepend (NULL, focus_window);
+
+ /* Reset x and y ("origin" placement algorithm) */
+ x = 0;
+ y = 0;
+
+ found_fit =
+ find_first_fit (window, focus_window_list, x, y, &x, &y);
+
+ g_list_free (focus_window_list);
+ }
+ }
+
+ /* If that still didn't work, just place it where we can see as much
+ * as possible.
+ */
+ if (!found_fit)
+ find_most_freespace (window, focus_window, x, y, &x, &y);
+ }
+
+ g_list_free (windows);
+
+ done:
+ if (((x + window_width + window->input.right < work_area.x +
+ work_area.width) &&
+ (x + window_width + window->input.right > work_area.x))
+ ||
+ ((x - window->input.left > work_area.x) &&
+ (x - window->input.left < work_area.x + work_area.width)))
+ {
+ if (x + window_width + window->input.right >
+ work_area.x + work_area.width)
+ x = work_area.x + work_area.width
+ - window_width - window->input.right;
+
+ if (x - window->input.left < work_area.x)
+ x = work_area.x + window->input.left;
+ }
+ else
+ {
+ //only use THIS code if the window is TOTALLY outside the viewport.
+ while (x + window_width + window->input.right >
+ work_area.x + work_area.width)
+ x -= work_area.width;
+
+
+ if (x - window->input.left < work_area.x)
+ x = work_area.x + window->input.left;
+ }
+
+ done_no_x_constraints:
+ if (window->screen->nOutputDev == 1)
+ {
+ if (y + window_height + window->input.bottom >
+ work_area.y + work_area.height)
+ y = work_area.y + work_area.height
+ - window_height - window->input.bottom;
+
+ if (y - window->input.top < work_area.y)
+ y = work_area.y + window->input.top;
+ }
+ else
+ {
+ int head = screenGetOutputDevForWindow (window);
+ XRectangle workArea;
+
+ screenGetOutputDevWorkArea (window->screen, head, &workArea);
+
+ if (y + window_height + window->input.bottom >
+ workArea.y + workArea.height)
+ y = workArea.y + workArea.height - window_height -
+ window->input.bottom;
+
+ if (y - window->input.top < workArea.y)
+ y = workArea.y + window->input.top;
+
+ }
+
+ done_no_constraints:
+ *new_x = x;
+ *new_y = y;
}
static Bool
-placeDamageWindowRect(CompWindow * w, Bool initial, BoxPtr rect)
+placeDamageWindowRect (CompWindow * w, Bool initial, BoxPtr rect)
{
- Bool status;
+ Bool status;
- PLACE_SCREEN(w->screen);
+ PLACE_SCREEN (w->screen);
- UNWRAP(ps, w->screen, damageWindowRect);
- status = (*w->screen->damageWindowRect) (w, initial, rect);
- WRAP(ps, w->screen, damageWindowRect, placeDamageWindowRect);
+ UNWRAP (ps, w->screen, damageWindowRect);
+ status = (*w->screen->damageWindowRect) (w, initial, rect);
+ WRAP (ps, w->screen, damageWindowRect, placeDamageWindowRect);
- if (initial && !w->attrib.override_redirect && !w->placed) {
- int newX, newY;
+ if (initial && !w->attrib.override_redirect && !w->placed)
+ {
+ int newX, newY;
- placeWindow(w, w->attrib.x, w->attrib.y, &newX, &newY);
+ placeWindow (w, w->attrib.x, w->attrib.y, &newX, &newY);
- w->placed = TRUE;
+ w->placed = TRUE;
- if (newX != w->attrib.x || newY != w->attrib.y) {
- moveWindow(w, newX - w->attrib.x,
- newY - w->attrib.y, FALSE, TRUE);
- syncWindowPosition(w);
- }
- }
+ if (newX != w->attrib.x || newY != w->attrib.y)
+ {
+ moveWindow (w, newX - w->attrib.x,
+ newY - w->attrib.y, FALSE, TRUE);
+ syncWindowPosition (w);
+ }
+ }
- return status;
+ return status;
}
-static Bool placeInitDisplay(CompPlugin * p, CompDisplay * d)
+static Bool
+placeInitDisplay (CompPlugin * p, CompDisplay * d)
{
- PlaceDisplay *pd;
+ PlaceDisplay *pd;
- pd = malloc(sizeof(PlaceDisplay));
- if (!pd)
- return FALSE;
+ pd = malloc (sizeof (PlaceDisplay));
+ if (!pd)
+ return FALSE;
- pd->screenPrivateIndex = allocateScreenPrivateIndex(d);
- if (pd->screenPrivateIndex < 0) {
- free(pd);
- return FALSE;
- }
+ pd->screenPrivateIndex = allocateScreenPrivateIndex (d);
+ if (pd->screenPrivateIndex < 0)
+ {
+ free (pd);
+ return FALSE;
+ }
- d->privates[displayPrivateIndex].ptr = pd;
+ d->privates[displayPrivateIndex].ptr = pd;
- // WRAP (pd, d, handleEvent, placeHandleEvent);
+ // WRAP (pd, d, handleEvent, placeHandleEvent);
- return TRUE;
+ return TRUE;
}
-static void placeFiniDisplay(CompPlugin * p, CompDisplay * d)
+static void
+placeFiniDisplay (CompPlugin * p, CompDisplay * d)
{
- PLACE_DISPLAY(d);
+ PLACE_DISPLAY (d);
- // UNWRAP (pd, d, handleEvent);
+ // UNWRAP (pd, d, handleEvent);
- freeScreenPrivateIndex(d, pd->screenPrivateIndex);
+ freeScreenPrivateIndex (d, pd->screenPrivateIndex);
- free(pd);
+ free (pd);
}
-static Bool placeInitScreen(CompPlugin * p, CompScreen * s)
+static Bool
+placeInitScreen (CompPlugin * p, CompScreen * s)
{
- PlaceScreen *ps;
+ PlaceScreen *ps;
- PLACE_DISPLAY(s->display);
+ PLACE_DISPLAY (s->display);
- ps = malloc(sizeof(PlaceScreen));
- if (!ps)
- return FALSE;
+ ps = malloc (sizeof (PlaceScreen));
+ if (!ps)
+ return FALSE;
- placeScreenInitOptions(ps);
- // addScreenBinding (s, &ps->opt[PLACE_SCREEN_OPTION_CENTER_INITIATE].value.bind);
+ placeScreenInitOptions (ps);
+ // addScreenBinding (s, &ps->opt[PLACE_SCREEN_OPTION_CENTER_INITIATE].value.bind);
- WRAP(ps, s, damageWindowRect, placeDamageWindowRect);
+ WRAP (ps, s, damageWindowRect, placeDamageWindowRect);
- s->privates[pd->screenPrivateIndex].ptr = ps;
+ s->privates[pd->screenPrivateIndex].ptr = ps;
- return TRUE;
+ return TRUE;
}
-static void placeFiniScreen(CompPlugin * p, CompScreen * s)
+static void
+placeFiniScreen (CompPlugin * p, CompScreen * s)
{
- PLACE_SCREEN(s);
+ PLACE_SCREEN (s);
- UNWRAP(ps, s, damageWindowRect);
+ UNWRAP (ps, s, damageWindowRect);
- free(ps);
+ free (ps);
}
-static Bool placeInit(CompPlugin * p)
+static Bool
+placeInit (CompPlugin * p)
{
- displayPrivateIndex = allocateDisplayPrivateIndex();
- if (displayPrivateIndex < 0)
- return FALSE;
+ displayPrivateIndex = allocateDisplayPrivateIndex ();
+ if (displayPrivateIndex < 0)
+ return FALSE;
- return TRUE;
+ return TRUE;
}
-static void placeFini(CompPlugin * p)
+static void
+placeFini (CompPlugin * p)
{
- if (displayPrivateIndex >= 0)
- freeDisplayPrivateIndex(displayPrivateIndex);
+ if (displayPrivateIndex >= 0)
+ freeDisplayPrivateIndex (displayPrivateIndex);
}
static CompPluginVTable placeVTable = {
- "place",
- N_("Place Windows"),
- N_("Place windows at appropriate positions when mapped"),
- placeInit,
- placeFini,
- placeInitDisplay,
- placeFiniDisplay,
- placeInitScreen,
- placeFiniScreen,
- 0, /* InitWindow */
- 0, /* FiniWindow */
- 0, /* GetDisplayOptions */
- 0, /* SetDisplayOption */
- placeGetScreenOptions,
- placeSetScreenOption,
- 0,
- 0,
- 0,
- 0,
- BERYL_ABI_INFO,
- "beryl-plugins",
- "wm"
+ "place",
+ N_("Place Windows"),
+ N_("Place windows at appropriate positions when mapped"),
+ placeInit,
+ placeFini,
+ placeInitDisplay,
+ placeFiniDisplay,
+ placeInitScreen,
+ placeFiniScreen,
+ 0, /* InitWindow */
+ 0, /* FiniWindow */
+ 0, /* GetDisplayOptions */
+ 0, /* SetDisplayOption */
+ placeGetScreenOptions,
+ placeSetScreenOption,
+ 0,
+ 0,
+ 0,
+ 0,
+ BERYL_ABI_INFO,
+ "beryl-plugins",
+ "wm"
};
-CompPluginVTable *getCompPluginInfo(void)
+CompPluginVTable *
+getCompPluginInfo (void)
{
- return &placeVTable;
+ return &placeVTable;
}