From ae7235c2df819604f2b407cc738a835f55e6b81f Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Wed, 27 Mar 2013 22:46:00 +0000 Subject: [PATCH] Shortcuts for moving windows between workspaces. Added new keyboard shortcuts for moving windows between workspaces. MoveToWorkspace1Key moves the active window directly to workspace 1. Similarly for MoveToWorkspace2Key through MoveToWorkspace10Key. MoveToNextWorkspaceKey moves the window to the next workspace, MoveToPrevWorkspaceKey moves the window to the previous workspace. Both keys respect the ws_advance and ws_cycle preferences. MoveToNextWorkspaceLayerKey moves the window ten workspaces "forward" if possible. MoveToPrevWorkspaceLayerKey moves the window ten workspaces "back" if possible. --- src/defaults.c | 36 ++++++++++++++++++++++++++++++++++++ src/event.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/keybind.h | 17 +++++++++++++++++ src/window.c | 24 ++++++++++++++++++++++++ src/window.h | 1 + src/winmenu.c | 17 ++++++++++++++--- 6 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/defaults.c b/src/defaults.c index 0a8fc0fb..6c23064d 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -636,6 +636,36 @@ WDefaultEntry optionList[] = { NULL, getKeybind, setKeyGrab, NULL, NULL}, {"Workspace10Key", "None", (void *)WKBD_WORKSPACE10, NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace1Key", "None", (void *)WKBD_MOVE_WORKSPACE1, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace2Key", "None", (void *)WKBD_MOVE_WORKSPACE2, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace3Key", "None", (void *)WKBD_MOVE_WORKSPACE3, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace4Key", "None", (void *)WKBD_MOVE_WORKSPACE4, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace5Key", "None", (void *)WKBD_MOVE_WORKSPACE5, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace6Key", "None", (void *)WKBD_MOVE_WORKSPACE6, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace7Key", "None", (void *)WKBD_MOVE_WORKSPACE7, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace8Key", "None", (void *)WKBD_MOVE_WORKSPACE8, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace9Key", "None", (void *)WKBD_MOVE_WORKSPACE9, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToWorkspace10Key", "None", (void *)WKBD_MOVE_WORKSPACE10, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToNextWorkspaceKey", "None", (void *)WKBD_MOVE_NEXTWORKSPACE, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToPrevWorkspaceKey", "None", (void *)WKBD_MOVE_PREVWORKSPACE, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToLastWorkspaceKey", "None", (void *)WKBD_MOVE_LASTWORKSPACE, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToNextWorkspaceLayerKey", "None", (void *)WKBD_MOVE_NEXTWSLAYER, + NULL, getKeybind, setKeyGrab, NULL, NULL}, + {"MoveToPrevWorkspaceLayerKey", "None", (void *)WKBD_MOVE_PREVWSLAYER, + NULL, getKeybind, setKeyGrab, NULL, NULL}, {"WindowShortcut1Key", "None", (void *)WKBD_WINDOW1, NULL, getKeybind, setKeyGrab, NULL, NULL}, {"WindowShortcut2Key", "None", (void *)WKBD_WINDOW2, @@ -1139,6 +1169,10 @@ void wReadDefaults(WScreen * scr, WMPropList * new_dict) wWorkspaceMenuUpdate(scr, scr->workspace_menu); if (scr->clip_ws_menu) wWorkspaceMenuUpdate(scr, scr->clip_ws_menu); + if (scr->workspace_submenu) + scr->workspace_submenu->flags.realized = 0; + if (scr->clip_submenu) + scr->clip_submenu->flags.realized = 0; } } } @@ -2856,6 +2890,8 @@ static int setKeyGrab(WScreen * scr, WDefaultEntry * entry, WShortKey * shortcut return REFRESH_WORKSPACE_MENU; if (widx == WKBD_LASTWORKSPACE) return REFRESH_WORKSPACE_MENU; + if (widx >= WKBD_MOVE_WORKSPACE1 && widx <= WKBD_MOVE_WORKSPACE10) + return REFRESH_WORKSPACE_MENU; return 0; } diff --git a/src/event.c b/src/event.c index 0f4b53db..2da09885 100644 --- a/src/event.c +++ b/src/event.c @@ -1558,6 +1558,46 @@ static void handleKeyPress(XEvent * event) wWorkspaceChange(scr, scr->last_workspace); break; + case WKBD_MOVE_WORKSPACE1 ... WKBD_MOVE_WORKSPACE10: + widx = command - WKBD_MOVE_WORKSPACE1; + i = (scr->current_workspace / 10) * 10 + widx; + if (wwin && (wPreferences.ws_advance || i < scr->workspace_count)) + wWindowChangeWorkspace(wwin, i); + break; + + case WKBD_MOVE_NEXTWORKSPACE: + if (wwin) + wWindowChangeWorkspaceRelative(wwin, 1); + break; + case WKBD_MOVE_PREVWORKSPACE: + if (wwin) + wWindowChangeWorkspaceRelative(wwin, -1); + break; + case WKBD_MOVE_LASTWORKSPACE: + if (wwin) + wWindowChangeWorkspace(wwin, scr->last_workspace); + break; + + case WKBD_MOVE_NEXTWSLAYER: + case WKBD_MOVE_PREVWSLAYER: + { + if (wwin) { + int row, column; + + row = scr->current_workspace / 10; + column = scr->current_workspace % 10; + + if (command == WKBD_MOVE_NEXTWSLAYER) { + if ((row + 1) * 10 < scr->workspace_count) + wWindowChangeWorkspace(wwin, column + (row + 1) * 10); + } else { + if (row > 0) + wWindowChangeWorkspace(wwin, column + (row - 1) * 10); + } + } + } + break; + case WKBD_WINDOW1: case WKBD_WINDOW2: case WKBD_WINDOW3: diff --git a/src/keybind.h b/src/keybind.h index f4ec95c6..44379503 100644 --- a/src/keybind.h +++ b/src/keybind.h @@ -75,6 +75,23 @@ enum { WKBD_NEXTWSLAYER, WKBD_PREVWSLAYER, + /* move to workspace */ + WKBD_MOVE_WORKSPACE1, + WKBD_MOVE_WORKSPACE2, + WKBD_MOVE_WORKSPACE3, + WKBD_MOVE_WORKSPACE4, + WKBD_MOVE_WORKSPACE5, + WKBD_MOVE_WORKSPACE6, + WKBD_MOVE_WORKSPACE7, + WKBD_MOVE_WORKSPACE8, + WKBD_MOVE_WORKSPACE9, + WKBD_MOVE_WORKSPACE10, + WKBD_MOVE_NEXTWORKSPACE, + WKBD_MOVE_PREVWORKSPACE, + WKBD_MOVE_LASTWORKSPACE, + WKBD_MOVE_NEXTWSLAYER, + WKBD_MOVE_PREVWSLAYER, + /* window shortcuts */ WKBD_WINDOW1, WKBD_WINDOW2, diff --git a/src/window.c b/src/window.c index a070b0b1..affafcfb 100644 --- a/src/window.c +++ b/src/window.c @@ -1917,6 +1917,30 @@ void wWindowChangeWorkspace(WWindow *wwin, int workspace) wWindowUnmap(wwin); } +void wWindowChangeWorkspaceRelative(WWindow *wwin, int amount) +{ + WScreen *scr = wwin->screen_ptr; + int w = scr->current_workspace + amount; + + if (amount < 0) { + if (w >= 0) { + wWindowChangeWorkspace(wwin, w); + } else if (wPreferences.ws_cycle) { + wWindowChangeWorkspace(wwin, scr->workspace_count + w); + } + } else if (amount > 0) { + if (w < scr->workspace_count) { + wWindowChangeWorkspace(wwin, w); + } else if (wPreferences.ws_advance) { + int workspace = WMIN(w, MAX_WORKSPACES - 1); + wWorkspaceMake(scr, workspace); + wWindowChangeWorkspace(wwin, workspace); + } else if (wPreferences.ws_cycle) { + wWindowChangeWorkspace(wwin, w % scr->workspace_count); + } + } +} + void wWindowSynthConfigureNotify(WWindow *wwin) { XEvent sevent; diff --git a/src/window.h b/src/window.h index c4148a36..2e24f49e 100644 --- a/src/window.h +++ b/src/window.h @@ -364,6 +364,7 @@ void wWindowUpdateButtonImages(WWindow *wwin); void wWindowSaveState(WWindow *wwin); void wWindowChangeWorkspace(WWindow *wwin, int workspace); +void wWindowChangeWorkspaceRelative(WWindow *wwin, int amount); void wWindowSetKeyGrabs(WWindow *wwin); diff --git a/src/winmenu.c b/src/winmenu.c index 983f7e86..7d49d2b2 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -220,25 +220,36 @@ static void updateWorkspaceMenu(WMenu * menu) { WScreen *scr = menu->frame->screen_ptr; char title[MAX_WORKSPACENAME_WIDTH + 1]; + WMenuEntry *entry; int i; for (i = 0; i < scr->workspace_count; i++) { if (i < menu->entry_no) { - if (strcmp(menu->entries[i]->text, scr->workspaces[i]->name) != 0) { - wfree(menu->entries[i]->text); + + entry = menu->entries[i]; + if (strcmp(entry->text, scr->workspaces[i]->name) != 0) { + wfree(entry->text); strncpy(title, scr->workspaces[i]->name, MAX_WORKSPACENAME_WIDTH); title[MAX_WORKSPACENAME_WIDTH] = 0; menu->entries[i]->text = wstrdup(title); + menu->entries[i]->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVE_WORKSPACE1 + i]); menu->flags.realized = 0; } } else { strncpy(title, scr->workspaces[i]->name, MAX_WORKSPACENAME_WIDTH); title[MAX_WORKSPACENAME_WIDTH] = 0; - wMenuAddCallback(menu, title, switchWSCommand, NULL); + entry = wMenuAddCallback(menu, title, switchWSCommand, NULL); + entry->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVE_WORKSPACE1 + i]); menu->flags.realized = 0; } + + /* workspace shortcut labels */ + if (i / 10 == scr->current_workspace / 10) + entry->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVE_WORKSPACE1 + (i % 10)]); + else + entry->rtext = NULL; } if (!menu->flags.realized)