Skip to content

Commit

Permalink
MultitaskingView: move keyboard navigation code into WindowCloneConta…
Browse files Browse the repository at this point in the history
…iner (#1793)

Co-authored-by: Leonhard <[email protected]>
  • Loading branch information
lenemter and leolost2605 committed Feb 10, 2024
1 parent ff1ee4c commit 517ba7d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 122 deletions.
54 changes: 10 additions & 44 deletions src/Widgets/MultitaskingView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -595,58 +595,24 @@ namespace Gala {
public override bool key_press_event (Clutter.KeyEvent event) {
#endif
if (!opened) {
return true;
}

switch (event.get_key_symbol ()) {
case Clutter.Key.Escape:
toggle ();
break;
case Clutter.Key.Down:
select_window (Meta.MotionDirection.DOWN);
break;
case Clutter.Key.Up:
select_window (Meta.MotionDirection.UP);
break;
case Clutter.Key.Left:
select_window (Meta.MotionDirection.LEFT);
break;
case Clutter.Key.Right:
select_window (Meta.MotionDirection.RIGHT);
break;
case Clutter.Key.Return:
case Clutter.Key.KP_Enter:
if (!get_active_workspace_clone ().window_container.activate_selected_window ()) {
toggle ();
}

break;
return Clutter.EVENT_PROPAGATE;
}

return false;
}

/**
* Inform the current WindowCloneContainer that we want to move the focus in
* a specific direction.
*
* @param direction The direction in which to move the focus to
*/
private void select_window (Meta.MotionDirection direction) {
get_active_workspace_clone ().window_container.select_next_window (direction);
return get_active_window_clone_container ().key_press_event (event);
}

/**
* Finds the active WorkspaceClone
*
* @return The active WorkspaceClone
*/
private WorkspaceClone get_active_workspace_clone () {
unowned Meta.WorkspaceManager manager = display.get_workspace_manager ();
private WindowCloneContainer get_active_window_clone_container () {
unowned var manager = display.get_workspace_manager ();
unowned var active_workspace = manager.get_active_workspace ();
foreach (unowned var child in workspaces.get_children ()) {
unowned WorkspaceClone workspace_clone = (WorkspaceClone) child;
if (workspace_clone.workspace == manager.get_active_workspace ()) {
return workspace_clone;
unowned var workspace_clone = (WorkspaceClone) child;
if (workspace_clone.workspace == active_workspace) {
return workspace_clone.window_container;
}
}

Expand All @@ -655,8 +621,8 @@ namespace Gala {

private void window_selected (Meta.Window window) {
var time = display.get_current_time ();
unowned Meta.WorkspaceManager manager = display.get_workspace_manager ();
var workspace = window.get_workspace ();
unowned var manager = display.get_workspace_manager ();
unowned var workspace = window.get_workspace ();

if (workspace != manager.get_active_workspace ()) {
workspace.activate (time);
Expand Down
126 changes: 69 additions & 57 deletions src/Widgets/WindowCloneContainer.vala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Gala {
*/
public class WindowCloneContainer : Clutter.Actor {
public signal void window_selected (Meta.Window window);
public signal void requested_close ();

public int padding_top { get; set; default = 12; }
public int padding_left { get; set; default = 12; }
Expand Down Expand Up @@ -82,9 +83,9 @@ namespace Gala {

var new_window = new WindowClone (wm, window, gesture_tracker, monitor_scale, overview_mode);

new_window.selected.connect (window_selected_cb);
new_window.destroy.connect (window_destroyed);
new_window.request_reposition.connect (window_request_reposition);
new_window.selected.connect ((clone) => window_selected (clone.window));
new_window.destroy.connect (() => reflow ());
new_window.request_reposition.connect (() => reflow ());

unowned Meta.Window? target = null;
foreach (unowned var w in windows_ordered) {
Expand Down Expand Up @@ -124,24 +125,6 @@ namespace Gala {
}
}

private void window_selected_cb (WindowClone clone) {
window_selected (clone.window);
}

private void window_destroyed (Clutter.Actor actor) {
unowned var clone = (WindowClone) actor;

clone.destroy.disconnect (window_destroyed);
clone.selected.disconnect (window_selected_cb);
clone.request_reposition.disconnect (window_request_reposition);

reflow ();
}

private void window_request_reposition () {
reflow ();
}

/**
* Sort the windows z-order by their actual stacking to make intersections
* during animations correct.
Expand Down Expand Up @@ -217,6 +200,47 @@ namespace Gala {
}
}

/**
* Collect key events, mainly for redirecting them to the WindowCloneContainers to
* select the active window.
*/
#if HAS_MUTTER45
public override bool key_press_event (Clutter.Event event) {
#else
public override bool key_press_event (Clutter.KeyEvent event) {
#endif
if (!opened) {
return Clutter.EVENT_PROPAGATE;
}


switch (event.get_key_symbol ()) {
case Clutter.Key.Escape:
requested_close ();
break;
case Clutter.Key.Down:
select_next_window (Meta.MotionDirection.DOWN);
break;
case Clutter.Key.Up:
select_next_window (Meta.MotionDirection.UP);
break;
case Clutter.Key.Left:
select_next_window (Meta.MotionDirection.LEFT);
break;
case Clutter.Key.Right:
select_next_window (Meta.MotionDirection.RIGHT);
break;
case Clutter.Key.Return:
case Clutter.Key.KP_Enter:
if (!activate_selected_window ()) {
requested_close ();
}
break;
}

return Clutter.EVENT_STOP;
}

/**
* Look for the next window in a direction and make this window the
* new current_window. Used for keyboard navigation.
Expand All @@ -228,23 +252,21 @@ namespace Gala {
return;
}

if (current_window == null) {
current_window = (WindowClone) get_child_at_index (0);
return;
}
WindowClone? closest = null;

var current_rect = current_window.slot;
if (current_window == null) {
closest = (WindowClone) get_child_at_index (0);
} else {
var current_rect = current_window.slot;

WindowClone? closest = null;
foreach (unowned var child in get_children ()) {
if (child == current_window) {
continue;
}
foreach (unowned var child in get_children ()) {
if (child == current_window) {
continue;
}

var window_rect = ((WindowClone) child).slot;
var window_rect = ((WindowClone) child).slot;

switch (direction) {
case Meta.MotionDirection.LEFT:
if (direction == LEFT) {
if (window_rect.x > current_rect.x) {
continue;
}
Expand All @@ -253,14 +275,11 @@ namespace Gala {
if (window_rect.y + window_rect.height > current_rect.y
&& window_rect.y < current_rect.y + current_rect.height) {

if (closest == null
|| closest.slot.x < window_rect.x) {

if (closest == null || closest.slot.x < window_rect.x) {
closest = (WindowClone) child;
}
}
break;
case Meta.MotionDirection.RIGHT:
} else if (direction == RIGHT) {
if (window_rect.x < current_rect.x) {
continue;
}
Expand All @@ -269,14 +288,11 @@ namespace Gala {
if (window_rect.y + window_rect.height > current_rect.y
&& window_rect.y < current_rect.y + current_rect.height) {

if (closest == null
|| closest.slot.x > window_rect.x) {

if (closest == null || closest.slot.x > window_rect.x) {
closest = (WindowClone) child;
}
}
break;
case Meta.MotionDirection.UP:
} else if (direction == UP) {
if (window_rect.y > current_rect.y) {
continue;
}
Expand All @@ -285,14 +301,11 @@ namespace Gala {
if (window_rect.x + window_rect.width > current_rect.x
&& window_rect.x < current_rect.x + current_rect.width) {

if (closest == null
|| closest.slot.y < window_rect.y) {

closest = (WindowClone) child;
if (closest == null || closest.slot.y < window_rect.y) {
closest = (WindowClone) child;
}
}
break;
case Meta.MotionDirection.DOWN:
} else if (direction == DOWN) {
if (window_rect.y < current_rect.y) {
continue;
}
Expand All @@ -301,15 +314,14 @@ namespace Gala {
if (window_rect.x + window_rect.width > current_rect.x
&& window_rect.x < current_rect.x + current_rect.width) {

if (closest == null
|| closest.slot.y > window_rect.y) {

if (closest == null || closest.slot.y > window_rect.y) {
closest = (WindowClone) child;
}
}
} else {
warning ("Invalid direction");
break;
default:
break;
}
}
}

Expand All @@ -330,7 +342,7 @@ namespace Gala {
*/
public bool activate_selected_window () {
if (current_window != null) {
current_window.selected ();
window_selected (current_window.window);
return true;
}

Expand All @@ -340,7 +352,7 @@ namespace Gala {
/**
* When opened the WindowClones are animated to a tiled layout
*/
public void open (Meta.Window? selected_window = null, bool with_gesture = false, bool is_cancel_animation = false) {
public void open (Meta.Window? selected_window, bool with_gesture, bool is_cancel_animation) {
if (opened) {
return;
}
Expand Down
34 changes: 15 additions & 19 deletions src/Widgets/WindowOverview.vala
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent {
public WindowManager wm { get; construct; }

private ModalProxy modal_proxy;

// the workspaces which we expose right now
private List<Meta.Workspace> workspaces;
private WindowCloneContainer window_clone_container;

public WindowOverview (WindowManager wm) {
Object (wm : wm);
Expand All @@ -26,24 +26,17 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent {
reactive = true;
}


#if HAS_MUTTER45
public override bool key_press_event (Clutter.Event event) {
#else
public override bool key_press_event (Clutter.KeyEvent event) {
#endif
if (event.get_key_symbol () == Clutter.Key.Escape) {
close ();

return Clutter.EVENT_STOP;
if (!is_opened ()) {
return Clutter.EVENT_PROPAGATE;
}

return Clutter.EVENT_PROPAGATE;
}

public override void key_focus_out () {
if (!contains (get_stage ().key_focus)) {
close ();
}
return window_clone_container.key_press_event (event);
}

#if HAS_MUTTER45
Expand Down Expand Up @@ -131,17 +124,20 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent {
var geometry = display.get_monitor_geometry (i);
var scale = display.get_monitor_scale (i);

var container = new WindowCloneContainer (wm, null, scale, true) {
window_clone_container = new WindowCloneContainer (wm, null, scale, true) {
padding_top = TOP_GAP,
padding_left = BORDER,
padding_right = BORDER,
padding_bottom = BOTTOM_GAP
padding_bottom = BOTTOM_GAP,
width = geometry.width,
height = geometry.height,
x = geometry.x,
y = geometry.y,
};
container.set_position (geometry.x, geometry.y);
container.set_size (geometry.width, geometry.height);
container.window_selected.connect (thumb_selected);
window_clone_container.window_selected.connect (thumb_selected);
window_clone_container.requested_close.connect (() => close ());

add_child (container);
add_child (window_clone_container);
}

visible = true;
Expand All @@ -156,7 +152,7 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent {
}

container.add_window (window);
container.open ();
container.open (display.get_focus_window (), false, false);
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/Widgets/WorkspaceClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,12 @@ namespace Gala {
background = new FramedBackground (wm);
background.add_action (background_click_action);

window_container = new WindowCloneContainer (wm, gesture_tracker, scale_factor);
window_container = new WindowCloneContainer (wm, gesture_tracker, scale_factor) {
width = monitor_geometry.width,
height = monitor_geometry.height,
};
window_container.window_selected.connect ((w) => { window_selected (w); });
window_container.set_size (monitor_geometry.width, monitor_geometry.height);
window_container.requested_close.connect (() => selected (true));

icon_group = new IconGroup (wm, workspace, scale_factor);
icon_group.selected.connect (() => selected (true));
Expand Down

0 comments on commit 517ba7d

Please sign in to comment.