From 42443b23394324666867b03172049a946a12e58d Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 25 Jan 2025 17:49:17 +0300 Subject: [PATCH 1/3] PointerLocator: inline namespace (#2244) --- src/Widgets/PointerLocator.vala | 260 +++++++++++++++----------------- 1 file changed, 123 insertions(+), 137 deletions(-) diff --git a/src/Widgets/PointerLocator.vala b/src/Widgets/PointerLocator.vala index 43469bc25..79d6650c7 100644 --- a/src/Widgets/PointerLocator.vala +++ b/src/Widgets/PointerLocator.vala @@ -1,165 +1,151 @@ -// -// Copyright 2020 elementary, Inc. (https://elementary.io) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -namespace Gala { - public class PointerLocator : Clutter.Actor, Clutter.Animatable { - private const int WIDTH_PX = 300; - private const int HEIGHT_PX = 300; - private const int ANIMATION_TIME_MS = 300; - - private const int BORDER_WIDTH_PX = 1; - - private const double BACKGROUND_OPACITY = 0.7; - - public Meta.Display display { get; construct; } - - private float scaling_factor = 1.0f; - private int surface_width = WIDTH_PX; - private int surface_height = HEIGHT_PX; - - private GLib.Settings settings; - private Cogl.Pipeline pipeline; - private Cairo.ImageSurface surface; - private Cairo.Pattern stroke_color; - private Cairo.Pattern fill_color; - - public PointerLocator (Meta.Display display) { - Object (display: display); - } +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2020-2025 elementary, Inc. (https://elementary.io) + */ + +public class Gala.PointerLocator : Clutter.Actor, Clutter.Animatable { + private const int WIDTH_PX = 300; + private const int HEIGHT_PX = 300; + private const int ANIMATION_TIME_MS = 300; + + private const int BORDER_WIDTH_PX = 1; + + private const double BACKGROUND_OPACITY = 0.7; - construct { - visible = false; - reactive = false; + public Meta.Display display { get; construct; } + + private float scaling_factor = 1.0f; + private int surface_width = WIDTH_PX; + private int surface_height = HEIGHT_PX; + + private GLib.Settings settings; + private Cogl.Pipeline pipeline; + private Cairo.ImageSurface surface; + private Cairo.Pattern stroke_color; + private Cairo.Pattern fill_color; + + public PointerLocator (Meta.Display display) { + Object (display: display); + } - settings = new GLib.Settings ("org.gnome.desktop.interface"); + construct { + visible = false; + reactive = false; + + settings = new GLib.Settings ("org.gnome.desktop.interface"); #if HAS_MUTTER47 - unowned var ctx = context.get_backend ().get_cogl_context (); + unowned var ctx = context.get_backend ().get_cogl_context (); #else - unowned var ctx = Clutter.get_default_backend ().get_cogl_context (); + unowned var ctx = Clutter.get_default_backend ().get_cogl_context (); #endif - pipeline = new Cogl.Pipeline (ctx); + pipeline = new Cogl.Pipeline (ctx); - var pivot = Graphene.Point (); - pivot.init (0.5f, 0.5f); - pivot_point = pivot; - } + var pivot = Graphene.Point (); + pivot.init (0.5f, 0.5f); + pivot_point = pivot; + } - private void update_surface (float cur_scale) { - if (surface == null || cur_scale != scaling_factor) { - scaling_factor = cur_scale; - surface_width = InternalUtils.scale_to_int (WIDTH_PX, scaling_factor); - surface_height = InternalUtils.scale_to_int (HEIGHT_PX, scaling_factor); + private void update_surface (float cur_scale) { + if (surface == null || cur_scale != scaling_factor) { + scaling_factor = cur_scale; + surface_width = InternalUtils.scale_to_int (WIDTH_PX, scaling_factor); + surface_height = InternalUtils.scale_to_int (HEIGHT_PX, scaling_factor); - surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, surface_width, surface_height); + surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, surface_width, surface_height); - set_size (surface_width, surface_height); - } + set_size (surface_width, surface_height); } + } - public override void paint (Clutter.PaintContext context) { - var radius = int.min (surface_width / 2, surface_height / 2); + public override void paint (Clutter.PaintContext context) { + var radius = int.min (surface_width / 2, surface_height / 2); - var cr = new Cairo.Context (surface); - var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor); + var cr = new Cairo.Context (surface); + var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor); - // Clear the surface - cr.save (); - cr.set_source_rgba (0, 0, 0, 0); - cr.set_operator (Cairo.Operator.SOURCE); - cr.paint (); - cr.restore (); + // Clear the surface + cr.save (); + cr.set_source_rgba (0, 0, 0, 0); + cr.set_operator (Cairo.Operator.SOURCE); + cr.paint (); + cr.restore (); - cr.set_line_cap (Cairo.LineCap.ROUND); - cr.set_line_join (Cairo.LineJoin.ROUND); - cr.translate (surface_width / 2, surface_height / 2); + cr.set_line_cap (Cairo.LineCap.ROUND); + cr.set_line_join (Cairo.LineJoin.ROUND); + cr.translate (surface_width / 2, surface_height / 2); - cr.move_to (radius - BORDER_WIDTH_PX, 0); - cr.arc (0, 0, radius - border_width, 0, 2 * Math.PI); - cr.close_path (); + cr.move_to (radius - BORDER_WIDTH_PX, 0); + cr.arc (0, 0, radius - border_width, 0, 2 * Math.PI); + cr.close_path (); - cr.set_line_width (0); - cr.set_source (fill_color); - cr.fill_preserve (); + cr.set_line_width (0); + cr.set_source (fill_color); + cr.fill_preserve (); - cr.set_line_width (border_width); - cr.set_source (stroke_color); - cr.stroke (); + cr.set_line_width (border_width); + cr.set_source (stroke_color); + cr.stroke (); - var cogl_context = context.get_framebuffer ().get_context (); + var cogl_context = context.get_framebuffer ().get_context (); - try { - var texture = new Cogl.Texture2D.from_data (cogl_context, surface_width, surface_height, - Cogl.PixelFormat.BGRA_8888_PRE, surface.get_stride (), surface.get_data ()); + try { + var texture = new Cogl.Texture2D.from_data (cogl_context, surface_width, surface_height, + Cogl.PixelFormat.BGRA_8888_PRE, surface.get_stride (), surface.get_data ()); - pipeline.set_layer_texture (0, texture); + pipeline.set_layer_texture (0, texture); - context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, surface_width, surface_height); - } catch (Error e) {} + context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, surface_width, surface_height); + } catch (Error e) {} - base.paint (context); + base.paint (context); + } + + public void show_ripple () { + if (!settings.get_boolean ("locate-pointer")) { + return; } - public void show_ripple () { - if (!settings.get_boolean ("locate-pointer")) { - return; - } - - unowned var old_transition = get_transition ("circle"); - if (old_transition != null) { - old_transition.stop (); - } - - var transition = new Clutter.TransitionGroup (); - transition.remove_on_complete = true; - var transition_x = new Clutter.PropertyTransition ("scale-x"); - var transition_y = new Clutter.PropertyTransition ("scale-y"); - var start_val = Value (typeof (double)); - start_val.set_double (1); - var stop_val = Value (typeof (double)); - stop_val.set_double (0); - transition_x.set_from_value (start_val); - transition_y.set_from_value (start_val); - transition_x.set_to_value (stop_val); - transition_y.set_to_value (stop_val); - transition.progress_mode = Clutter.AnimationMode.EASE_OUT_QUAD; - transition.duration = ANIMATION_TIME_MS; - transition.add_transition (transition_x); - transition.add_transition (transition_y); - transition.stopped.connect (() => { visible = false; }); - transition.started.connect (() => { visible = true; }); - add_transition ("circle", transition); - - var rgba = Drawing.StyleManager.get_instance ().theme_accent_color; - - /* Don't use alpha from the stylesheet to ensure contrast */ - stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue); - fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY); - - unowned var tracker = display.get_cursor_tracker (); - Graphene.Point coords = {}; - tracker.get_pointer (out coords, null); - - update_surface (display.get_monitor_scale (display.get_current_monitor ())); - - x = coords.x - (width / 2); - y = coords.y - (width / 2); - - transition.start (); + unowned var old_transition = get_transition ("circle"); + if (old_transition != null) { + old_transition.stop (); } + + var transition = new Clutter.TransitionGroup (); + transition.remove_on_complete = true; + var transition_x = new Clutter.PropertyTransition ("scale-x"); + var transition_y = new Clutter.PropertyTransition ("scale-y"); + var start_val = Value (typeof (double)); + start_val.set_double (1); + var stop_val = Value (typeof (double)); + stop_val.set_double (0); + transition_x.set_from_value (start_val); + transition_y.set_from_value (start_val); + transition_x.set_to_value (stop_val); + transition_y.set_to_value (stop_val); + transition.progress_mode = Clutter.AnimationMode.EASE_OUT_QUAD; + transition.duration = ANIMATION_TIME_MS; + transition.add_transition (transition_x); + transition.add_transition (transition_y); + transition.stopped.connect (() => { visible = false; }); + transition.started.connect (() => { visible = true; }); + add_transition ("circle", transition); + + var rgba = Drawing.StyleManager.get_instance ().theme_accent_color; + + /* Don't use alpha from the stylesheet to ensure contrast */ + stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue); + fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY); + + unowned var tracker = display.get_cursor_tracker (); + Graphene.Point coords = {}; + tracker.get_pointer (out coords, null); + + update_surface (display.get_monitor_scale (display.get_current_monitor ())); + + x = coords.x - (width / 2); + y = coords.y - (width / 2); + + transition.start (); } } From 86f194097ac4ca653111f258817c5726a66ed970 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 25 Jan 2025 17:50:30 +0300 Subject: [PATCH 2/3] WindowIconActor: inline namespace (#2245) Co-authored-by: Leonhard --- src/Widgets/WindowIconActor.vala | 285 +++++++++++++++---------------- 1 file changed, 136 insertions(+), 149 deletions(-) diff --git a/src/Widgets/WindowIconActor.vala b/src/Widgets/WindowIconActor.vala index 4abd60da0..0e73eca6e 100644 --- a/src/Widgets/WindowIconActor.vala +++ b/src/Widgets/WindowIconActor.vala @@ -1,177 +1,164 @@ -// -// Copyright (C) 2014 Tom Beckmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -namespace Gala { +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2014 Tom Beckmann + * 2025 elementary, Inc. (https://elementary.io) + */ + +/** + * Private class which is basically just a container for the actual + * icon and takes care of blending the same icon in different sizes + * over each other and various animations related to the icons + */ +public class Gala.WindowIconActor : Clutter.Actor { + public Meta.Window window { get; construct; } + + private float cur_icon_scale = 1.0f; + private float desired_icon_scale = 1.0f; + + private int _icon_size; /** - * Private class which is basically just a container for the actual - * icon and takes care of blending the same icon in different sizes - * over each other and various animations related to the icons + * The icon size of the WindowIcon. Once set the new icon will be + * faded over the old one and the actor animates to the new size. */ - public class WindowIconActor : Clutter.Actor { - public Meta.Window window { get; construct; } - - private float cur_icon_scale = 1.0f; - private float desired_icon_scale = 1.0f; - - private int _icon_size; - /** - * The icon size of the WindowIcon. Once set the new icon will be - * faded over the old one and the actor animates to the new size. - */ - public int icon_size { - get { - return _icon_size; + public int icon_size { + get { + return _icon_size; + } + private set { + if (value == _icon_size && cur_icon_scale == desired_icon_scale) { + return; } - private set { - if (value == _icon_size && cur_icon_scale == desired_icon_scale) { - return; - } - _icon_size = value; - cur_icon_scale = desired_icon_scale; + _icon_size = value; + cur_icon_scale = desired_icon_scale; - var scaled_size = InternalUtils.scale_to_int (_icon_size, cur_icon_scale); - set_size (scaled_size, scaled_size); + var scaled_size = InternalUtils.scale_to_int (_icon_size, cur_icon_scale); + set_size (scaled_size, scaled_size); - fade_new_icon (); - } + fade_new_icon (); } + } - private bool _temporary; - /** - * Mark the WindowIcon as temporary. Only effect of this is that a pulse - * animation will be played on the actor. Used while DnDing window thumbs - * over the group. - */ - public bool temporary { - get { - return _temporary; - } - set { - if (_temporary && !value) { - remove_transition ("pulse"); - } else if (!_temporary && value && AnimationsSettings.get_enable_animations ()) { - var transition = new Clutter.TransitionGroup () { - duration = 800, - auto_reverse = true, - repeat_count = -1, - progress_mode = Clutter.AnimationMode.LINEAR - }; - - var opacity_transition = new Clutter.PropertyTransition ("opacity"); - opacity_transition.set_from_value (100); - opacity_transition.set_to_value (255); - opacity_transition.auto_reverse = true; - - var scale_x_transition = new Clutter.PropertyTransition ("scale-x"); - scale_x_transition.set_from_value (0.8); - scale_x_transition.set_to_value (1.1); - scale_x_transition.auto_reverse = true; - - var scale_y_transition = new Clutter.PropertyTransition ("scale-y"); - scale_y_transition.set_from_value (0.8); - scale_y_transition.set_to_value (1.1); - scale_y_transition.auto_reverse = true; - - transition.add_transition (opacity_transition); - transition.add_transition (scale_x_transition); - transition.add_transition (scale_y_transition); - - add_transition ("pulse", transition); - } - - _temporary = value; + private bool _temporary; + /** + * Mark the WindowIcon as temporary. Only effect of this is that a pulse + * animation will be played on the actor. Used while DnDing window thumbs + * over the group. + */ + public bool temporary { + get { + return _temporary; + } + set { + if (_temporary && !value) { + remove_transition ("pulse"); + } else if (!_temporary && value && AnimationsSettings.get_enable_animations ()) { + var transition = new Clutter.TransitionGroup () { + duration = 800, + auto_reverse = true, + repeat_count = -1, + progress_mode = Clutter.AnimationMode.LINEAR + }; + + var opacity_transition = new Clutter.PropertyTransition ("opacity"); + opacity_transition.set_from_value (100); + opacity_transition.set_to_value (255); + opacity_transition.auto_reverse = true; + + var scale_x_transition = new Clutter.PropertyTransition ("scale-x"); + scale_x_transition.set_from_value (0.8); + scale_x_transition.set_to_value (1.1); + scale_x_transition.auto_reverse = true; + + var scale_y_transition = new Clutter.PropertyTransition ("scale-y"); + scale_y_transition.set_from_value (0.8); + scale_y_transition.set_to_value (1.1); + scale_y_transition.auto_reverse = true; + + transition.add_transition (opacity_transition); + transition.add_transition (scale_x_transition); + transition.add_transition (scale_y_transition); + + add_transition ("pulse", transition); } + + _temporary = value; } + } - private WindowIcon? icon = null; - private WindowIcon? old_icon = null; + private WindowIcon? icon = null; + private WindowIcon? old_icon = null; - public WindowIconActor (Meta.Window window) { - Object (window: window); - } + public WindowIconActor (Meta.Window window) { + Object (window: window); + } - construct { - set_pivot_point (0.5f, 0.5f); + construct { + set_pivot_point (0.5f, 0.5f); - window.notify["on-all-workspaces"].connect (on_all_workspaces_changed); - } + window.notify["on-all-workspaces"].connect (on_all_workspaces_changed); + } - ~WindowIconActor () { - window.notify["on-all-workspaces"].disconnect (on_all_workspaces_changed); - } + ~WindowIconActor () { + window.notify["on-all-workspaces"].disconnect (on_all_workspaces_changed); + } - private void on_all_workspaces_changed () { - // we don't display windows that are on all workspaces - if (window.on_all_workspaces) - destroy (); - } + private void on_all_workspaces_changed () { + // we don't display windows that are on all workspaces + if (window.on_all_workspaces) + destroy (); + } - /** - * Shortcut to set both position and size of the icon - * - * @param x The x coordinate to which to animate to - * @param y The y coordinate to which to animate to - * @param size The size to which to animate to and display the icon in - */ - public void place (float x, float y, int size, float scale) { - desired_icon_scale = scale; - set_position (x, y); - icon_size = size; - } + /** + * Shortcut to set both position and size of the icon + * + * @param x The x coordinate to which to animate to + * @param y The y coordinate to which to animate to + * @param size The size to which to animate to and display the icon in + */ + public void place (float x, float y, int size, float scale) { + desired_icon_scale = scale; + set_position (x, y); + icon_size = size; + } - /** - * Fades out the old icon and fades in the new icon - */ - private void fade_new_icon () { - var new_icon = new WindowIcon (window, icon_size, (int)Math.round (cur_icon_scale)); - new_icon.add_constraint (new Clutter.BindConstraint (this, Clutter.BindCoordinate.SIZE, 0)); - new_icon.opacity = 0; + /** + * Fades out the old icon and fades in the new icon + */ + private void fade_new_icon () { + var new_icon = new WindowIcon (window, icon_size, (int)Math.round (cur_icon_scale)); + new_icon.add_constraint (new Clutter.BindConstraint (this, Clutter.BindCoordinate.SIZE, 0)); + new_icon.opacity = 0; - add_child (new_icon); + add_child (new_icon); - new_icon.save_easing_state (); - new_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); - new_icon.set_easing_duration (AnimationsSettings.get_animation_duration (500)); - new_icon.restore_easing_state (); + new_icon.save_easing_state (); + new_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); + new_icon.set_easing_duration (AnimationsSettings.get_animation_duration (500)); + new_icon.restore_easing_state (); - if (icon == null) { - icon = new_icon; - } else { - old_icon = icon; - } + if (icon == null) { + icon = new_icon; + } else { + old_icon = icon; + } + + new_icon.opacity = 255; - new_icon.opacity = 255; - - if (old_icon != null) { - old_icon.opacity = 0; - var transition = old_icon.get_transition ("opacity"); - if (transition != null) { - transition.completed.connect (() => { - old_icon.destroy (); - old_icon = null; - }); - } else { + if (old_icon != null) { + old_icon.opacity = 0; + var transition = old_icon.get_transition ("opacity"); + if (transition != null) { + transition.completed.connect (() => { old_icon.destroy (); old_icon = null; - } + }); + } else { + old_icon.destroy (); + old_icon = null; } - - icon = new_icon; } + + icon = new_icon; } } From 4ed139b4361ac80c128cf5c5efdb2ce12f8849a6 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 25 Jan 2025 17:51:41 +0300 Subject: [PATCH 3/3] DwellClickTimer: inline namespace (#2246) --- src/Widgets/DwellClickTimer.vala | 265 +++++++++++++++---------------- 1 file changed, 125 insertions(+), 140 deletions(-) diff --git a/src/Widgets/DwellClickTimer.vala b/src/Widgets/DwellClickTimer.vala index 84d3b11f6..a2e9ac4a0 100644 --- a/src/Widgets/DwellClickTimer.vala +++ b/src/Widgets/DwellClickTimer.vala @@ -1,183 +1,168 @@ -// -// Copyright 2020 elementary, Inc. (https://elementary.io) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -namespace Gala { - public class DwellClickTimer : Clutter.Actor, Clutter.Animatable { - private const double BACKGROUND_OPACITY = 0.7; - private const int BORDER_WIDTH_PX = 1; - - private const double START_ANGLE = 3 * Math.PI / 2; - - /** - * Delay, in milliseconds, before showing the animation. - * libinput uses a timeout of 180ms when tapping is enabled. Use that value plus a safety - * margin so the animation is never displayed when tapping. - */ - private const double DELAY_TIMEOUT = 185; - - private float scaling_factor = 1.0f; - private int cursor_size = 24; - - private Cogl.Pipeline pipeline; - private Clutter.PropertyTransition transition; - private Cairo.Pattern stroke_color; - private Cairo.Pattern fill_color; - private GLib.Settings interface_settings; - private Cairo.ImageSurface surface; - - public Meta.Display display { get; construct; } - - public double angle { get; set; } - - public DwellClickTimer (Meta.Display display) { - Object (display: display); - } +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2020, 2025 elementary, Inc. (https://elementary.io) + */ - construct { - visible = false; - reactive = false; +public class Gala.DwellClickTimer : Clutter.Actor, Clutter.Animatable { + private const double BACKGROUND_OPACITY = 0.7; + private const int BORDER_WIDTH_PX = 1; + + private const double START_ANGLE = 3 * Math.PI / 2; + + /** + * Delay, in milliseconds, before showing the animation. + * libinput uses a timeout of 180ms when tapping is enabled. Use that value plus a safety + * margin so the animation is never displayed when tapping. + */ + private const double DELAY_TIMEOUT = 185; + + private float scaling_factor = 1.0f; + private int cursor_size = 24; + + private Cogl.Pipeline pipeline; + private Clutter.PropertyTransition transition; + private Cairo.Pattern stroke_color; + private Cairo.Pattern fill_color; + private GLib.Settings interface_settings; + private Cairo.ImageSurface surface; + + public Meta.Display display { get; construct; } + + public double angle { get; set; } + + public DwellClickTimer (Meta.Display display) { + Object (display: display); + } + + construct { + visible = false; + reactive = false; #if HAS_MUTTER47 - unowned var backend = context.get_backend (); + unowned var backend = context.get_backend (); #else - unowned var backend = Clutter.get_default_backend (); + unowned var backend = Clutter.get_default_backend (); #endif - pipeline = new Cogl.Pipeline (backend.get_cogl_context ()); + pipeline = new Cogl.Pipeline (backend.get_cogl_context ()); - transition = new Clutter.PropertyTransition ("angle"); - transition.set_progress_mode (Clutter.AnimationMode.EASE_OUT_QUAD); - transition.set_animatable (this); - transition.set_from_value (START_ANGLE); - transition.set_to_value (START_ANGLE + (2 * Math.PI)); + transition = new Clutter.PropertyTransition ("angle"); + transition.set_progress_mode (Clutter.AnimationMode.EASE_OUT_QUAD); + transition.set_animatable (this); + transition.set_from_value (START_ANGLE); + transition.set_to_value (START_ANGLE + (2 * Math.PI)); - transition.new_frame.connect (() => { - queue_redraw (); - }); + transition.new_frame.connect (() => { + queue_redraw (); + }); - interface_settings = new GLib.Settings ("org.gnome.desktop.interface"); + interface_settings = new GLib.Settings ("org.gnome.desktop.interface"); - var seat = backend.get_default_seat (); - seat.set_pointer_a11y_dwell_click_type (Clutter.PointerA11yDwellClickType.PRIMARY); + var seat = backend.get_default_seat (); + seat.set_pointer_a11y_dwell_click_type (Clutter.PointerA11yDwellClickType.PRIMARY); - seat.ptr_a11y_timeout_started.connect ((device, type, timeout) => { - var scale = display.get_monitor_scale (display.get_current_monitor ()); - update_cursor_size (scale); + seat.ptr_a11y_timeout_started.connect ((device, type, timeout) => { + var scale = display.get_monitor_scale (display.get_current_monitor ()); + update_cursor_size (scale); - unowned var tracker = display.get_cursor_tracker (); - Graphene.Point coords = {}; - tracker.get_pointer (out coords, null); + unowned var tracker = display.get_cursor_tracker (); + Graphene.Point coords = {}; + tracker.get_pointer (out coords, null); - x = coords.x - (width / 2); - y = coords.y - (width / 2); + x = coords.x - (width / 2); + y = coords.y - (width / 2); - transition.set_duration (timeout); - visible = true; - transition.start (); - }); + transition.set_duration (timeout); + visible = true; + transition.start (); + }); - seat.ptr_a11y_timeout_stopped.connect ((device, type, clicked) => { - transition.stop (); - visible = false; - }); - } - - private void update_cursor_size (float scale) { - scaling_factor = scale; + seat.ptr_a11y_timeout_stopped.connect ((device, type, clicked) => { + transition.stop (); + visible = false; + }); + } - cursor_size = (int) (interface_settings.get_int ("cursor-size") * scaling_factor * 1.25); + private void update_cursor_size (float scale) { + scaling_factor = scale; - if (surface == null || surface.get_width () != cursor_size || surface.get_height () != cursor_size) { - surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, cursor_size, cursor_size); - } + cursor_size = (int) (interface_settings.get_int ("cursor-size") * scaling_factor * 1.25); - set_size (cursor_size, cursor_size); + if (surface == null || surface.get_width () != cursor_size || surface.get_height () != cursor_size) { + surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, cursor_size, cursor_size); } - public override void paint (Clutter.PaintContext context) { - if (angle == 0) { - return; - } + set_size (cursor_size, cursor_size); + } - var rgba = Drawing.StyleManager.get_instance ().theme_accent_color; + public override void paint (Clutter.PaintContext context) { + if (angle == 0) { + return; + } - /* Don't use alpha from the stylesheet to ensure contrast */ - stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue); - fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY); + var rgba = Drawing.StyleManager.get_instance ().theme_accent_color; - var radius = int.min (cursor_size / 2, cursor_size / 2); - var end_angle = START_ANGLE + angle; - var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor); + /* Don't use alpha from the stylesheet to ensure contrast */ + stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue); + fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY); - var cr = new Cairo.Context (surface); + var radius = int.min (cursor_size / 2, cursor_size / 2); + var end_angle = START_ANGLE + angle; + var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor); - // Clear the surface - cr.save (); - cr.set_source_rgba (0, 0, 0, 0); - cr.set_operator (Cairo.Operator.SOURCE); - cr.paint (); - cr.restore (); + var cr = new Cairo.Context (surface); - cr.set_line_cap (Cairo.LineCap.ROUND); - cr.set_line_join (Cairo.LineJoin.ROUND); - cr.translate (cursor_size / 2, cursor_size / 2); + // Clear the surface + cr.save (); + cr.set_source_rgba (0, 0, 0, 0); + cr.set_operator (Cairo.Operator.SOURCE); + cr.paint (); + cr.restore (); - cr.move_to (0, 0); - cr.arc (0, 0, radius - border_width, START_ANGLE, end_angle); - cr.line_to (0, 0); - cr.close_path (); + cr.set_line_cap (Cairo.LineCap.ROUND); + cr.set_line_join (Cairo.LineJoin.ROUND); + cr.translate (cursor_size / 2, cursor_size / 2); - cr.set_line_width (0); - cr.set_source (fill_color); - cr.fill_preserve (); + cr.move_to (0, 0); + cr.arc (0, 0, radius - border_width, START_ANGLE, end_angle); + cr.line_to (0, 0); + cr.close_path (); - cr.set_line_width (border_width); - cr.set_source (stroke_color); - cr.stroke (); + cr.set_line_width (0); + cr.set_source (fill_color); + cr.fill_preserve (); - var cogl_context = context.get_framebuffer ().get_context (); + cr.set_line_width (border_width); + cr.set_source (stroke_color); + cr.stroke (); - try { - var texture = new Cogl.Texture2D.from_data (cogl_context, cursor_size, cursor_size, Cogl.PixelFormat.BGRA_8888_PRE, - surface.get_stride (), surface.get_data ()); + var cogl_context = context.get_framebuffer ().get_context (); - pipeline.set_layer_texture (0, texture); + try { + var texture = new Cogl.Texture2D.from_data (cogl_context, cursor_size, cursor_size, Cogl.PixelFormat.BGRA_8888_PRE, + surface.get_stride (), surface.get_data ()); - context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, cursor_size, cursor_size); - } catch (Error e) {} + pipeline.set_layer_texture (0, texture); - base.paint (context); - } + context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, cursor_size, cursor_size); + } catch (Error e) {} - public bool interpolate_value (string property_name, Clutter.Interval interval, double progress, out Value @value) { - if (property_name == "angle") { - @value = 0; + base.paint (context); + } - var elapsed_time = transition.get_elapsed_time (); - if (elapsed_time > DELAY_TIMEOUT) { - double delayed_progress = (elapsed_time - DELAY_TIMEOUT) / (transition.duration - DELAY_TIMEOUT); - @value = (delayed_progress * 2 * Math.PI); - } + public bool interpolate_value (string property_name, Clutter.Interval interval, double progress, out Value @value) { + if (property_name == "angle") { + @value = 0; - return true; + var elapsed_time = transition.get_elapsed_time (); + if (elapsed_time > DELAY_TIMEOUT) { + double delayed_progress = (elapsed_time - DELAY_TIMEOUT) / (transition.duration - DELAY_TIMEOUT); + @value = (delayed_progress * 2 * Math.PI); } - return base.interpolate_value (property_name, interval, progress, out @value); + return true; } + return base.interpolate_value (property_name, interval, progress, out @value); } }