Add support for configurable hotcorners

This commit is contained in:
Tom Beckmann 2012-07-26 00:45:51 +02:00
parent 86a2f6339b
commit 3fd839b950
5 changed files with 107 additions and 39 deletions

View File

@ -15,11 +15,28 @@
</enum>
<schema path="/org/pantheon/desktop/gala/behavior/" id="org.pantheon.desktop.gala.behavior" gettext-domain="gala">
<key type="b" name="enable-manager-corner">
<default>false</default>
<summary>Make the lower right a hot corner to reveal the manager</summary>
<description>This turns the lower right corner to a hot corner, showing some icons allowing you to do tasks like window tiling</description>
<key enum="gala-action-type" name="hotcorner-topleft">
<default>"None"</default>
<summary>Action for the top left corner</summary>
<description></description>
</key>
<key enum="gala-action-type" name="hotcorner-topright">
<default>"None"</default>
<summary>Action for the top right corner</summary>
<description></description>
</key>
<key enum="gala-action-type" name="hotcorner-bottomleft">
<default>"None"</default>
<summary>Action for the bottom left corner</summary>
<description></description>
</key>
<key enum="gala-action-type" name="hotcorner-bottomright">
<default>"None"</default>
<summary>Action for the bottom right corner</summary>
<description></description>
</key>
<key type="b" name="edge-tiling">
<default>true</default>
<summary>Enable edge tiling when dropping windows on screen edges</summary>

View File

@ -4,16 +4,16 @@ namespace Gala
{
public enum ActionType
{
NONE,
SHOW_WORKSPACE_VIEW,
WORKSPACE_LEFT,
WORKSPACE_RIGHT,
MOVE_TO_WORKSPACE_LEFT,
MOVE_TO_WORKSPACE_RIGHT,
MAXIMIZE_CURRENT,
MINIMIZE_CURRENT,
CLOSE_CURRENT,
OPEN_LAUNCHER
NONE = 0,
SHOW_WORKSPACE_VIEW = 1,
WORKSPACE_LEFT = 2,
WORKSPACE_RIGHT = 3,
MOVE_TO_WORKSPACE_LEFT = 4,
MOVE_TO_WORKSPACE_RIGHT = 5,
MAXIMIZE_CURRENT = 6,
MINIMIZE_CURRENT = 7,
CLOSE_CURRENT = 8,
OPEN_LAUNCHER = 9
}
public class Action
@ -22,6 +22,7 @@ namespace Gala
{
var screen = plugin.get_screen ();
var display = screen.get_display ();
var current = display.get_focus_window ();
switch (type) {
case ActionType.SHOW_WORKSPACE_VIEW:
@ -34,19 +35,26 @@ namespace Gala
plugin.workspace_view.switch_to_next_workspace (MotionDirection.RIGHT);
break;
case ActionType.MOVE_TO_WORKSPACE_LEFT:
plugin.move_window (display.get_focus_window (), MotionDirection.LEFT);
plugin.move_window (current, MotionDirection.LEFT);
break;
case ActionType.MOVE_TO_WORKSPACE_RIGHT:
plugin.move_window (display.get_focus_window (), MotionDirection.RIGHT);
plugin.move_window (current, MotionDirection.RIGHT);
break;
case ActionType.MAXIMIZE_CURRENT:
display.get_focus_window ().maximize (MaximizeFlags.HORIZONTAL | MaximizeFlags.VERTICAL);
if (current == null)
break;
if (current.get_maximized () == (MaximizeFlags.HORIZONTAL | MaximizeFlags.VERTICAL))
current.unmaximize (MaximizeFlags.HORIZONTAL | MaximizeFlags.VERTICAL);
else
current.maximize (MaximizeFlags.HORIZONTAL | MaximizeFlags.VERTICAL);
break;
case ActionType.MINIMIZE_CURRENT:
display.get_focus_window ().minimize ();
if (current != null)
current.minimize ();
break;
case ActionType.CLOSE_CURRENT:
display.get_focus_window ().delete (display.get_current_time ());
if (current != null)
current.delete (display.get_current_time ());
break;
case ActionType.OPEN_LAUNCHER:
try {

View File

@ -116,32 +116,60 @@ namespace Gala
Utils.reload_shadow ();
ShadowSettings.get_default ().notify.connect (Utils.reload_shadow);
/*hot corner*/
/*hot corner, getting enum values from GraniteServicesSettings did not work, so we use GSettings directly*/
var geometry = screen.get_monitor_geometry (screen.get_primary_monitor ());
var hot_corner = new Clutter.Rectangle ();
hot_corner.x = geometry.x + geometry.width - 1;
hot_corner.y = geometry.y + geometry.height - 1;
var top_left = create_hotcorner (geometry.x, geometry.y);
top_left.enter_event.connect (() => {
Action.run (this, (ActionType)BehaviorSettings.get_default ().schema.get_enum ("hotcorner-topleft"));
return false;
});
var top_right = create_hotcorner (geometry.x + geometry.width - 1, geometry.y);
top_right.enter_event.connect (() => {
Action.run (this, (ActionType)BehaviorSettings.get_default ().schema.get_enum ("hotcorner-topright"));
return false;
});
var bottom_left = create_hotcorner (geometry.x, geometry.y + geometry.height - 1);
bottom_left.enter_event.connect (() => {
Action.run (this, (ActionType)BehaviorSettings.get_default ().schema.get_enum ("hotcorner-bottomleft"));
return false;
});
var bottom_right = create_hotcorner (geometry.x + geometry.width - 1, geometry.y + geometry.height - 1);
bottom_right.enter_event.connect (() => {
Action.run (this, (ActionType)BehaviorSettings.get_default ().schema.get_enum ("hotcorner-bottomright"));
return false;
});
update_input_area ();
BehaviorSettings.get_default ().notify["hotcorner-topleft"].connect (update_input_area);
BehaviorSettings.get_default ().notify["hotcorner-topright"].connect (update_input_area);
BehaviorSettings.get_default ().notify["hotcorner-bottomleft"].connect (update_input_area);
BehaviorSettings.get_default ().notify["hotcorner-bottomright"].connect (update_input_area);
BehaviorSettings.get_default ().schema.changed.connect ((key) => update_input_area ());
}
Clutter.Actor create_hotcorner (float x, float y)
{
var hot_corner = new Clutter.Actor ();
hot_corner.x = x;
hot_corner.y = y;
hot_corner.width = 1;
hot_corner.height = 1;
hot_corner.opacity = 0;
hot_corner.reactive = true;
hot_corner.enter_event.connect (() => {
workspace_view.show ();
return false;
});
Compositor.get_stage_for_screen (get_screen ()).add_child (hot_corner);
stage.add_child (hot_corner);
update_input_area ();
BehaviorSettings.get_default ().notify["enable-manager-corner"].connect (update_input_area);
return hot_corner;
}
public void update_input_area ()
{
if (BehaviorSettings.get_default ().enable_manager_corner)
if (BehaviorSettings.get_default ().schema.get_enum ("hotcorner-topleft") != ActionType.NONE ||
BehaviorSettings.get_default ().schema.get_enum ("hotcorner-topright") != ActionType.NONE ||
BehaviorSettings.get_default ().schema.get_enum ("hotcorner-bottomleft") != ActionType.NONE ||
BehaviorSettings.get_default ().schema.get_enum ("hotcorner-bottomright") != ActionType.NONE)
Utils.set_input_area (get_screen (), Utils.InputArea.HOT_CORNER);
else
Utils.set_input_area (get_screen (), Utils.InputArea.NONE);

View File

@ -23,7 +23,11 @@ namespace Gala
public string panel_main_menu_action { get; set; }
public string toggle_recording_action { get; set; }
public string overlay_action { get; set; }
public bool enable_manager_corner { get; set; }
public ActionType hotcorner_topleft { get; set; }
public ActionType hotcorner_topright { get; set; }
public ActionType hotcorner_bottomleft { get; set; }
public ActionType hotcorner_bottomright { get; set; }
static BehaviorSettings? instance = null;

View File

@ -105,24 +105,35 @@ namespace Gala.Utils
{
var display = screen.get_display ();
X.Xrectangle rect;
X.Xrectangle[] rects;
int width, height;
screen.get_size (out width, out height);
var geometry = screen.get_monitor_geometry (screen.get_primary_monitor ());
switch (area) {
case InputArea.FULLSCREEN:
rect = {0, 0, (ushort)width, (ushort)height};
X.Xrectangle rect = {0, 0, (ushort)width, (ushort)height};
rects = {rect};
break;
case InputArea.HOT_CORNER: //leave one pix in the bottom left
rect = {(short)(geometry.x + geometry.width - 1), (short)(geometry.y + geometry.height - 1), 1, 1};
case InputArea.HOT_CORNER: //if action type is none, make them 0 sized
short tl_size = (BehaviorSettings.get_default ().schema.get_enum ("hotcorner-topleft") != ActionType.NONE)?1:0;
short tr_size = (BehaviorSettings.get_default ().schema.get_enum ("hotcorner-topright") != ActionType.NONE)?1:0;
short bl_size = (BehaviorSettings.get_default ().schema.get_enum ("hotcorner-bottomleft") != ActionType.NONE)?1:0;
short br_size = (BehaviorSettings.get_default ().schema.get_enum ("hotcorner-bottomright") != ActionType.NONE)?1:0;
X.Xrectangle topleft = {(short)geometry.x, (short)geometry.y, tl_size, tl_size};
X.Xrectangle topright = {(short)(geometry.x + geometry.width - 1), (short)geometry.y, tr_size, tr_size};
X.Xrectangle bottomleft = {(short)geometry.x, (short)(geometry.y + geometry.height - 1), bl_size, bl_size};
X.Xrectangle bottomright = {(short)(geometry.x + geometry.width - 1), (short)(geometry.y + geometry.height - 1), br_size, br_size};
rects = {topleft, topright, bottomleft, bottomright};
break;
default:
Util.empty_stage_input_region (screen);
return;
}
var xregion = X.Fixes.create_region (display.get_xdisplay (), {rect});
var xregion = X.Fixes.create_region (display.get_xdisplay (), rects);
Util.set_stage_input_region (screen, xregion);
}