diff --git a/WPrefs.app/KeyboardShortcuts.c b/WPrefs.app/KeyboardShortcuts.c index 6cc6f9e7..2c44b8cf 100644 --- a/WPrefs.app/KeyboardShortcuts.c +++ b/WPrefs.app/KeyboardShortcuts.c @@ -83,6 +83,8 @@ static char *keyOptions[] = { "SelectKey", "FocusNextKey", "FocusPrevKey", + "GroupNextKey", + "GroupPrevKey", "NextWorkspaceKey", "PrevWorkspaceKey", "NextWorkspaceLayerKey", @@ -487,6 +489,8 @@ static void createPanel(Panel * p) WMAddListItem(panel->actLs, _("Select active window")); WMAddListItem(panel->actLs, _("Focus next window")); WMAddListItem(panel->actLs, _("Focus previous window")); + WMAddListItem(panel->actLs, _("Focus next group window")); + WMAddListItem(panel->actLs, _("Focus previous group window")); WMAddListItem(panel->actLs, _("Switch to next workspace")); WMAddListItem(panel->actLs, _("Switch to previous workspace")); WMAddListItem(panel->actLs, _("Switch to next ten workspaces")); diff --git a/src/cycling.c b/src/cycling.c index 2510d2f5..c064f1dc 100644 --- a/src/cycling.c +++ b/src/cycling.c @@ -81,7 +81,7 @@ static WWindow *change_focus_and_raise(WWindow *newFocused, WWindow *oldFocused, return oldFocused; } -void StartWindozeCycle(WWindow * wwin, XEvent * event, Bool next) +void StartWindozeCycle(WWindow * wwin, XEvent * event, Bool next, Bool class_only) { XModifierKeymap *keymap = NULL; @@ -123,7 +123,7 @@ void StartWindozeCycle(WWindow * wwin, XEvent * event, Bool next) scr->flags.doing_alt_tab = 1; - swpanel = wInitSwitchPanel(scr, wwin, scr->current_workspace); + swpanel = wInitSwitchPanel(scr, wwin, scr->current_workspace, class_only); oldFocused = wwin; if (swpanel) { @@ -159,6 +159,8 @@ void StartWindozeCycle(WWindow * wwin, XEvent * event, Bool next) if ((wKeyBindings[WKBD_FOCUSNEXT].keycode == ev.xkey.keycode && wKeyBindings[WKBD_FOCUSNEXT].modifier == modifiers) + || (wKeyBindings[WKBD_GROUPNEXT].keycode == ev.xkey.keycode + && wKeyBindings[WKBD_GROUPNEXT].modifier == modifiers) || ev.xkey.keycode == rightKey) { newFocused = wSwitchPanelSelectNext(swpanel, False); @@ -166,6 +168,8 @@ void StartWindozeCycle(WWindow * wwin, XEvent * event, Bool next) } else if ((wKeyBindings[WKBD_FOCUSPREV].keycode == ev.xkey.keycode && wKeyBindings[WKBD_FOCUSPREV].modifier == modifiers) + || (wKeyBindings[WKBD_GROUPPREV].keycode == ev.xkey.keycode + && wKeyBindings[WKBD_GROUPPREV].modifier == modifiers) || ev.xkey.keycode == leftKey) { newFocused = wSwitchPanelSelectNext(swpanel, True); @@ -199,7 +203,9 @@ void StartWindozeCycle(WWindow * wwin, XEvent * event, Bool next) if (keymap->modifiermap[i] == ev.xkey.keycode && ((wKeyBindings[WKBD_FOCUSNEXT].modifier & mask) - || (wKeyBindings[WKBD_FOCUSPREV].modifier & mask))) { + || (wKeyBindings[WKBD_FOCUSPREV].modifier & mask) + || (wKeyBindings[WKBD_GROUPNEXT].modifier & mask) + || (wKeyBindings[WKBD_GROUPPREV].modifier & mask))) { done = True; break; } diff --git a/src/defaults.c b/src/defaults.c index 61756b0e..555bdac1 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -601,6 +601,10 @@ WDefaultEntry optionList[] = { NULL, getKeybind, setKeyGrab}, {"FocusPrevKey", "None", (void *)WKBD_FOCUSPREV, NULL, getKeybind, setKeyGrab}, + {"GroupNextKey", "None", (void *)WKBD_GROUPNEXT, + NULL, getKeybind, setKeyGrab}, + {"GroupPrevKey", "None", (void *)WKBD_GROUPPREV, + NULL, getKeybind, setKeyGrab}, {"NextWorkspaceKey", "None", (void *)WKBD_NEXTWORKSPACE, NULL, getKeybind, setKeyGrab}, {"PrevWorkspaceKey", "None", (void *)WKBD_PREVWORKSPACE, diff --git a/src/event.c b/src/event.c index 023e896e..71720b63 100644 --- a/src/event.c +++ b/src/event.c @@ -1542,11 +1542,19 @@ static void handleKeyPress(XEvent * event) } break; case WKBD_FOCUSNEXT: - StartWindozeCycle(wwin, event, True); + StartWindozeCycle(wwin, event, True, False); break; case WKBD_FOCUSPREV: - StartWindozeCycle(wwin, event, False); + StartWindozeCycle(wwin, event, False, False); + break; + + case WKBD_GROUPNEXT: + StartWindozeCycle(wwin, event, True, True); + break; + + case WKBD_GROUPPREV: + StartWindozeCycle(wwin, event, False, True); break; case WKBD_WORKSPACE1 ... WKBD_WORKSPACE10: diff --git a/src/funcs.h b/src/funcs.h index c900976a..f49536ef 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -85,7 +85,7 @@ void PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned int width, unsigned int height); -void StartWindozeCycle(WWindow *wwin, XEvent *event, Bool next); +void StartWindozeCycle(WWindow *wwin, XEvent *event, Bool next, Bool class_only); #ifdef USECPP char *MakeCPPArgs(char *path); diff --git a/src/keybind.h b/src/keybind.h index 995e7a70..2daca8d6 100644 --- a/src/keybind.h +++ b/src/keybind.h @@ -44,6 +44,8 @@ enum { WKBD_SHADE, WKBD_FOCUSNEXT, WKBD_FOCUSPREV, + WKBD_GROUPNEXT, + WKBD_GROUPPREV, /* window, menu */ WKBD_CLOSE, diff --git a/src/switchpanel.c b/src/switchpanel.c index 3e1ae158..41cb1ba4 100644 --- a/src/switchpanel.c +++ b/src/switchpanel.c @@ -374,7 +374,7 @@ static void drawTitle(WSwitchPanel * panel, int idecks, char *title) free(ntitle); } -static WMArray *makeWindowListArray(WScreen * scr, WWindow * curwin, int workspace, int include_unmapped) +static WMArray *makeWindowListArray(WScreen * scr, WWindow * curwin, int workspace, int include_unmapped, Bool class_only) { WMArray *windows = WMCreateArray(10); int fl; @@ -385,6 +385,12 @@ static WMArray *makeWindowListArray(WScreen * scr, WWindow * curwin, int workspa if (((!fl && canReceiveFocus(wwin) > 0) || (fl && canReceiveFocus(wwin) < 0)) && (!WFLAGP(wwin, skip_window_list) || wwin->flags.internal_window) && (wwin->flags.mapped || include_unmapped)) { + if (class_only) { + if (!wwin->wm_class || !curwin->wm_class) + continue; + if (strcmp(wwin->wm_class, curwin->wm_class)) + continue; + } WMAddToArray(windows, wwin); } } @@ -397,6 +403,12 @@ static WMArray *makeWindowListArray(WScreen * scr, WWindow * curwin, int workspa if (((!fl && canReceiveFocus(wwin) > 0) || (fl && canReceiveFocus(wwin) < 0)) && (!WFLAGP(wwin, skip_window_list) || wwin->flags.internal_window) && (wwin->flags.mapped || include_unmapped)) { + if (class_only) { + if (!wwin->wm_class || !curwin->wm_class) + continue; + if (strcmp(wwin->wm_class, curwin->wm_class)) + continue; + } WMAddToArray(windows, wwin); } } @@ -405,7 +417,7 @@ static WMArray *makeWindowListArray(WScreen * scr, WWindow * curwin, int workspa return windows; } -WSwitchPanel *wInitSwitchPanel(WScreen * scr, WWindow * curwin, int workspace) +WSwitchPanel *wInitSwitchPanel(WScreen * scr, WWindow * curwin, int workspace, Bool class_only) { WWindow *wwin; WSwitchPanel *panel = wmalloc(sizeof(WSwitchPanel)); @@ -421,7 +433,7 @@ WSwitchPanel *wInitSwitchPanel(WScreen * scr, WWindow * curwin, int workspace) panel->scr = scr; - panel->windows = makeWindowListArray(scr, curwin, workspace, wPreferences.swtileImage != 0); + panel->windows = makeWindowListArray(scr, curwin, workspace, wPreferences.swtileImage != 0, class_only); count = WMGetArrayItemCount(panel->windows); if (count == 0) { diff --git a/src/switchpanel.h b/src/switchpanel.h index 6a931b0f..0ed19280 100644 --- a/src/switchpanel.h +++ b/src/switchpanel.h @@ -24,7 +24,7 @@ typedef struct SwitchPanel WSwitchPanel; -WSwitchPanel *wInitSwitchPanel(WScreen *scr, WWindow *curwin, int workspace); +WSwitchPanel *wInitSwitchPanel(WScreen *scr, WWindow *curwin, int workspace, Bool class_only); void wSwitchPanelDestroy(WSwitchPanel *panel);