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

MultitaskingView: move keyboard navigation code into WindowCloneContainer #1793

Merged
merged 7 commits into from
Feb 10, 2024
Merged
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
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