diff --git a/ChangeLog b/ChangeLog index e62a2609..c159dbe1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ Changes since version 0.62.1: ............................. - added blackbox style igradient (interwoven) - added wmagnify utility +- added definable workspace border (0..5 pixels). See NEWS. Changes since version 0.62.0: ............................. diff --git a/NEWS b/NEWS index 38c27d8a..e6456965 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,26 @@ your mouse pointer is located, updating it in real-time. tip: maximize it horizontally, make it Omnipresent and Always at Bottom. Then leave it in the bottom of the screen. +workspace border +---------------- + +2 options (WorkspaceBorder and WorkspaceBorderSize) were added to allow one to +set a small (0..5 pixels) border for the workspace. This border will not be +covered by windows when maximizing, allowing one to easily access the clip +or map a menu using the mouse in the border area, even when there are +windows maximized in both horizontal and vertical directions. +WorkspaceBorder can be one of (None, LeftRight, TopBottom, AllDirections) +while WorkspaceBorderSize is the size in pixles of the border not to be +covered by windows when maximizing (usually a small amount 0..5 pixles). + +Both options can be set using WPrefs.app in the "Miscelaneous Ergonomic +Preferences" section. WPrefs will always limit WorkspaceBorderSize in the +(0..5) range. + +Note that if "full screen maximization" option is set for a window, that +window will ignore this border area, maximizing to full screen. + + --- 0.62.0 diff --git a/WPrefs.app/Preferences.c b/WPrefs.app/Preferences.c index 051c498e..e3479bc8 100644 --- a/WPrefs.app/Preferences.c +++ b/WPrefs.app/Preferences.c @@ -49,6 +49,12 @@ typedef struct _Panel { WMButton *modeB; #endif /* XKB_MODELOCK */ + WMFrame *borderF; + WMSlider *borderS; + WMLabel *borderL; + WMButton *lrB; + WMButton *tbB; + } _Panel; @@ -56,11 +62,30 @@ typedef struct _Panel { #define ICON_FILE "ergonomic" +static void +borderCallback(WMWidget *w, void *data) +{ + _Panel *panel = (_Panel*)data; + char buffer[64]; + int i; + + i = WMGetSliderValue(panel->borderS); + + if (i == 0) + WMSetLabelText(panel->borderL, "OFF"); + else { + sprintf(buffer, "%i pixel%s", i, i>1 ? "s" : ""); + WMSetLabelText(panel->borderL, buffer); + } +} + + static void showData(_Panel *panel) { char *str; - + int x; + str = GetStringForKey("ResizeDisplay"); if (!str) str = "corner"; @@ -82,7 +107,24 @@ showData(_Panel *panel) WMSetPopUpButtonSelectedItem(panel->posiP, 1); else if (strcasecmp(str, "floating")==0) WMSetPopUpButtonSelectedItem(panel->posiP, 2); - + + x = GetIntegerForKey("WorkspaceBorderSize"); + x = x<0 ? 0 : x; + x = x>5 ? 5 : x; + WMSetSliderValue(panel->borderS, x); + borderCallback(NULL, panel); + + str = GetStringForKey("WorkspaceBorder"); + if (!str) + str = "none"; + if (strcasecmp(str, "LeftRight")==0) { + WMSetButtonSelected(panel->lrB, True); + } else if (strcasecmp(str, "TopBottom")==0) { + WMSetButtonSelected(panel->tbB, True); + } else if (strcasecmp(str, "AllDirections")==0) { + WMSetButtonSelected(panel->tbB, True); + WMSetButtonSelected(panel->lrB, True); + } WMSetButtonSelected(panel->raisB, GetBoolForKey("CirculateRaise")); #ifdef XKB_MODELOCK @@ -100,7 +142,8 @@ static void storeData(_Panel *panel) { char *str; - + Bool lr, tb; + switch (WMGetPopUpButtonSelectedItem(panel->sizeP)) { case 0: str = "corner"; @@ -130,6 +173,19 @@ storeData(_Panel *panel) } SetStringForKey(str, "MoveDisplay"); + lr = WMGetButtonSelected(panel->lrB); + tb = WMGetButtonSelected(panel->tbB); + if (lr && tb) + str = "AllDirections"; + else if (lr) + str = "LeftRight"; + else if (tb) + str = "TopBottom"; + else + str = "None"; + SetStringForKey(str, "WorkspaceBorder"); + SetIntegerForKey(WMGetSliderValue(panel->borderS), "WorkspaceBorderSize"); + SetBoolForKey(WMGetButtonSelected(panel->raisB), "CirculateRaise"); #ifdef XKB_MODELOCK SetBoolForKey(WMGetButtonSelected(panel->modeB), "KbdModeLock"); @@ -211,23 +267,53 @@ createPanel(Panel *p) /***************** Options ****************/ panel->optF = WMCreateFrame(panel->frame); - WMResizeWidget(panel->optF, 485, 75); - WMMoveWidget(panel->optF, 20, 145); + WMResizeWidget(panel->optF, 235, 75); + WMMoveWidget(panel->optF, 270, 145); panel->raisB = WMCreateSwitchButton(panel->optF); - WMResizeWidget(panel->raisB, 440, 20); - WMMoveWidget(panel->raisB, 20, 15); - WMSetButtonText(panel->raisB, _("Raise window when switching focus with keyboard (CirculateRaise).")); + WMResizeWidget(panel->raisB, 210, 30); + WMMoveWidget(panel->raisB, 15, 7); + WMSetButtonText(panel->raisB, _("Raise window when switching focus with keyboard.")); #ifdef XKB_MODELOCK panel->modeB = WMCreateSwitchButton(panel->optF); - WMResizeWidget(panel->modeB, 440, 20); - WMMoveWidget(panel->modeB, 20, 40); - WMSetButtonText(panel->modeB, _("Keep keyboard language status for each window.")); + WMResizeWidget(panel->modeB, 210, 30); + WMMoveWidget(panel->modeB, 15, 40); + WMSetButtonText(panel->modeB, _("Enable keyboard language switch button in window titlebars.")); #endif WMMapSubwidgets(panel->optF); + /***************** Workspace border ****************/ + panel->borderF = WMCreateFrame(panel->frame); + WMResizeWidget(panel->borderF, 240, 75); + WMMoveWidget(panel->borderF, 20, 145); + WMSetFrameTitle(panel->borderF, _("Workspace border")); + + panel->borderS = WMCreateSlider(panel->borderF); + WMResizeWidget(panel->borderS, 80, 15); + WMMoveWidget(panel->borderS, 20, 20); + WMSetSliderMinValue(panel->borderS, 0); + WMSetSliderMaxValue(panel->borderS, 5); + WMSetSliderAction(panel->borderS, borderCallback, panel); + + panel->borderL = WMCreateLabel(panel->borderF); + WMResizeWidget(panel->borderL, 50, 15); + WMMoveWidget(panel->borderL, 105, 20); + + panel->lrB = WMCreateSwitchButton(panel->borderF); + WMMoveWidget(panel->lrB, 20, 40); + WMResizeWidget(panel->lrB, 90, 30); + WMSetButtonText(panel->lrB, _("Left/Right")); + + panel->tbB = WMCreateSwitchButton(panel->borderF); + WMMoveWidget(panel->tbB, 120, 40); + WMResizeWidget(panel->tbB, 90, 30); + WMSetButtonText(panel->tbB, _("Top/Bottom")); + + + WMMapSubwidgets(panel->borderF); + WMRealizeWidget(panel->frame); WMMapSubwidgets(panel->frame); diff --git a/WindowMaker/Defaults/WindowMaker.in b/WindowMaker/Defaults/WindowMaker.in index de30d6ba..31e05be2 100644 --- a/WindowMaker/Defaults/WindowMaker.in +++ b/WindowMaker/Defaults/WindowMaker.in @@ -7,6 +7,8 @@ DisableMiniwindows = NO; OpenTransientOnOwnerWorkspace = NO; EdgeResistance = 30; + WorkspaceBorderSize = 0; + WorkspaceBorder = None; IconificationStyle = Zoom; IconPath = ( "~/GNUstep/Library/Icons", diff --git a/src/WindowMaker.h b/src/WindowMaker.h index 973e5307..ba3a69ba 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -219,6 +219,13 @@ typedef enum { #define WD_BOTTOMRIGHT 7 +/* workspace border position */ +#define WB_NONE 0 +#define WB_LEFTRIGHT 1 +#define WB_TOPBOTTOM 2 +#define WB_ALLDIRS (WB_LEFTRIGHT|WB_TOPBOTTOM) + + /* program states */ #define WSTATE_NORMAL 0 #define WSTATE_NEED_EXIT 1 @@ -420,6 +427,9 @@ typedef struct WPreferences { int edge_resistance; char attract; + unsigned int workspace_border_size; /* Size in pixels of the workspace border */ + char workspace_border_position; /* Where to leave a workspace border */ + struct { unsigned int nodock:1; /* don't display the dock */ unsigned int noclip:1; /* don't display the clip */ diff --git a/src/defaults.c b/src/defaults.c index 22a641c2..1719e497 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -319,7 +319,16 @@ static WOptionEnumeration seDisplayPositions[] = { {"topleft", WD_TOPLEFT, 0}, {"topright", WD_TOPRIGHT, 0}, {"bottomleft", WD_BOTTOMLEFT, 0}, - {"bottomright", WD_BOTTOMRIGHT, 0} + {"bottomright", WD_BOTTOMRIGHT, 0}, + {NULL, 0, 0} +}; + +static WOptionEnumeration seWorkspaceBorder[] = { + {"None", WB_NONE, 0}, + {"LeftRight", WB_LEFTRIGHT, 0}, + {"TopBottom", WB_TOPBOTTOM, 0}, + {"AllDirections", WB_ALLDIRS, 0}, + {NULL, 0, 0} }; @@ -423,6 +432,12 @@ WDefaultEntry optionList[] = { {"WorkspaceNameDisplayPosition", "center", seDisplayPositions, &wPreferences.workspace_name_display_position, getEnum, NULL }, + {"WorkspaceBorder", "None", seWorkspaceBorder, + &wPreferences.workspace_border_position, getEnum, updateUsableArea + }, + {"WorkspaceBorderSize", "0", NULL, + &wPreferences.workspace_border_size, getInt, updateUsableArea + }, #ifdef VIRTUAL_DESKTOP {"VirtualEdgeThickness", "1", NULL, &wPreferences.vedge_thickness, getInt, NULL @@ -2597,7 +2612,8 @@ static WCursorLookup cursor_table[] = { NULL, CURSOR_ID_NONE } }; -static void check_bitmap_status(int status, char *filename, Pixmap bitmap) +static void +check_bitmap_status(int status, char *filename, Pixmap bitmap) { switch(status) { case BitmapOpenFailed: @@ -2620,7 +2636,8 @@ static void check_bitmap_status(int status, char *filename, Pixmap bitmap) * (builtin, ) * (bitmap, , ) */ -static int parse_cursor(WScreen *scr, proplist_t pl, Cursor *cursor) +static int +parse_cursor(WScreen *scr, proplist_t pl, Cursor *cursor) { proplist_t elem; char *val; diff --git a/src/screen.c b/src/screen.c index c2f1d265..b850e1e2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -987,6 +987,23 @@ wScreenUpdateUsableArea(WScreen *scr) } #endif #endif + + { + unsigned size = wPreferences.workspace_border_size; + unsigned position = wPreferences.workspace_border_position; + + if (size>0 && position!=WB_NONE) { + if (position & WB_LEFTRIGHT) { + scr->totalUsableArea.x1 += size; + scr->totalUsableArea.x2 -= size; + } + if (position & WB_TOPBOTTOM) { + scr->totalUsableArea.y1 += size; + scr->totalUsableArea.y2 -= size; + } + } + } + }