Skip to content

Commit 37cd466

Browse files
authored
Merge branch 'main' into lenemter/notifications-manager
2 parents 1416bf5 + 4ed139b commit 37cd466

File tree

3 files changed

+384
-426
lines changed

3 files changed

+384
-426
lines changed

src/Widgets/DwellClickTimer.vala

Lines changed: 125 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,183 +1,168 @@
1-
//
2-
// Copyright 2020 elementary, Inc. (https://elementary.io)
3-
//
4-
// This program is free software: you can redistribute it and/or modify
5-
// it under the terms of the GNU General Public License as published by
6-
// the Free Software Foundation, either version 3 of the License, or
7-
// (at your option) any later version.
8-
//
9-
// This program is distributed in the hope that it will be useful,
10-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-
// GNU General Public License for more details.
13-
//
14-
// You should have received a copy of the GNU General Public License
15-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
//
17-
18-
namespace Gala {
19-
public class DwellClickTimer : Clutter.Actor, Clutter.Animatable {
20-
private const double BACKGROUND_OPACITY = 0.7;
21-
private const int BORDER_WIDTH_PX = 1;
22-
23-
private const double START_ANGLE = 3 * Math.PI / 2;
24-
25-
/**
26-
* Delay, in milliseconds, before showing the animation.
27-
* libinput uses a timeout of 180ms when tapping is enabled. Use that value plus a safety
28-
* margin so the animation is never displayed when tapping.
29-
*/
30-
private const double DELAY_TIMEOUT = 185;
31-
32-
private float scaling_factor = 1.0f;
33-
private int cursor_size = 24;
34-
35-
private Cogl.Pipeline pipeline;
36-
private Clutter.PropertyTransition transition;
37-
private Cairo.Pattern stroke_color;
38-
private Cairo.Pattern fill_color;
39-
private GLib.Settings interface_settings;
40-
private Cairo.ImageSurface surface;
41-
42-
public Meta.Display display { get; construct; }
43-
44-
public double angle { get; set; }
45-
46-
public DwellClickTimer (Meta.Display display) {
47-
Object (display: display);
48-
}
1+
/*
2+
* SPDX-License-Identifier: GPL-3.0-or-later
3+
* SPDX-FileCopyrightText: 2020, 2025 elementary, Inc. (https://elementary.io)
4+
*/
495

50-
construct {
51-
visible = false;
52-
reactive = false;
6+
public class Gala.DwellClickTimer : Clutter.Actor, Clutter.Animatable {
7+
private const double BACKGROUND_OPACITY = 0.7;
8+
private const int BORDER_WIDTH_PX = 1;
9+
10+
private const double START_ANGLE = 3 * Math.PI / 2;
11+
12+
/**
13+
* Delay, in milliseconds, before showing the animation.
14+
* libinput uses a timeout of 180ms when tapping is enabled. Use that value plus a safety
15+
* margin so the animation is never displayed when tapping.
16+
*/
17+
private const double DELAY_TIMEOUT = 185;
18+
19+
private float scaling_factor = 1.0f;
20+
private int cursor_size = 24;
21+
22+
private Cogl.Pipeline pipeline;
23+
private Clutter.PropertyTransition transition;
24+
private Cairo.Pattern stroke_color;
25+
private Cairo.Pattern fill_color;
26+
private GLib.Settings interface_settings;
27+
private Cairo.ImageSurface surface;
28+
29+
public Meta.Display display { get; construct; }
30+
31+
public double angle { get; set; }
32+
33+
public DwellClickTimer (Meta.Display display) {
34+
Object (display: display);
35+
}
36+
37+
construct {
38+
visible = false;
39+
reactive = false;
5340

5441
#if HAS_MUTTER47
55-
unowned var backend = context.get_backend ();
42+
unowned var backend = context.get_backend ();
5643
#else
57-
unowned var backend = Clutter.get_default_backend ();
44+
unowned var backend = Clutter.get_default_backend ();
5845
#endif
5946

60-
pipeline = new Cogl.Pipeline (backend.get_cogl_context ());
47+
pipeline = new Cogl.Pipeline (backend.get_cogl_context ());
6148

62-
transition = new Clutter.PropertyTransition ("angle");
63-
transition.set_progress_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
64-
transition.set_animatable (this);
65-
transition.set_from_value (START_ANGLE);
66-
transition.set_to_value (START_ANGLE + (2 * Math.PI));
49+
transition = new Clutter.PropertyTransition ("angle");
50+
transition.set_progress_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
51+
transition.set_animatable (this);
52+
transition.set_from_value (START_ANGLE);
53+
transition.set_to_value (START_ANGLE + (2 * Math.PI));
6754

68-
transition.new_frame.connect (() => {
69-
queue_redraw ();
70-
});
55+
transition.new_frame.connect (() => {
56+
queue_redraw ();
57+
});
7158

72-
interface_settings = new GLib.Settings ("org.gnome.desktop.interface");
59+
interface_settings = new GLib.Settings ("org.gnome.desktop.interface");
7360

74-
var seat = backend.get_default_seat ();
75-
seat.set_pointer_a11y_dwell_click_type (Clutter.PointerA11yDwellClickType.PRIMARY);
61+
var seat = backend.get_default_seat ();
62+
seat.set_pointer_a11y_dwell_click_type (Clutter.PointerA11yDwellClickType.PRIMARY);
7663

77-
seat.ptr_a11y_timeout_started.connect ((device, type, timeout) => {
78-
var scale = display.get_monitor_scale (display.get_current_monitor ());
79-
update_cursor_size (scale);
64+
seat.ptr_a11y_timeout_started.connect ((device, type, timeout) => {
65+
var scale = display.get_monitor_scale (display.get_current_monitor ());
66+
update_cursor_size (scale);
8067

81-
unowned var tracker = display.get_cursor_tracker ();
82-
Graphene.Point coords = {};
83-
tracker.get_pointer (out coords, null);
68+
unowned var tracker = display.get_cursor_tracker ();
69+
Graphene.Point coords = {};
70+
tracker.get_pointer (out coords, null);
8471

85-
x = coords.x - (width / 2);
86-
y = coords.y - (width / 2);
72+
x = coords.x - (width / 2);
73+
y = coords.y - (width / 2);
8774

88-
transition.set_duration (timeout);
89-
visible = true;
90-
transition.start ();
91-
});
75+
transition.set_duration (timeout);
76+
visible = true;
77+
transition.start ();
78+
});
9279

93-
seat.ptr_a11y_timeout_stopped.connect ((device, type, clicked) => {
94-
transition.stop ();
95-
visible = false;
96-
});
97-
}
98-
99-
private void update_cursor_size (float scale) {
100-
scaling_factor = scale;
80+
seat.ptr_a11y_timeout_stopped.connect ((device, type, clicked) => {
81+
transition.stop ();
82+
visible = false;
83+
});
84+
}
10185

102-
cursor_size = (int) (interface_settings.get_int ("cursor-size") * scaling_factor * 1.25);
86+
private void update_cursor_size (float scale) {
87+
scaling_factor = scale;
10388

104-
if (surface == null || surface.get_width () != cursor_size || surface.get_height () != cursor_size) {
105-
surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, cursor_size, cursor_size);
106-
}
89+
cursor_size = (int) (interface_settings.get_int ("cursor-size") * scaling_factor * 1.25);
10790

108-
set_size (cursor_size, cursor_size);
91+
if (surface == null || surface.get_width () != cursor_size || surface.get_height () != cursor_size) {
92+
surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, cursor_size, cursor_size);
10993
}
11094

111-
public override void paint (Clutter.PaintContext context) {
112-
if (angle == 0) {
113-
return;
114-
}
95+
set_size (cursor_size, cursor_size);
96+
}
11597

116-
var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;
98+
public override void paint (Clutter.PaintContext context) {
99+
if (angle == 0) {
100+
return;
101+
}
117102

118-
/* Don't use alpha from the stylesheet to ensure contrast */
119-
stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue);
120-
fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY);
103+
var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;
121104

122-
var radius = int.min (cursor_size / 2, cursor_size / 2);
123-
var end_angle = START_ANGLE + angle;
124-
var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor);
105+
/* Don't use alpha from the stylesheet to ensure contrast */
106+
stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue);
107+
fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY);
125108

126-
var cr = new Cairo.Context (surface);
109+
var radius = int.min (cursor_size / 2, cursor_size / 2);
110+
var end_angle = START_ANGLE + angle;
111+
var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor);
127112

128-
// Clear the surface
129-
cr.save ();
130-
cr.set_source_rgba (0, 0, 0, 0);
131-
cr.set_operator (Cairo.Operator.SOURCE);
132-
cr.paint ();
133-
cr.restore ();
113+
var cr = new Cairo.Context (surface);
134114

135-
cr.set_line_cap (Cairo.LineCap.ROUND);
136-
cr.set_line_join (Cairo.LineJoin.ROUND);
137-
cr.translate (cursor_size / 2, cursor_size / 2);
115+
// Clear the surface
116+
cr.save ();
117+
cr.set_source_rgba (0, 0, 0, 0);
118+
cr.set_operator (Cairo.Operator.SOURCE);
119+
cr.paint ();
120+
cr.restore ();
138121

139-
cr.move_to (0, 0);
140-
cr.arc (0, 0, radius - border_width, START_ANGLE, end_angle);
141-
cr.line_to (0, 0);
142-
cr.close_path ();
122+
cr.set_line_cap (Cairo.LineCap.ROUND);
123+
cr.set_line_join (Cairo.LineJoin.ROUND);
124+
cr.translate (cursor_size / 2, cursor_size / 2);
143125

144-
cr.set_line_width (0);
145-
cr.set_source (fill_color);
146-
cr.fill_preserve ();
126+
cr.move_to (0, 0);
127+
cr.arc (0, 0, radius - border_width, START_ANGLE, end_angle);
128+
cr.line_to (0, 0);
129+
cr.close_path ();
147130

148-
cr.set_line_width (border_width);
149-
cr.set_source (stroke_color);
150-
cr.stroke ();
131+
cr.set_line_width (0);
132+
cr.set_source (fill_color);
133+
cr.fill_preserve ();
151134

152-
var cogl_context = context.get_framebuffer ().get_context ();
135+
cr.set_line_width (border_width);
136+
cr.set_source (stroke_color);
137+
cr.stroke ();
153138

154-
try {
155-
var texture = new Cogl.Texture2D.from_data (cogl_context, cursor_size, cursor_size, Cogl.PixelFormat.BGRA_8888_PRE,
156-
surface.get_stride (), surface.get_data ());
139+
var cogl_context = context.get_framebuffer ().get_context ();
157140

158-
pipeline.set_layer_texture (0, texture);
141+
try {
142+
var texture = new Cogl.Texture2D.from_data (cogl_context, cursor_size, cursor_size, Cogl.PixelFormat.BGRA_8888_PRE,
143+
surface.get_stride (), surface.get_data ());
159144

160-
context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, cursor_size, cursor_size);
161-
} catch (Error e) {}
145+
pipeline.set_layer_texture (0, texture);
162146

163-
base.paint (context);
164-
}
147+
context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, cursor_size, cursor_size);
148+
} catch (Error e) {}
165149

166-
public bool interpolate_value (string property_name, Clutter.Interval interval, double progress, out Value @value) {
167-
if (property_name == "angle") {
168-
@value = 0;
150+
base.paint (context);
151+
}
169152

170-
var elapsed_time = transition.get_elapsed_time ();
171-
if (elapsed_time > DELAY_TIMEOUT) {
172-
double delayed_progress = (elapsed_time - DELAY_TIMEOUT) / (transition.duration - DELAY_TIMEOUT);
173-
@value = (delayed_progress * 2 * Math.PI);
174-
}
153+
public bool interpolate_value (string property_name, Clutter.Interval interval, double progress, out Value @value) {
154+
if (property_name == "angle") {
155+
@value = 0;
175156

176-
return true;
157+
var elapsed_time = transition.get_elapsed_time ();
158+
if (elapsed_time > DELAY_TIMEOUT) {
159+
double delayed_progress = (elapsed_time - DELAY_TIMEOUT) / (transition.duration - DELAY_TIMEOUT);
160+
@value = (delayed_progress * 2 * Math.PI);
177161
}
178162

179-
return base.interpolate_value (property_name, interval, progress, out @value);
163+
return true;
180164
}
181165

166+
return base.interpolate_value (property_name, interval, progress, out @value);
182167
}
183168
}

0 commit comments

Comments
 (0)