Skip to content

Commit 75bd177

Browse files
committed
Root instead of focuscontroller
1 parent 4c7da9c commit 75bd177

File tree

6 files changed

+84
-87
lines changed

6 files changed

+84
-87
lines changed

lib/Widget/FocusController.vala

Lines changed: 0 additions & 73 deletions
This file was deleted.

lib/Widget/Root.vala

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2025 elementary, Inc. (https://elementary.io)
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*
5+
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
6+
*/
7+
8+
public class Gala.Root : Widget {
9+
private bool _focus_visible = false;
10+
internal bool focus_visible {
11+
get { return _focus_visible; }
12+
set {
13+
_focus_visible = value;
14+
(get_stage ().key_focus as Widget)?.focus_changed ();
15+
}
16+
}
17+
18+
private uint timeout_id = 0;
19+
20+
public override void map () {
21+
base.map ();
22+
// In the case the key focus moves out of our widget tree by some other means
23+
// make sure we can recapture it
24+
get_stage ().key_press_event.connect (check_focus);
25+
}
26+
27+
public override void unmap () {
28+
base.unmap ();
29+
get_stage ().key_press_event.disconnect (check_focus);
30+
}
31+
32+
public override bool key_press_event (Clutter.Event event) {
33+
return check_focus (event);
34+
}
35+
36+
private bool check_focus (Clutter.Event event) {
37+
var direction = FocusDirection.get_for_event (event);
38+
39+
if (direction == null) {
40+
return Clutter.EVENT_PROPAGATE;
41+
}
42+
43+
if (!focus (direction)) {
44+
#if HAS_MUTTER47
45+
get_stage ().context.get_backend ().get_default_seat ().bell_notify ();
46+
#else
47+
Clutter.get_default_backend ().get_default_seat ().bell_notify ();
48+
#endif
49+
50+
if (!(get_stage ().key_focus in this)) {
51+
get_stage ().key_focus = this;
52+
}
53+
}
54+
55+
show_focus ();
56+
57+
return Clutter.EVENT_STOP;
58+
}
59+
60+
private void show_focus () {
61+
if (timeout_id != 0) {
62+
Source.remove (timeout_id);
63+
} else {
64+
focus_visible = true;
65+
}
66+
67+
timeout_id = Timeout.add_seconds (5, () => {
68+
focus_visible = false;
69+
timeout_id = 0;
70+
return Source.REMOVE;
71+
});
72+
}
73+
}

lib/Widget/Widget.vala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ public class Gala.Widget : ActorTarget {
1515
}
1616

1717
internal void focus_changed () {
18-
has_visible_focus = has_key_focus () && get_root ().get_qdata<bool> (FocusController.focus_visible_quark);
18+
has_visible_focus = has_key_focus () && get_root ().focus_visible;
1919
}
2020

21-
private Widget get_root () {
22-
var parent = get_parent ();
23-
if (parent is Widget) {
24-
return parent.get_root ();
21+
private Root? get_root () {
22+
for (Clutter.Actor? actor = this; actor is Widget; actor = actor.get_parent ()) {
23+
if (actor is Root) {
24+
return (Root) actor;
25+
}
2526
}
2627

27-
return this;
28+
return null;
2829
}
2930

3031
public bool focus (FocusDirection direction) {

lib/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ gala_lib_sources = files(
4444
'Gestures/ToucheggBackend.vala',
4545
'Gestures/TouchpadBackend.vala',
4646
'Gestures/WorkspaceHideTracker.vala',
47-
'Widget/FocusController.vala',
4847
'Widget/FocusUtils.vala',
48+
'Widget/Root.vala',
4949
'Widget/Widget.vala',
5050
) + gala_common_enums
5151

src/Widgets/MultitaskingView/MultitaskingView.vala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* preparing the wm, opening the components and holds containers for
2121
* the icon groups, the WorkspaceClones and the MonitorClones.
2222
*/
23-
public class Gala.MultitaskingView : Widget, RootTarget, ActivatableComponent {
23+
public class Gala.MultitaskingView : Root, RootTarget, ActivatableComponent {
2424
public const int ANIMATION_DURATION = 250;
2525

2626
private GestureController workspaces_gesture_controller;
@@ -59,8 +59,6 @@ public class Gala.MultitaskingView : Widget, RootTarget, ActivatableComponent {
5959
opened = false;
6060
display = wm.get_display ();
6161

62-
add_action (new FocusController (wm.stage));
63-
6462
multitasking_gesture_controller = new GestureController (MULTITASKING_VIEW);
6563
multitasking_gesture_controller.add_trigger (new GlobalTrigger (MULTITASKING_VIEW, wm));
6664
add_gesture_controller (multitasking_gesture_controller);

src/Widgets/WindowOverview.vala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* SPDX-License-Identifier: GPL-3.0-or-later
66
*/
77

8-
public class Gala.WindowOverview : Widget, RootTarget, ActivatableComponent {
8+
public class Gala.WindowOverview : Root, RootTarget, ActivatableComponent {
99
private const int BORDER = 10;
1010
private const int TOP_GAP = 30;
1111
private const int BOTTOM_GAP = 100;
@@ -33,8 +33,6 @@ public class Gala.WindowOverview : Widget, RootTarget, ActivatableComponent {
3333
enabled = false
3434
};
3535
add_gesture_controller (gesture_controller);
36-
37-
add_action (new FocusController (wm.stage));
3836
}
3937

4038
public override bool key_press_event (Clutter.Event event) {
@@ -45,7 +43,7 @@ public class Gala.WindowOverview : Widget, RootTarget, ActivatableComponent {
4543
close ();
4644
return Clutter.EVENT_STOP;
4745
default:
48-
return Clutter.EVENT_PROPAGATE;
46+
return base.key_press_event (event);
4947
}
5048
}
5149

0 commit comments

Comments
 (0)