From 154fd60d1dc64ebd52d9ca25e22584fa06efa3be Mon Sep 17 00:00:00 2001 From: Tom Beckmann Date: Mon, 6 Aug 2012 23:03:11 +0200 Subject: [PATCH 1/6] Implemented zooming support --- CMakeLists.txt | 1 + data/org.pantheon.desktop.gala.gschema.xml | 10 ++ src/Plugin.vala | 10 ++ src/Zooming.vala | 139 +++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 src/Zooming.vala diff --git a/CMakeLists.txt b/CMakeLists.txt index 72b15b52..a0135bbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ vala_precompile(VALA_C src/Settings.vala src/TextShadowEffect.vala src/Utils.vala + src/Zooming.vala src/Widgets/AppIcon.vala src/Widgets/WindowSwitcher.vala src/Widgets/WorkspaceThumb.vala diff --git a/data/org.pantheon.desktop.gala.gschema.xml b/data/org.pantheon.desktop.gala.gschema.xml index e820770c..09d87e64 100644 --- a/data/org.pantheon.desktop.gala.gschema.xml +++ b/data/org.pantheon.desktop.gala.gschema.xml @@ -65,6 +65,16 @@ Shortcut to move to last workspace + + plus', 'KP_Add']]]> + Zoom in + + + + minus', 'KP_Subtract']]]> + Zoom out + + diff --git a/src/Plugin.vala b/src/Plugin.vala index d431c940..d8436c22 100644 --- a/src/Plugin.vala +++ b/src/Plugin.vala @@ -39,6 +39,7 @@ namespace Gala { WindowSwitcher winswitcher; WorkspaceView workspace_view; + Zooming zooming; Window? moving; //place for the window that is being moved over @@ -77,8 +78,11 @@ namespace Gala winswitcher = new WindowSwitcher (this); + zooming = new Zooming (this); + stage.add_child (workspace_view); stage.add_child (winswitcher); + stage.add_child (zooming); /*keybindings*/ @@ -88,6 +92,12 @@ namespace Gala screen.get_display ().add_keybinding ("move-to-workspace-last", BehaviorSettings.get_default ().schema, 0, () => { screen.get_workspace_by_index (screen.n_workspaces - 1).activate (screen.get_display ().get_current_time ()); }); + screen.get_display ().add_keybinding ("zoom-in", BehaviorSettings.get_default ().schema, 0, () => { + zooming.zoom (true); + }); + screen.get_display ().add_keybinding ("zoom-out", BehaviorSettings.get_default ().schema, 0, () => { + zooming.zoom (false); + }); screen.get_display ().overlay_key.connect (() => { try { diff --git a/src/Zooming.vala b/src/Zooming.vala new file mode 100644 index 00000000..4057648b --- /dev/null +++ b/src/Zooming.vala @@ -0,0 +1,139 @@ +// +// Copyright (C) 2012 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 . +// + +using Clutter; +using Meta; + +namespace Gala +{ + + public class Zooming : Clutter.Actor + { + + Plugin plugin; + + public Zooming (Plugin _plugin) + { + plugin = _plugin; + var stage = Compositor.get_stage_for_screen (plugin.get_screen ()); + + visible = false; + reactive = true; + + add_constraint (new BindConstraint (stage, BindCoordinate.WIDTH, 0)); + add_constraint (new BindConstraint (stage, BindCoordinate.HEIGHT, 0)); + + } + + public override bool key_press_event (Clutter.KeyEvent event) + { + switch (event.keyval) { + case Key.Escape: + end (); + + return true; + case Key.plus: + case Key.KP_Add: + zoom (true); + + return true; + case Key.KP_Subtract: + case Key.minus: + zoom (false); + + return true; + } + + return false; + } + + public override bool button_release_event (ButtonEvent event) + { + end (); + + return true; + } + + public override void key_focus_out () + { + end (); + } + + public override bool motion_event (Clutter.MotionEvent event) + { + var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); + wins.scale_center_x = event.x * (1 / (float)scale_x); + wins.scale_center_y = event.y * (1 / (float)scale_x); + + return true; + } + + void end () + { + if (!visible) + return; + + visible = false; + + var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); + wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x:1.0, scale_y:1.0).completed.connect (() => { + wins.scale_center_x = 0.0f; + wins.scale_center_y = 0.0f; + }); + plugin.end_modal (); + + plugin.update_input_area (); + } + + public void zoom (bool in) + { + var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); + + //setup things + if (in && !visible) { + plugin.begin_modal (); + grab_key_focus (); + + int mx, my; + Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out mx, out my); + wins.scale_center_x = mx; + wins.scale_center_y = my; + + visible = true; + get_parent ().set_child_above_sibling (this, null); + Utils.set_input_area (plugin.get_screen (), InputArea.FULLSCREEN); + } + + if (!visible) + return; + + var new_val = wins.scale_x - ( in ? -0.5 : 0.5); + + //because of the animation, we might stop a bit before 1.0 accidentally + if (new_val <= 1.25) { + end (); + return; + } + if (new_val > 2.5) + new_val = 2.5; + + wins.animate (Clutter.AnimationMode.EASE_OUT_CUBIC, 300, scale_x:new_val, scale_y:new_val); + } + + } + +} From 511145eaf7bf318a1304950a1a42b46f5716ff94 Mon Sep 17 00:00:00 2001 From: Tom Beckmann Date: Wed, 8 Aug 2012 22:04:15 +0200 Subject: [PATCH 2/6] Make input working while being zoomed in --- data/org.pantheon.desktop.gala.gschema.xml | 2 +- src/Plugin.vala | 1 - src/Zooming.vala | 86 ++++++---------------- 3 files changed, 23 insertions(+), 66 deletions(-) diff --git a/data/org.pantheon.desktop.gala.gschema.xml b/data/org.pantheon.desktop.gala.gschema.xml index 09d87e64..c411b35a 100644 --- a/data/org.pantheon.desktop.gala.gschema.xml +++ b/data/org.pantheon.desktop.gala.gschema.xml @@ -71,7 +71,7 @@ - minus', 'KP_Subtract']]]> + minus', 'KP_Subtract']]]> Zoom out diff --git a/src/Plugin.vala b/src/Plugin.vala index d8436c22..57f8cd5a 100644 --- a/src/Plugin.vala +++ b/src/Plugin.vala @@ -82,7 +82,6 @@ namespace Gala stage.add_child (workspace_view); stage.add_child (winswitcher); - stage.add_child (zooming); /*keybindings*/ diff --git a/src/Zooming.vala b/src/Zooming.vala index 4057648b..c45a7222 100644 --- a/src/Zooming.vala +++ b/src/Zooming.vala @@ -20,83 +20,36 @@ using Meta; namespace Gala { - - public class Zooming : Clutter.Actor + + public class Zooming : Object { Plugin plugin; + bool active; + uint mouse_poll; + public Zooming (Plugin _plugin) { plugin = _plugin; - var stage = Compositor.get_stage_for_screen (plugin.get_screen ()); - visible = false; - reactive = true; - - add_constraint (new BindConstraint (stage, BindCoordinate.WIDTH, 0)); - add_constraint (new BindConstraint (stage, BindCoordinate.HEIGHT, 0)); - - } - - public override bool key_press_event (Clutter.KeyEvent event) - { - switch (event.keyval) { - case Key.Escape: - end (); - - return true; - case Key.plus: - case Key.KP_Add: - zoom (true); - - return true; - case Key.KP_Subtract: - case Key.minus: - zoom (false); - - return true; - } - - return false; - } - - public override bool button_release_event (ButtonEvent event) - { - end (); - - return true; - } - - public override void key_focus_out () - { - end (); - } - - public override bool motion_event (Clutter.MotionEvent event) - { - var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); - wins.scale_center_x = event.x * (1 / (float)scale_x); - wins.scale_center_y = event.y * (1 / (float)scale_x); - - return true; + active = false; } void end () { - if (!visible) + if (!active) return; - visible = false; + active = false; var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x:1.0, scale_y:1.0).completed.connect (() => { wins.scale_center_x = 0.0f; wins.scale_center_y = 0.0f; }); - plugin.end_modal (); - plugin.update_input_area (); + Source.remove (mouse_poll); } public void zoom (bool in) @@ -104,21 +57,26 @@ namespace Gala var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); //setup things - if (in && !visible) { - plugin.begin_modal (); - grab_key_focus (); - + if (in && !active) { int mx, my; Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out mx, out my); wins.scale_center_x = mx; wins.scale_center_y = my; - visible = true; - get_parent ().set_child_above_sibling (this, null); - Utils.set_input_area (plugin.get_screen (), InputArea.FULLSCREEN); + active = true; + + mouse_poll = Timeout.add (50, () => { + float x, y; + Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out x, out y); + + wins.animate (Clutter.AnimationMode.LINEAR, 50, scale_center_x : x); + wins.animate (Clutter.AnimationMode.LINEAR, 50, scale_center_y : y); + + return true; + }); } - if (!visible) + if (!active) return; var new_val = wins.scale_x - ( in ? -0.5 : 0.5); From d4e1adb16ead854d13a684642e611e8508e7ebb1 Mon Sep 17 00:00:00 2001 From: Tom Beckmann Date: Tue, 28 Aug 2012 10:09:34 +0200 Subject: [PATCH 3/6] Some cleanups --- src/Zooming.vala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Zooming.vala b/src/Zooming.vala index c45a7222..f7c31caa 100644 --- a/src/Zooming.vala +++ b/src/Zooming.vala @@ -20,10 +20,8 @@ using Meta; namespace Gala { - public class Zooming : Object { - Plugin plugin; bool active; @@ -69,8 +67,7 @@ namespace Gala float x, y; Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out x, out y); - wins.animate (Clutter.AnimationMode.LINEAR, 50, scale_center_x : x); - wins.animate (Clutter.AnimationMode.LINEAR, 50, scale_center_y : y); + wins.animate (Clutter.AnimationMode.LINEAR, 50, scale_center_x : x, scale_center_y : y); return true; }); @@ -91,7 +88,5 @@ namespace Gala wins.animate (Clutter.AnimationMode.EASE_OUT_CUBIC, 300, scale_x:new_val, scale_y:new_val); } - } - } From b7e01e36b10f3467a77cf9393115461ab0778077 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Tue, 28 Aug 2012 13:44:52 +0200 Subject: [PATCH 4/6] Clean up which resulted in changing the whole thing --- src/Plugin.vala | 4 +-- src/Zooming.vala | 87 ++++++++++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/Plugin.vala b/src/Plugin.vala index adf8ff0b..258fcee2 100644 --- a/src/Plugin.vala +++ b/src/Plugin.vala @@ -101,10 +101,10 @@ namespace Gala screen.get_workspace_by_index (screen.n_workspaces - 1).activate (screen.get_display ().get_current_time ()); }); screen.get_display ().add_keybinding ("zoom-in", BehaviorSettings.get_default ().schema, 0, () => { - zooming.zoom (true); + zooming.zoom_in (); }); screen.get_display ().add_keybinding ("zoom-out", BehaviorSettings.get_default ().schema, 0, () => { - zooming.zoom (false); + zooming.zoom_out (); }); screen.get_display ().overlay_key.connect (() => { diff --git a/src/Zooming.vala b/src/Zooming.vala index f7c31caa..235fd446 100644 --- a/src/Zooming.vala +++ b/src/Zooming.vala @@ -24,69 +24,76 @@ namespace Gala { Plugin plugin; - bool active; - uint mouse_poll; + const uint MOUSE_POLL_TIME = 50; + uint mouse_poll_timer = 0; + float current_zoom = 1.0f; public Zooming (Plugin _plugin) { plugin = _plugin; - - active = false; } - void end () + ~Zooming () { - if (!active) + if (mouse_poll_timer > 0) + Source.remove (mouse_poll_timer); + mouse_poll_timer = 0; + } + + public void zoom_in () { + zoom (true); + } + + public void zoom_out () { + zoom (false); + } + + void zoom (bool @in) + { + // Nothing to do if zooming out of our bounds is requested + if (current_zoom <= 1.0f && !@in) + return; + else if (current_zoom >= 2.5f && @in) return; - active = false; - - var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); - wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x:1.0, scale_y:1.0).completed.connect (() => { - wins.scale_center_x = 0.0f; - wins.scale_center_y = 0.0f; - }); - - Source.remove (mouse_poll); - } - - public void zoom (bool in) - { var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); - //setup things - if (in && !active) { - int mx, my; - Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out mx, out my); + // Add timer to poll current mouse position to reposition window-group + // to show requested zoomed area + if (mouse_poll_timer == 0) { + float mx, my; + var client_pointer = Gdk.Display.get_default ().get_device_manager ().get_client_pointer (); + client_pointer.get_position (null, out mx, out my); wins.scale_center_x = mx; wins.scale_center_y = my; - active = true; - - mouse_poll = Timeout.add (50, () => { - float x, y; - Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out x, out y); - - wins.animate (Clutter.AnimationMode.LINEAR, 50, scale_center_x : x, scale_center_y : y); + mouse_poll_timer = Timeout.add (MOUSE_POLL_TIME, () => { + client_pointer.get_position (null, out mx, out my); + wins.animate (AnimationMode.LINEAR, 50, scale_center_x : mx, scale_center_y : my); return true; }); } - if (!active) - return; + current_zoom += (@in ? 0.5f : -0.5f); - var new_val = wins.scale_x - ( in ? -0.5 : 0.5); - - //because of the animation, we might stop a bit before 1.0 accidentally - if (new_val <= 1.25) { - end (); + if (current_zoom <= 1.0f) { + current_zoom = 1.0f; + + if (mouse_poll_timer == 0) + return; + Source.remove (mouse_poll_timer); + mouse_poll_timer = 0; + + wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x : 1.0f, scale_y : 1.0f).completed.connect (() => { + wins.scale_center_x = 0.0f; + wins.scale_center_y = 0.0f; + }); + return; } - if (new_val > 2.5) - new_val = 2.5; - wins.animate (Clutter.AnimationMode.EASE_OUT_CUBIC, 300, scale_x:new_val, scale_y:new_val); + wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x : current_zoom, scale_y : current_zoom); } } } From 5f85958429dbe4da301b7ec131935f48e5410ed3 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Tue, 28 Aug 2012 14:16:14 +0200 Subject: [PATCH 5/6] No need to bail here --- src/Zooming.vala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Zooming.vala b/src/Zooming.vala index 235fd446..1e1fa463 100644 --- a/src/Zooming.vala +++ b/src/Zooming.vala @@ -80,9 +80,8 @@ namespace Gala if (current_zoom <= 1.0f) { current_zoom = 1.0f; - if (mouse_poll_timer == 0) - return; - Source.remove (mouse_poll_timer); + if (mouse_poll_timer > 0) + Source.remove (mouse_poll_timer); mouse_poll_timer = 0; wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x : 1.0f, scale_y : 1.0f).completed.connect (() => { From 66211659a7396c4ae62a5ccb86af598a00f54b2b Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Tue, 28 Aug 2012 14:36:49 +0200 Subject: [PATCH 6/6] Avoid attaching useless animation to follow mouse cursor --- src/Zooming.vala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Zooming.vala b/src/Zooming.vala index 1e1fa463..6e44d5f3 100644 --- a/src/Zooming.vala +++ b/src/Zooming.vala @@ -69,7 +69,10 @@ namespace Gala mouse_poll_timer = Timeout.add (MOUSE_POLL_TIME, () => { client_pointer.get_position (null, out mx, out my); - wins.animate (AnimationMode.LINEAR, 50, scale_center_x : mx, scale_center_y : my); + if (wins.scale_center_x == mx && wins.scale_center_y == my) + return true; + + wins.animate (AnimationMode.LINEAR, MOUSE_POLL_TIME, scale_center_x : mx, scale_center_y : my); return true; });