From 9d3d34599f682867b08ae4308f5a58bf9f8f10ec Mon Sep 17 00:00:00 2001 From: Yuri Karaban Date: Sun, 10 Jun 2012 18:04:59 +0300 Subject: [PATCH] Add "Center" window placement strategy Center strategy: try to put window at the center of the usable area. If window would overlap with existing windows, fall back to "Auto" placement strategy. It's very useful for fresh workplaces. --- WPrefs.app/WindowHandling.c | 6 ++++- src/WindowMaker.h | 1 + src/defaults.c | 1 + src/placement.c | 47 ++++++++++++++++++++++++++++++++++++- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/WPrefs.app/WindowHandling.c b/WPrefs.app/WindowHandling.c index 0770ed51..335690c5 100644 --- a/WPrefs.app/WindowHandling.c +++ b/WPrefs.app/WindowHandling.c @@ -82,7 +82,8 @@ static char *placements[] = { "random", "manual", "cascade", - "smart" + "smart", + "center" }; static void sliderCallback(WMWidget * w, void *data) @@ -151,6 +152,8 @@ static int getPlacement(char *str) return 3; else if (strcasecmp(str, "smart") == 0) return 4; + else if (strcasecmp(str, "center") == 0) + return 5; else wwarning(_("bad option value %s in WindowPlacement. Using default value"), str); return 0; @@ -266,6 +269,7 @@ static void createPanel(Panel * p) WMAddPopUpButtonItem(panel->placP, _("Manual")); WMAddPopUpButtonItem(panel->placP, _("Cascade")); WMAddPopUpButtonItem(panel->placP, _("Smart")); + WMAddPopUpButtonItem(panel->placP, _("Center")); panel->porigL = WMCreateLabel(panel->placF); WMResizeWidget(panel->porigL, 120, 32); diff --git a/src/WindowMaker.h b/src/WindowMaker.h index e10b5ab6..745cd424 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -153,6 +153,7 @@ typedef enum { #define WPM_SMART 2 #define WPM_RANDOM 3 #define WPM_AUTO 4 +#define WPM_CENTER 5 /* text justification */ #define WTJ_CENTER 0 diff --git a/src/defaults.c b/src/defaults.c index 50e8cbe7..86edfa48 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -204,6 +204,7 @@ static WOptionEnumeration sePlacements[] = { {"Cascade", WPM_CASCADE, 0}, {"Random", WPM_RANDOM, 0}, {"Manual", WPM_MANUAL, 0}, + {"Center", WPM_CENTER, 0}, {NULL, 0, 0} }; diff --git a/src/placement.c b/src/placement.c index 93ba39a3..b30e0aff 100644 --- a/src/placement.c +++ b/src/placement.c @@ -360,6 +360,46 @@ smartPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned int width, *y_ret = min_isect_y; } +static Bool +center_place_window(WWindow *wwin, int *x_ret, int *y_ret, + unsigned int width, unsigned int height, WArea usableArea) +{ + WScreen *scr = wwin->screen_ptr; + int try_x, try_y; + int swidth, sheight; + WWindow *win; + + set_width_height(wwin, &width, &height); + swidth = usableArea.x2 - usableArea.x1; + sheight = usableArea.y2 - usableArea.y1; + + if (width > swidth || height > sheight) + return False; + + try_x = (usableArea.x1 + usableArea.x2 - width) / 2; + try_y = (usableArea.y1 + usableArea.y2 - height) / 2; + + for (win = scr->focused_window; win != NULL; win = win->next) { + int w = win->frame->core->width; + int h = win->frame->core->height; + int x = win->frame_x; + int y = win->frame_y; + + if ((x < (try_x + width)) && ((x + w) > try_x) && + (y < (try_y + height)) && ((y + h) > try_y) && + (win->flags.mapped || + (win->flags.shaded && + win->frame->workspace == scr->current_workspace && + !(win->flags.miniaturized || win->flags.hidden)))) + return False; + } + + *x_ret = try_x; + *y_ret = try_y; + + return True; +} + static Bool autoPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned int width, unsigned int height, int tryCount, WArea usableArea) @@ -502,6 +542,11 @@ void PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned width, unsigned smartPlaceWindow(wwin, x_ret, y_ret, width, height, usableArea); break; + case WPM_CENTER: + if (center_place_window(wwin, x_ret, y_ret, width, height, usableArea)) + break; + /* fall through to auto placement */ + case WPM_AUTO: if (autoPlaceWindow(wwin, x_ret, y_ret, width, height, 0, usableArea)) { break; @@ -513,7 +558,7 @@ void PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned width, unsigned automagicness aren't going to want to place their window */ case WPM_CASCADE: - if (wPreferences.window_placement == WPM_AUTO) + if (wPreferences.window_placement == WPM_AUTO || wPreferences.window_placement == WPM_CENTER) scr->cascade_index++; cascadeWindow(scr, wwin, x_ret, y_ret, width, height, h, usableArea);