diff --git a/src/defaults.c b/src/defaults.c index 5b57dd9d..0a8fc0fb 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -610,6 +610,8 @@ WDefaultEntry optionList[] = { NULL, getKeybind, setKeyGrab, NULL, NULL}, {"PrevWorkspaceKey", "None", (void *)WKBD_PREVWORKSPACE, NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"LastWorkspaceKey", "None", (void *)WKBD_LASTWORKSPACE, + NULL, getKeybind, setKeyGrab, NULL, NULL}, {"NextWorkspaceLayerKey", "None", (void *)WKBD_NEXTWSLAYER, NULL, getKeybind, setKeyGrab, NULL, NULL}, {"PrevWorkspaceLayerKey", "None", (void *)WKBD_PREVWSLAYER, @@ -2852,6 +2854,8 @@ static int setKeyGrab(WScreen * scr, WDefaultEntry * entry, WShortKey * shortcut /* do we need to update window menus? */ if (widx >= WKBD_WORKSPACE1 && widx <= WKBD_WORKSPACE10) return REFRESH_WORKSPACE_MENU; + if (widx == WKBD_LASTWORKSPACE) + return REFRESH_WORKSPACE_MENU; return 0; } diff --git a/src/event.c b/src/event.c index ace2a3cf..0f4b53db 100644 --- a/src/event.c +++ b/src/event.c @@ -1554,6 +1554,9 @@ static void handleKeyPress(XEvent * event) case WKBD_PREVWORKSPACE: wWorkspaceRelativeChange(scr, -1); break; + case WKBD_LASTWORKSPACE: + wWorkspaceChange(scr, scr->last_workspace); + break; case WKBD_WINDOW1: case WKBD_WINDOW2: diff --git a/src/keybind.h b/src/keybind.h index 99137d8b..f4ec95c6 100644 --- a/src/keybind.h +++ b/src/keybind.h @@ -71,6 +71,7 @@ enum { WKBD_WORKSPACE10, WKBD_NEXTWORKSPACE, WKBD_PREVWORKSPACE, + WKBD_LASTWORKSPACE, WKBD_NEXTWSLAYER, WKBD_PREVWSLAYER, diff --git a/src/screen.h b/src/screen.h index 15fd4f8d..b2c2f42d 100644 --- a/src/screen.h +++ b/src/screen.h @@ -120,6 +120,7 @@ typedef struct _WScreen { struct WWorkspace **workspaces; /* workspace array */ int current_workspace; /* current workspace number */ + int last_workspace; /* last used workspace number */ WReservedArea *reservedAreas; /* used to build totalUsableArea */ diff --git a/src/startup.c b/src/startup.c index 00e32ef6..93b5fe78 100644 --- a/src/startup.c +++ b/src/startup.c @@ -911,6 +911,7 @@ static void manageAllWindows(WScreen * scr, int crashRecovery) WMNextEvent(dpy, &ev); WMHandleEvent(&ev); } + scr->last_workspace = 0; wWorkspaceForceChange(scr, 0); if (!wPreferences.flags.noclip) wDockShowIcons(scr->workspaces[scr->current_workspace]->clip); diff --git a/src/workspace.c b/src/workspace.c index 6d494984..2f94427f 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -51,8 +51,9 @@ #define MC_NEW 0 #define MC_DESTROY_LAST 1 +#define MC_LAST_USED 2 /* index of the first workspace menu entry */ -#define MC_WORKSPACE1 2 +#define MC_WORKSPACE1 3 #define MAX_SHORTCUT_LENGTH 32 #define WORKSPACE_NAME_DISPLAY_PADDING 32 @@ -193,6 +194,8 @@ Bool wWorkspaceDelete(WScreen * scr, int workspace) if (scr->current_workspace >= scr->workspace_count) wWorkspaceChange(scr, scr->workspace_count - 1); + if (scr->last_workspace >= scr->workspace_count) + scr->last_workspace = 0; return True; } @@ -480,6 +483,7 @@ void wWorkspaceForceChange(WScreen * scr, int workspace) wClipUpdateForWorkspaceChange(scr, workspace); + scr->last_workspace = scr->current_workspace; scr->current_workspace = workspace; wWorkspaceMenuUpdate(scr, scr->workspace_menu); @@ -626,6 +630,11 @@ static void switchWSCommand(WMenu * menu, WMenuEntry * entry) wWorkspaceChange(menu->frame->screen_ptr, (long)entry->clientdata); } +static void lastWSCommand(WMenu * menu, WMenuEntry * entry) +{ + wWorkspaceChange(menu->frame->screen_ptr, menu->frame->screen_ptr->last_workspace); +} + static void deleteWSCommand(WMenu * menu, WMenuEntry * entry) { wWorkspaceDelete(menu->frame->screen_ptr, menu->frame->screen_ptr->workspace_count - 1); @@ -698,6 +707,7 @@ static void onMenuEntryEdited(WMenu * menu, WMenuEntry * entry) WMenu *wWorkspaceMenuMake(WScreen * scr, Bool titled) { WMenu *wsmenu; + WMenuEntry *entry; wsmenu = wMenuCreate(scr, titled ? _("Workspaces") : NULL, False); if (!wsmenu) { @@ -711,6 +721,9 @@ WMenu *wWorkspaceMenuMake(WScreen * scr, Bool titled) wMenuAddCallback(wsmenu, _("New"), newWSCommand, NULL); wMenuAddCallback(wsmenu, _("Destroy Last"), deleteWSCommand, NULL); + entry = wMenuAddCallback(wsmenu, _("Last Used"), lastWSCommand, NULL); + entry->rtext = GetShortcutKey(wKeyBindings[WKBD_LASTWORKSPACE]); + return wsmenu; } @@ -765,6 +778,12 @@ void wWorkspaceMenuUpdate(WScreen * scr, WMenu * menu) wMenuSetEnabled(menu, MC_DESTROY_LAST, True); } + /* back to last workspace */ + if (scr->workspace_count && scr->last_workspace != scr->current_workspace) + wMenuSetEnabled(menu, MC_LAST_USED, True); + else + wMenuSetEnabled(menu, MC_LAST_USED, False); + tmp = menu->frame->top_width + 5; /* if menu got unreachable, bring it to a visible place */ if (menu->frame_x < tmp - (int)menu->frame->core->width)