diff --git a/settings-dialogs/xfwm4-settings.c b/settings-dialogs/xfwm4-settings.c index 212e4e7..87477a6 100644 --- a/settings-dialogs/xfwm4-settings.c +++ b/settings-dialogs/xfwm4-settings.c @@ -305,6 +305,10 @@ static const ShortcutTemplate shortcut_values[] = { { N_("Add adjacent workspace"), "add_adjacent_workspace_key", NULL }, { N_("Delete last workspace"), "del_workspace_key", NULL }, { N_("Delete active workspace"), "del_active_workspace_key", NULL }, + { N_("Focus higher window"), "focus_up_key", NULL }, + { N_("Focus left window"), "focus_left_key", NULL }, + { N_("Focus lower window"), "focus_down_key", NULL }, + { N_("Focus right window"), "focus_right_key", NULL }, { NULL, NULL, NULL } }; diff --git a/src/cycle.h b/src/cycle.h index 58c192d..6b2217e 100644 --- a/src/cycle.h +++ b/src/cycle.h @@ -38,4 +38,5 @@ void clientCycle (Client *, XKeyEvent *); gboolean clientSwitchWindow (void); gboolean clientSwitchApp (void); +void clientFocusDirection (Client * c, int dir); #endif /* INC_CYCLE_H */ diff --git a/src/events.c b/src/events.c index 4b49171..92fe8a2 100644 --- a/src/events.c +++ b/src/events.c @@ -450,6 +450,12 @@ handleKeyPress (DisplayInfo *display_info, XKeyEvent * ev) frameY (c) + frameHeight (c) / 2, TILE_UP, TRUE); break; + case KEY_FOCUS_UP: + case KEY_FOCUS_LEFT: + case KEY_FOCUS_DOWN: + case KEY_FOCUS_RIGHT: + clientFocusDirection(c, key - KEY_FOCUS_UP); + break; default: break; } diff --git a/src/focus.c b/src/focus.c index c1f870c..7a0005a 100644 --- a/src/focus.c +++ b/src/focus.c @@ -61,6 +61,8 @@ static Client *user_focus = NULL; static Client *delayed_focus = NULL; static guint focus_timeout = 0; +typedef enum _FocusDirection { FOCUS_UP, FOCUS_LEFT, FOCUS_DOWN, FOCUS_RIGHT } FocusDirection; + #if 0 static void clientDumpList (ScreenInfo *screen_info) @@ -787,3 +789,51 @@ clientGetDelayedFocus (void) { return delayed_focus; } + +void +clientFocusDirection (Client * c, int dir) +{ + Client *c2, *n = NULL; + guint i; + gint diff = 0, cur = 1024 * 1024; + + g_return_if_fail (c); + TRACE ("entering focus direction"); + + for (c2 = c->next, i = 1; c && i < c->screen_info->client_count; i++, c2 = c2->next) + { + if (!clientSelectMask (c2, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) + { + TRACE ("%s not in select mask", c2->name); + continue; + } + + switch (dir) + { + case FOCUS_UP: + diff = c->y - c2->y; + break; + case FOCUS_DOWN: + diff = c2->y - c->y; + break; + case FOCUS_LEFT: + diff = c->x - c2->x; + break; + case FOCUS_RIGHT: + diff = c2->x - c->x; + break; + } + + if (diff > 0 && cur > diff) + { + cur = diff; + n = c2; + } + } + + if (n) + { + clientSetFocus (c->screen_info, n, myDisplayGetCurrentTime (c->screen_info->display_info), + NO_FOCUS_FLAG); + } +} diff --git a/src/settings.c b/src/settings.c index 607bb7b..f912884 100644 --- a/src/settings.c +++ b/src/settings.c @@ -618,7 +618,11 @@ loadKeyBindings (ScreenInfo *screen_info) parseShortcut (screen_info, KEY_TOGGLE_ABOVE, "above_key", shortcuts); parseShortcut (screen_info, KEY_TOGGLE_FULLSCREEN, "fullscreen_key", shortcuts); parseShortcut (screen_info, KEY_UP_WORKSPACE, "up_workspace_key", shortcuts); - + parseShortcut (screen_info, KEY_FOCUS_UP, "focus_up_key", shortcuts); + parseShortcut (screen_info, KEY_FOCUS_LEFT, "focus_left_key", shortcuts); + parseShortcut (screen_info, KEY_FOCUS_DOWN, "focus_down_key", shortcuts); + parseShortcut (screen_info, KEY_FOCUS_RIGHT, "focus_right_key", shortcuts); + for (i = 0; i < 12; i++) { g_snprintf(keyname, sizeof (keyname), "move_window_workspace_%d_key", i + 1); diff --git a/src/settings.h b/src/settings.h index be01b6b..32a5a3e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -119,6 +119,10 @@ enum KEY_WORKSPACE_10, KEY_WORKSPACE_11, KEY_WORKSPACE_12, + KEY_FOCUS_UP, + KEY_FOCUS_LEFT, + KEY_FOCUS_DOWN, + KEY_FOCUS_RIGHT, KEY_COUNT };