Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Next] Add hotkey support for (tiling-) window switching #700

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions debian/libmuffin0.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,7 @@ libmuffin.so.0 libmuffin0 #MINVER#
meta_display_get_tab_current@Base 5.3.0
meta_display_get_tab_list@Base 5.3.0
meta_display_get_tab_next@Base 5.3.0
meta_display_get_tab_in_direction@Base 6.0.1
meta_display_get_type@Base 5.3.0
meta_display_get_workspace_manager@Base 5.3.0
meta_display_get_x11_display@Base 5.3.0
Expand Down
122 changes: 122 additions & 0 deletions src/core/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -2418,6 +2418,94 @@ find_tab_backward (MetaDisplay *display,
return NULL;
}

static bool
tab_position_nearer(MetaWindow* test,
MetaWindow* current,
MetaWindow* target)
{
int test_center_x = test->rect.x + test->rect.width / 2;
int test_center_y = test->rect.y + test->rect.height / 2;
int current_center_x = current->rect.x + current->rect.width / 2;
int current_center_y = current->rect.y + current->rect.height / 2;
int target_center_x = target->rect.x + target->rect.width / 2;
int target_center_y = target->rect.y + target->rect.height / 2;

float test_distance = sqrt(pow(test_center_x - current_center_x, 2) +
pow(test_center_y - current_center_y, 2));
float target_distance = sqrt(pow(target_center_x - current_center_x, 2) +
pow(target_center_y - current_center_y, 2));

return (test_distance < target_distance);
}

static bool
tab_position_behind(MetaWindow* test,
MetaWindow* current,
MetaDirection direction)
{
int test_center_x = test->rect.x + test->rect.width / 2;
int test_center_y = test->rect.y + test->rect.height / 2;
int current_center_x = current->rect.x + current->rect.width / 2;
int current_center_y = current->rect.y + current->rect.height / 2;

return ((direction == META_DIRECTION_RIGHT &&
test_center_x > current_center_x) ||
(direction == META_DIRECTION_LEFT &&
test_center_x < current_center_x) ||
(direction == META_DIRECTION_UP &&
test_center_y < current_center_y) ||
(direction == META_DIRECTION_DOWN &&
test_center_y > current_center_y));
}

static bool
tab_is_next_in_direction (MetaWindow* test,
MetaWindow* current,
MetaWindow* target,
MetaDirection direction)
{
return (tab_position_behind(test, current, direction) &&
(target == current || tab_position_nearer(test, current, target)));
}

static MetaWindow*
find_tab_in_direction (MetaDisplay *display,
MetaTabList type,
MetaWorkspace *workspace,
GList *start,
MetaDirection direction)
{
GList *result;
GList *tmp;

g_return_val_if_fail (start != NULL, NULL);
g_return_val_if_fail (workspace != NULL, NULL);

result = start;
tmp = start->next;

while (tmp != NULL) {
MetaWindow *window = tmp->data;
if (IN_TAB_CHAIN (window, type) &&
!window->minimized &&
tab_is_next_in_direction(window, start->data, result->data, direction))
result = tmp;
tmp = tmp->next;
}

tmp = workspace->mru_list;
while (tmp != start && tmp != NULL) {
MetaWindow *window = tmp->data;
if (IN_TAB_CHAIN (window, type) &&
!window->minimized &&
tab_is_next_in_direction(window, start->data, result->data, direction))
result = tmp;
tmp = tmp->next;
}

return result->data;
}

static int
mru_cmp (gconstpointer a,
gconstpointer b)
Expand Down Expand Up @@ -2592,6 +2680,40 @@ meta_display_get_tab_current (MetaDisplay *display,
return NULL;
}

/**
* meta_display_get_tab_in_direction:
* @display: a #MetaDisplay
* @type: type of tab list
* @workspace: origin workspace
* @window: (nullable): starting window
* @direction: The direction that should be searched.
*
* Determine the nearest window in the given direction.
*
* Returns: (transfer none): The next window in the given direction
*
*/
MetaWindow*
meta_display_get_tab_in_direction (MetaDisplay *display,
MetaTabList type,
MetaWorkspace *workspace,
MetaWindow *window,
MetaDirection direction)
{
gboolean skip;
GList *tab_list;
MetaWindow *ret;
tab_list = meta_display_get_tab_list (display, type, workspace);

if (tab_list == NULL)
return NULL;

ret = find_tab_in_direction (display, type, workspace, tab_list, direction);

g_list_free (tab_list);
return ret;
}

MetaGravity
meta_resize_gravity_from_grab_op (MetaGrabOp op)
{
Expand Down
89 changes: 89 additions & 0 deletions src/core/keybindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -3491,6 +3491,67 @@ handle_cycle (MetaDisplay *display,
do_choose_window (display, event_window, event, binding, backwards);
}

static void
handle_switch_tile_action (MetaDisplay *display,
MetaWindow *event_window,
ClutterKeyEvent *event,
MetaKeyBinding *binding,
MetaDirection direction)
{
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
MetaTabList type = binding->handler->data;
MetaWindow *window;

window = meta_display_get_tab_in_direction (display,
type,
workspace_manager->active_workspace,
NULL,
direction);

if (window)
meta_window_activate (window, event->time);
}

static void
handle_switch_tile_action_right (MetaDisplay *display,
MetaWindow *event_window,
ClutterKeyEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_switch_tile_action (display, event_window, event, binding, META_DIRECTION_RIGHT);
}

static void
handle_switch_tile_action_left (MetaDisplay *display,
MetaWindow *event_window,
ClutterKeyEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_switch_tile_action (display, event_window, event, binding, META_DIRECTION_LEFT);
}

static void
handle_switch_tile_action_up (MetaDisplay *display,
MetaWindow *event_window,
ClutterKeyEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_switch_tile_action (display, event_window, event, binding, META_DIRECTION_UP);
}

static void
handle_switch_tile_action_down (MetaDisplay *display,
MetaWindow *event_window,
ClutterKeyEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_switch_tile_action (display, event_window, event, binding, META_DIRECTION_DOWN);
}

static void
handle_toggle_fullscreen (MetaDisplay *display,
MetaWindow *window,
Expand Down Expand Up @@ -4598,6 +4659,34 @@ init_builtin_key_bindings (MetaDisplay *display)
META_KEYBINDING_ACTION_PUSH_TILE_DOWN,
handle_tile_action, META_TILE_BOTTOM);

add_builtin_keybinding (display,
"switch-to-tile-left",
common_keybindings,
META_KEY_BINDING_NONE,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_LEFT,
handle_switch_tile_action_left, META_TAB_LIST_NORMAL);

add_builtin_keybinding (display,
"switch-to-tile-right",
common_keybindings,
META_KEY_BINDING_NONE,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_RIGHT,
handle_switch_tile_action_right, META_TAB_LIST_NORMAL);

add_builtin_keybinding (display,
"switch-to-tile-up",
common_keybindings,
META_KEY_BINDING_NONE,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_UP,
handle_switch_tile_action_up, META_TAB_LIST_NORMAL);

add_builtin_keybinding (display,
"switch-to-tile-down",
common_keybindings,
META_KEY_BINDING_NONE,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_DOWN,
handle_switch_tile_action_down, META_TAB_LIST_NORMAL);

add_builtin_keybinding (display,
"toggle-above",
common_keybindings,
Expand Down
7 changes: 7 additions & 0 deletions src/meta/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ MetaWindow* meta_display_get_tab_next (MetaDisplay *display,
MetaWindow *window,
gboolean backward);

META_EXPORT
MetaWindow* meta_display_get_tab_in_direction (MetaDisplay *display,
MetaTabList type,
MetaWorkspace *workspace,
MetaWindow *window,
MetaDirection direction);

META_EXPORT
MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
MetaTabList type,
Expand Down
8 changes: 8 additions & 0 deletions src/meta/prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ gboolean meta_prefs_get_invert_flip_direction (void);
* @META_KEYBINDING_ACTION_PUSH_TILE_RIGHT: FILLME
* @META_KEYBINDING_ACTION_PUSH_TILE_UP: FILLME
* @META_KEYBINDING_ACTION_PUSH_TILE_DOWN: FILLME
* @META_KEYBINDING_ACTION_SWITCH_TO_TILE_LEFT: FILLME
* @META_KEYBINDING_ACTION_SWITCH_TO_TILE_RIGHT: FILLME
* @META_KEYBINDING_ACTION_SWITCH_TO_TILE_UP: FILLME
* @META_KEYBINDING_ACTION_SWITCH_TO_TILE_DOWN: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE: FILLME
* @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME
Expand Down Expand Up @@ -432,6 +436,10 @@ typedef enum _MetaKeyBindingAction
META_KEYBINDING_ACTION_PUSH_TILE_RIGHT,
META_KEYBINDING_ACTION_PUSH_TILE_UP,
META_KEYBINDING_ACTION_PUSH_TILE_DOWN,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_LEFT,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_RIGHT,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_UP,
META_KEYBINDING_ACTION_SWITCH_TO_TILE_DOWN,
META_KEYBINDING_ACTION_TOGGLE_ABOVE,
META_KEYBINDING_ACTION_MAXIMIZE,
META_KEYBINDING_ACTION_UNMAXIMIZE,
Expand Down
Loading