diff --git a/meson.build b/meson.build index e9fd744c..0bff1410 100644 --- a/meson.build +++ b/meson.build @@ -142,7 +142,6 @@ subdir('daemon') subdir('plugins/maskcorners') subdir('plugins/pip') subdir('plugins/template') -subdir('plugins/touchegg') subdir('plugins/zoom') if get_option('documentation') subdir('docs') diff --git a/plugins/touchegg/Client.vala b/plugins/touchegg/Client.vala deleted file mode 100644 index 3e082f37..00000000 --- a/plugins/touchegg/Client.vala +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2020 elementary, Inc (https://elementary.io) - * 2020 José Expósito - * - * 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 . - */ - -/** -* This class connects to the Touchégg daemon to receive touch events. -* See: https://github.com/JoseExposito/touchegg -*/ -public class Gala.Plugins.Touchegg.Client : Object { - public signal void on_gesture_begin (Gesture gesture); - public signal void on_gesture_update (Gesture gesture); - public signal void on_gesture_end (Gesture gesture); - - /** - * Daemon D-Bus address. - */ - private const string DBUS_ADDRESS = "unix:abstract=touchegg"; - - /** - * D-Bus interface name. - */ - private const string DBUS_INTERFACE_NAME = "io.github.joseexposito.Touchegg"; - - /** - * D-Bus object path. - */ - private const string DBUS_OBJECT_PATH = "/io/github/joseexposito/Touchegg"; - - /** - * Signal names. - */ - private const string DBUS_ON_GESTURE_BEGIN = "OnGestureBegin"; - private const string DBUS_ON_GESTURE_UPDATE = "OnGestureUpdate"; - private const string DBUS_ON_GESTURE_END = "OnGestureEnd"; - - /** - * Maximum number of reconnection attempts to the daemon. - */ - private const int MAX_RECONNECTION_ATTEMPTS = 5; - - /** - * Time to sleep between reconnection attempts. - */ - private const int RECONNECTION_USLEEP_TIME = 5000000; - - /** - * Connection with the daemon. - */ - private GLib.DBusConnection? connection = null; - - /** - * Current number of reconnection attempts. - */ - private int reconnection_attempts = 0; - - /* - * Store the last received signal and signal parameters so in case of - * disconnection in the middle of a gesture we can finish it. - */ - private string? last_signal_received = null; - private Variant? last_params_received = null; - - /** - * Stablish a connection with the daemon server. - */ - public void stablish_connection () { - ThreadFunc run = () => { - var connected = false; - - while (!connected && reconnection_attempts < MAX_RECONNECTION_ATTEMPTS) { - try { - debug ("Connecting to Touchégg daemon"); - connection = new DBusConnection.for_address_sync ( - DBUS_ADDRESS, - GLib.DBusConnectionFlags.AUTHENTICATION_CLIENT - ); - - debug ("Connection with Touchégg established"); - connected = true; - reconnection_attempts = 0; - - connection.signal_subscribe (null, DBUS_INTERFACE_NAME, null, DBUS_OBJECT_PATH, - null, DBusSignalFlags.NONE, (DBusSignalCallback) on_new_message); - connection.on_closed.connect (on_disconnected); - } catch (Error e) { - warning ("Error connecting to Touchégg daemon: %s", e.message); - connected = false; - reconnection_attempts++; - - if (reconnection_attempts < MAX_RECONNECTION_ATTEMPTS) { - debug ("Reconnecting to Touchégg daemon in 5 seconds"); - Thread.usleep (RECONNECTION_USLEEP_TIME); - } else { - warning ("Maximum number of reconnections reached, aborting"); - } - } - } - }; - - new Thread (null, (owned) run); - } - - public void stop () { - try { - reconnection_attempts = MAX_RECONNECTION_ATTEMPTS; - - if (!connection.closed) { - connection.close_sync (); - } - } catch (Error e) { - // Ignore this error, the process is being killed as this point - } - } - - [CCode (instance_pos = -1)] - private void on_new_message (DBusConnection connection, string? sender_name, string object_path, - string interface_name, string signal_name, Variant parameters) { - last_signal_received = signal_name; - last_params_received = parameters; - - var gesture = make_gesture (parameters); - emit_event (signal_name, gesture); - } - - private void on_disconnected (bool remote_peer_vanished, Error? error) { - debug ("Connection with Touchégg daemon lost %s", error.message); - - if (last_signal_received == DBUS_ON_GESTURE_BEGIN || last_signal_received == DBUS_ON_GESTURE_UPDATE) { - debug ("Connection lost in the middle of a gesture, ending it"); - var gesture = make_gesture (last_params_received); - emit_event (DBUS_ON_GESTURE_END, gesture); - } - - stablish_connection (); - } - - private static Gesture make_gesture (Variant signal_params) { - GestureType type; - GestureDirection direction; - double percentage; - int fingers; - DeviceType performed_on_device_type; - uint64 elapsed_time; - - signal_params.get ("(uudiut)", out type, out direction, out percentage, out fingers, - out performed_on_device_type, out elapsed_time); - - Gesture gesture = new Gesture () { - type = type, - direction = direction, - percentage = percentage, - fingers = fingers, - performed_on_device_type = performed_on_device_type, - elapsed_time = elapsed_time - }; - - return gesture; - } - - private void emit_event (string signal_name, Gesture gesture) { - switch (signal_name) { - case DBUS_ON_GESTURE_BEGIN: - on_gesture_begin (gesture); - break; - case DBUS_ON_GESTURE_UPDATE: - on_gesture_update (gesture); - break; - case DBUS_ON_GESTURE_END: - on_gesture_end (gesture); - break; - default: - break; - } - } -} diff --git a/plugins/touchegg/Gesture.vala b/plugins/touchegg/Gesture.vala deleted file mode 100644 index aef1484b..00000000 --- a/plugins/touchegg/Gesture.vala +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020 elementary, Inc (https://elementary.io) - * 2020 José Expósito - * - * 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.Plugins.Touchegg { - public enum GestureType { - NOT_SUPPORTED = 0, - SWIPE = 1, - PINCH = 2, - } - - public enum GestureDirection { - UNKNOWN = 0, - - // GestureType.SWIPE - UP = 1, - DOWN = 2, - LEFT = 3, - RIGHT = 4, - - // GestureType.PINCH - IN = 5, - OUT = 6, - } - - public enum DeviceType { - UNKNOWN = 0, - TOUCHPAD = 1, - TOUCHSCREEN = 2, - } - - public class Gesture { - public GestureType type; - public GestureDirection direction; - public double percentage; - public int fingers; - public uint64 elapsed_time; - public DeviceType performed_on_device_type; - } -} diff --git a/plugins/touchegg/Main.vala b/plugins/touchegg/Main.vala deleted file mode 100644 index d2e1d294..00000000 --- a/plugins/touchegg/Main.vala +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2020 elementary, Inc (https://elementary.io) - * 2020 José Expósito - * - * 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 . - */ - -public class Gala.Plugins.Touchegg.Plugin : Gala.Plugin { - private Gala.WindowManager? wm = null; - private Client? client = null; - private GLib.Settings gala_settings; - private GLib.Settings touchpad_settings; - - public override void initialize (Gala.WindowManager window_manager) { - wm = window_manager; - gala_settings = new GLib.Settings ("io.elementary.desktop.wm.gestures"); - touchpad_settings = new GLib.Settings ("org.gnome.desktop.peripherals.touchpad"); - - client = new Client (); - client.on_gesture_begin.connect ((gesture) => Idle.add (() => { - on_handle_gesture (gesture, "begin"); - return false; - })); - client.on_gesture_update.connect ((gesture) => Idle.add (() => { - on_handle_gesture (gesture, "update"); - return false; - })); - client.on_gesture_end.connect ((gesture) => Idle.add (() => { - on_handle_gesture (gesture, "end"); - return false; - })); - client.stablish_connection (); - } - - public override void destroy () { - if (client != null) { - client.stop (); - } - } - - - private void on_handle_gesture (Gesture gesture, string event) { - // debug (@"Gesture $(event): $(gesture.type) - $(gesture.direction) - $(gesture.fingers) fingers - $(gesture.percentage)% - $(gesture.elapsed_time) - $(gesture.performed_on_device_type)"); - var hints = build_hints_from_gesture (gesture, event); - - if (is_open_workspace_gesture (gesture)) { - wm.workspace_view.open (hints); - } else if (is_close_workspace_gesture (gesture)) { - wm.workspace_view.close (hints); - } else if (is_next_desktop_gesture (gesture)) { - if (!wm.workspace_view.is_opened ()) { - wm.switch_to_next_workspace (Meta.MotionDirection.RIGHT, hints); - } - } else if (is_previous_desktop_gesture (gesture)) { - if (!wm.workspace_view.is_opened ()) { - wm.switch_to_next_workspace (Meta.MotionDirection.LEFT, hints); - } - } - } - - private GLib.HashTable build_hints_from_gesture (Gesture gesture, string event) { - var hints = new GLib.HashTable (str_hash, str_equal); - hints.insert ("manual_animation", new Variant.boolean (true)); - hints.insert ("event", new Variant.string (event)); - hints.insert ("percentage", new Variant.double (gesture.percentage)); - hints.insert ("elapsed_time", new Variant.uint64 (gesture.elapsed_time)); - return hints; - } - - private bool is_open_workspace_gesture (Gesture gesture) { - bool enabled = gala_settings.get_boolean ("multitasking-gesture-enabled"); - int fingers = gala_settings.get_int ("multitasking-gesture-fingers"); - - return enabled - && gesture.type == GestureType.SWIPE - && gesture.direction == GestureDirection.UP - && gesture.fingers == fingers; - } - - private bool is_close_workspace_gesture (Gesture gesture) { - bool enabled = gala_settings.get_boolean ("multitasking-gesture-enabled"); - int fingers = gala_settings.get_int ("multitasking-gesture-fingers"); - - return enabled - && gesture.type == GestureType.SWIPE - && gesture.direction == GestureDirection.DOWN - && gesture.fingers == fingers; - } - - private bool is_next_desktop_gesture (Gesture gesture) { - bool enabled = gala_settings.get_boolean ("workspaces-gesture-enabled"); - int fingers = gala_settings.get_int ("workspaces-gesture-fingers"); - bool natural_scroll = (gesture.performed_on_device_type == DeviceType.TOUCHSCREEN) - ? true - : touchpad_settings.get_boolean ("natural-scroll"); - var direction = natural_scroll ? GestureDirection.LEFT : GestureDirection.RIGHT; - - return enabled - && gesture.type == GestureType.SWIPE - && gesture.direction == direction - && gesture.fingers == fingers; - } - - private bool is_previous_desktop_gesture (Gesture gesture) { - bool enabled = gala_settings.get_boolean ("workspaces-gesture-enabled"); - int fingers = gala_settings.get_int ("workspaces-gesture-fingers"); - bool natural_scroll = (gesture.performed_on_device_type == DeviceType.TOUCHSCREEN) - ? true - : touchpad_settings.get_boolean ("natural-scroll"); - var direction = natural_scroll ? GestureDirection.RIGHT : GestureDirection.LEFT; - - return enabled - && gesture.type == GestureType.SWIPE - && gesture.direction == direction - && gesture.fingers == fingers; - } -} - - -public Gala.PluginInfo register_plugin () { - return Gala.PluginInfo () { - name = "Touchégg", - author = "José Expósito ", - plugin_type = typeof (Gala.Plugins.Touchegg.Plugin), - provides = Gala.PluginFunction.ADDITION, - load_priority = Gala.LoadPriority.DEFERRED - }; -} diff --git a/plugins/touchegg/meson.build b/plugins/touchegg/meson.build deleted file mode 100644 index 4967a296..00000000 --- a/plugins/touchegg/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -gala_touchegg_sources = [ - 'Main.vala', - 'Client.vala', - 'Gesture.vala', -] - -gala_touchegg_lib = shared_library( - 'gala-touchegg', - gala_touchegg_sources, - dependencies: [gala_dep, gala_base_dep], - include_directories: config_inc_dir, - install: true, - install_dir: plugins_dir, - install_rpath: mutter_typelib_dir, -) diff --git a/src/GestureAnimationDirector.vala b/src/GestureAnimationDirector.vala deleted file mode 100644 index 8c392b6b..00000000 --- a/src/GestureAnimationDirector.vala +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2020 elementary, Inc (https://elementary.io) - * 2020 José Expósito - * - * 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 . - */ - -public class Gala.GestureAnimationDirector : Object { - /** - * Percentage of the animation to be completed to apply the action. - */ - private const int SUCCESS_PERCENTAGE_THRESHOLD = 20; - - /** - * When a gesture ends with a velocity greater than this constant, the action is not cancelled, - * even if the animation threshold has not been reached. - */ - private const double SUCCESS_VELOCITY_THRESHOLD = 0.3; - - /** - * When a gesture ends with less velocity that this constant, this velocity is used instead. - */ - private const double ANIMATION_BASE_VELOCITY = 0.002; - - /** - * Maximum velocity allowed on gesture update. - */ - private const double MAX_VELOCITY = 0.5; - - public int min_animation_duration { get; construct; } - public int max_animation_duration { get; construct; } - - public bool running { get; set; default = false; } - public bool canceling { get; set; default = false; } - - public signal void on_animation_begin (double percentage); - public signal void on_animation_update (double percentage); - public signal void on_animation_end (double percentage, bool cancel_action, int calculated_duration); - - public delegate void OnBegin (double percentage); - public delegate void OnUpdate (double percentage); - public delegate void OnEnd (double percentage, bool cancel_action, int calculated_duration); - - private Gee.ArrayList handlers; - - private double previous_percentage; - private uint64 previous_time; - private double percentage_delta; - private double velocity; - - construct { - handlers = new Gee.ArrayList (); - previous_percentage = 0; - previous_time = 0; - percentage_delta = 0; - velocity = 0; - } - - public GestureAnimationDirector (int min_animation_duration, int max_animation_duration) { - Object (min_animation_duration: min_animation_duration, max_animation_duration: max_animation_duration); - } - - public void connect_handlers (owned OnBegin? on_begin, owned OnUpdate? on_update, owned OnEnd? on_end) { - if (on_begin != null) { - ulong handler_id = on_animation_begin.connect ((percentage) => on_begin (percentage)); - handlers.add (handler_id); - } - - if (on_update != null) { - ulong handler_id = on_animation_update.connect ((percentage) => on_update (percentage)); - handlers.add (handler_id); - } - - if (on_end != null) { - ulong handler_id = on_animation_end.connect ((percentage, cancel_action, duration) => on_end (percentage, cancel_action, duration)); - handlers.add (handler_id); - } - } - - public void disconnect_all_handlers () { - foreach (var handler in handlers) { - disconnect (handler); - } - - handlers.clear (); - } - - /** - * Utility method to calculate the current animation value based on the percentage of the - * gesture performed. - * Animations are always linear, as they are 1:1 to the user's movement. - * @param initial_value Animation start value. - * @param target_value Animation end value. - * @param percentage Current animation percentage. - * @param rounded If the returned value should be rounded to match physical pixels. - * Default to false because some animations, like for example scaling an actor, use intermediate - * values not divisible by physical pixels. - * @returns The linear animation value at the specified percentage. - */ - public static float animation_value (float initial_value, float target_value, double percentage, bool rounded = false) { - float value = (((target_value - initial_value) * (float) percentage) / 100) + initial_value; - - if (rounded) { - var scale_factor = InternalUtils.get_ui_scaling_factor (); - value = (float) Math.round (value * scale_factor) / scale_factor; - } - - return value; - } - - public void update_animation (HashTable hints) { - string event = hints.get ("event").get_string (); - double percentage = hints.get ("percentage").get_double (); - uint64 elapsed_time = hints.get ("elapsed_time").get_uint64 (); - - switch (event) { - case "begin": - update_animation_begin (percentage, elapsed_time); - break; - case "update": - update_animation_update (percentage, elapsed_time); - break; - case "end": - default: - update_animation_end (percentage, elapsed_time); - break; - } - } - - private void update_animation_begin (double percentage, uint64 elapsed_time) { - on_animation_begin (percentage); - - previous_percentage = percentage; - previous_time = elapsed_time; - } - - private void update_animation_update (double percentage, uint64 elapsed_time) { - if (elapsed_time != previous_time) { - double distance = percentage - previous_percentage; - double time = (double)(elapsed_time - previous_time); - velocity = (distance / time); - - if (velocity > MAX_VELOCITY) { - velocity = MAX_VELOCITY; - var used_percentage = MAX_VELOCITY * time + previous_percentage; - percentage_delta += percentage - used_percentage; - } - } - - on_animation_update (applied_percentage (percentage, percentage_delta)); - - previous_percentage = percentage; - previous_time = elapsed_time; - } - - private void update_animation_end (double percentage, uint64 elapsed_time) { - double end_percentage = applied_percentage (percentage, percentage_delta); - bool cancel_action = (end_percentage < SUCCESS_PERCENTAGE_THRESHOLD) - && ((end_percentage <= previous_percentage) && (velocity < SUCCESS_VELOCITY_THRESHOLD)); - int calculated_duration = calculate_end_animation_duration (end_percentage, cancel_action); - - on_animation_end (end_percentage, cancel_action, calculated_duration); - - previous_percentage = 0; - previous_time = 0; - percentage_delta = 0; - velocity = 0; - } - - private static double applied_percentage (double percentage, double percentage_delta) { - return (percentage - percentage_delta).clamp (0, 100); - } - - /** - * Calculates the end animation duration using the current gesture velocity. - */ - private int calculate_end_animation_duration (double end_percentage, bool cancel_action) { - double animation_velocity = (velocity > ANIMATION_BASE_VELOCITY) - ? velocity - : ANIMATION_BASE_VELOCITY; - - double pending_percentage = cancel_action ? end_percentage : 100 - end_percentage; - - int duration = ((int)(pending_percentage / animation_velocity).abs ()) - .clamp (min_animation_duration, max_animation_duration); - return duration; - } -} diff --git a/src/meson.build b/src/meson.build index 63fbed80..55f64c3e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -2,7 +2,6 @@ gala_bin_sources = files( 'DBus.vala', 'DBusAccelerator.vala', 'DockThemeManager.vala', - 'GestureAnimationDirector.vala', 'InternalUtils.vala', 'KeyboardManager.vala', 'NotificationStack.vala',