hot corners: Refactor hot corners

Move the hot corners code from the WindowManager to its own class.

Refator, no functional changes.
This commit is contained in:
José Expósito 2021-08-31 07:28:38 +02:00 committed by Corentin Noël
parent 67302862d9
commit a5f32b3331
3 changed files with 117 additions and 81 deletions

View File

@ -0,0 +1,111 @@
/*
* Copyright 2021 elementary, Inc (https://elementary.io)
* 2021 José Expósito <jose.exposito89@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
public class Gala.HotCornerManager : Object {
public signal void on_configured ();
public WindowManager wm { get; construct; }
public GLib.Settings behavior_settings { get; construct; }
public HotCornerManager (WindowManager wm, GLib.Settings behavior_settings) {
Object (wm: wm, behavior_settings: behavior_settings);
behavior_settings.changed.connect (configure);
Meta.MonitorManager.@get ().monitors_changed.connect (configure);
}
public void configure () {
unowned Meta.Display display = wm.get_display ();
var geometry = display.get_monitor_geometry (display.get_primary_monitor ());
add_hotcorner (geometry.x, geometry.y, "hotcorner-topleft");
add_hotcorner (geometry.x + geometry.width - 1, geometry.y, "hotcorner-topright");
add_hotcorner (geometry.x, geometry.y + geometry.height - 1, "hotcorner-bottomleft");
add_hotcorner (geometry.x + geometry.width - 1, geometry.y + geometry.height - 1, "hotcorner-bottomright");
this.on_configured ();
}
private void add_hotcorner (float x, float y, string key) {
unowned Clutter.Actor? stage = wm.get_display ().get_stage ();
return_if_fail (stage != null);
var action = (ActionType) behavior_settings.get_enum (key);
Clutter.Actor? hot_corner = stage.find_child_by_name (key);
if (action == ActionType.NONE) {
if (hot_corner != null)
stage.remove_child (hot_corner);
return;
}
// if the hot corner already exists, just reposition it, create it otherwise
if (hot_corner == null) {
hot_corner = new Clutter.Actor ();
hot_corner.width = 1;
hot_corner.height = 1;
hot_corner.opacity = 0;
hot_corner.reactive = true;
hot_corner.name = key;
stage.add_child (hot_corner);
hot_corner.enter_event.connect ((actor, event) => {
var hot_corner_name = actor.name;
var action_type = (ActionType) behavior_settings.get_enum (hot_corner_name);
if (action_type == ActionType.CUSTOM_COMMAND) {
run_custom_action (hot_corner_name);
} else {
wm.perform_action (action_type);
}
return false;
});
}
hot_corner.x = x;
hot_corner.y = y;
}
private void run_custom_action (string hot_corner_position) {
string command = "";
var line = behavior_settings.get_string ("hotcorner-custom-command");
if (line == "")
return;
var parts = line.split (";;");
// keep compatibility to old version where only one command was possible
if (parts.length == 1) {
command = line;
} else {
// find specific actions
foreach (var part in parts) {
var details = part.split (":");
if (details[0] == hot_corner_position) {
command = details[1];
}
}
}
try {
Process.spawn_command_line_async (command);
} catch (Error e) {
warning (e.message);
}
}
}

View File

@ -72,10 +72,10 @@ namespace Gala {
WindowSwitcher? winswitcher = null; WindowSwitcher? winswitcher = null;
ActivatableComponent? window_overview = null; ActivatableComponent? window_overview = null;
// used to detect which corner was used to trigger an action
Clutter.Actor? last_hotcorner;
public ScreenSaverManager? screensaver { get; private set; } public ScreenSaverManager? screensaver { get; private set; }
HotCornerManager? hot_corner_manager = null;
/** /**
* Allow to zoom in/out the entire desktop. * Allow to zoom in/out the entire desktop.
*/ */
@ -284,11 +284,11 @@ namespace Gala {
var shadow_settings = new GLib.Settings (Config.SCHEMA + ".shadows"); var shadow_settings = new GLib.Settings (Config.SCHEMA + ".shadows");
shadow_settings.changed.connect (InternalUtils.reload_shadow); shadow_settings.changed.connect (InternalUtils.reload_shadow);
/*hot corner, getting enum values from GraniteServicesSettings did not work, so we use GSettings directly*/
configure_hotcorners ();
Meta.MonitorManager.@get ().monitors_changed.connect (on_monitors_changed); Meta.MonitorManager.@get ().monitors_changed.connect (on_monitors_changed);
behavior_settings.changed.connect (configure_hotcorners); hot_corner_manager = new HotCornerManager (this, behavior_settings);
hot_corner_manager.on_configured.connect (update_input_area);
hot_corner_manager.configure ();
zoom = new Zoom (this); zoom = new Zoom (this);
@ -377,57 +377,9 @@ namespace Gala {
} }
void on_monitors_changed () { void on_monitors_changed () {
configure_hotcorners ();
screen_shield.expand_to_screen_size (); screen_shield.expand_to_screen_size ();
} }
void configure_hotcorners () {
unowned Meta.Display display = get_display ();
var geometry = display.get_monitor_geometry (display.get_primary_monitor ());
add_hotcorner (geometry.x, geometry.y, "hotcorner-topleft");
add_hotcorner (geometry.x + geometry.width - 1, geometry.y, "hotcorner-topright");
add_hotcorner (geometry.x, geometry.y + geometry.height - 1, "hotcorner-bottomleft");
add_hotcorner (geometry.x + geometry.width - 1, geometry.y + geometry.height - 1, "hotcorner-bottomright");
update_input_area ();
}
void add_hotcorner (float x, float y, string key) {
unowned Clutter.Actor? stage = get_display ().get_stage ();
return_if_fail (stage != null);
var action = (ActionType) behavior_settings.get_enum (key);
Clutter.Actor? hot_corner = stage.find_child_by_name (key);
if (action == ActionType.NONE) {
if (hot_corner != null)
stage.remove_child (hot_corner);
return;
}
// if the hot corner already exists, just reposition it, create it otherwise
if (hot_corner == null) {
hot_corner = new Clutter.Actor ();
hot_corner.width = 1;
hot_corner.height = 1;
hot_corner.opacity = 0;
hot_corner.reactive = true;
hot_corner.name = key;
stage.add_child (hot_corner);
hot_corner.enter_event.connect ((actor, event) => {
last_hotcorner = actor;
perform_action ((ActionType) behavior_settings.get_enum (actor.name));
return false;
});
}
hot_corner.x = x;
hot_corner.y = y;
}
[CCode (instance_pos = -1)] [CCode (instance_pos = -1)]
void handle_cycle_workspaces (Meta.Display display, Meta.Window? window, Clutter.KeyEvent event, void handle_cycle_workspaces (Meta.Display display, Meta.Window? window, Clutter.KeyEvent event,
Meta.KeyBinding binding) { Meta.KeyBinding binding) {
@ -861,34 +813,6 @@ namespace Gala {
warning (e.message); warning (e.message);
} }
break; break;
case ActionType.CUSTOM_COMMAND:
string command = "";
var line = behavior_settings.get_string ("hotcorner-custom-command");
if (line == "")
return;
var parts = line.split (";;");
// keep compatibility to old version where only one command was possible
if (parts.length == 1) {
command = line;
} else {
// find specific actions
var search = last_hotcorner.name;
foreach (var part in parts) {
var details = part.split (":");
if (details[0] == search) {
command = details[1];
}
}
}
try {
Process.spawn_command_line_async (command);
} catch (Error e) {
warning (e.message);
}
break;
case ActionType.WINDOW_OVERVIEW: case ActionType.WINDOW_OVERVIEW:
if (window_overview == null) if (window_overview == null)
break; break;

View File

@ -32,6 +32,7 @@ gala_bin_sources = files(
'Gestures/GestureTracker.vala', 'Gestures/GestureTracker.vala',
'Gestures/ScrollBackend.vala', 'Gestures/ScrollBackend.vala',
'Gestures/ToucheggBackend.vala', 'Gestures/ToucheggBackend.vala',
'HotCorners/HotCornerManager.vala',
'Widgets/IconGroup.vala', 'Widgets/IconGroup.vala',
'Widgets/IconGroupContainer.vala', 'Widgets/IconGroupContainer.vala',
'Widgets/MonitorClone.vala', 'Widgets/MonitorClone.vala',