allow keybindings to pass through while in multitaskingview, start implementing selecting windows via keyboard

This commit is contained in:
Tom Beckmann 2014-06-15 23:43:34 +02:00
parent 5d8d3b0f71
commit 5adb6566f6
5 changed files with 154 additions and 12 deletions

View File

@ -95,7 +95,7 @@ namespace Gala
/**
* returns a pixbuf for this application or a default icon
**/
public static Gdk.Pixbuf get_icon_for_application (Bamf.Application app, int size)
public static Gdk.Pixbuf get_icon_for_application (Bamf.Application? app, int size)
{
Gdk.Pixbuf? image = null;
bool not_cached = false;

View File

@ -54,6 +54,10 @@ namespace Gala
* counted from 0 up.
*/
public abstract HashTable<int,int> window_stacking_order { get; protected set; }
/**
* If true all keybindings will be blocked while modal mode is active.
*/
public abstract bool block_keybindings_in_modal { get; set; default = true; }
public abstract void begin_modal ();
public abstract void end_modal ();

View File

@ -1,4 +1,5 @@
using Clutter;
using Meta;
namespace Gala
{
@ -40,6 +41,12 @@ namespace Gala
});
}
public override void key_focus_out ()
{
if (opened)
toggle ();
}
public override bool scroll_event (ScrollEvent event)
{
if (event.direction == ScrollDirection.SMOOTH)
@ -141,12 +148,37 @@ namespace Gala
public override bool key_press_event (Clutter.KeyEvent event)
{
if (event.keyval == Clutter.Key.Escape)
toggle ();
switch (event.keyval) {
case Clutter.Key.Escape:
if (opened)
toggle ();
break;
case Clutter.Key.Down:
select_window (MotionDirection.DOWN);
break;
case Clutter.Key.Up:
select_window (MotionDirection.UP);
break;
case Clutter.Key.Left:
select_window (MotionDirection.LEFT);
break;
case Clutter.Key.Right:
select_window (MotionDirection.RIGHT);
break;
}
return false;
}
void select_window (MotionDirection direction)
{
foreach (var child in workspaces.get_children ()) {
var workspace_clone = child as WorkspaceClone;
if (workspace_clone.workspace == screen.get_active_workspace ())
workspace_clone.window_container.select_next_window (direction);
}
}
void window_selected (Meta.Window window)
{
window.activate (screen.get_display ().get_current_time ());
@ -165,6 +197,7 @@ namespace Gala
if (opening) {
wm.begin_modal ();
wm.block_keybindings_in_modal = false;
wm.background_group.hide ();
wm.window_group.hide ();
@ -206,6 +239,7 @@ namespace Gala
wm.window_group.show ();
wm.top_window_group.show ();
wm.block_keybindings_in_modal = true;
wm.end_modal ();
return false;

View File

@ -6,20 +6,39 @@ namespace Gala
public class TiledWindow : Actor
{
const int WINDOW_ICON_SIZE = 64;
const int ACTIVE_SHAPE_SIZE = 12;
public signal void selected ();
public signal void request_reposition ();
public Meta.Window window { get; construct; }
public Meta.Rectangle? slot { get; private set; default = null; }
bool _active = false;
public bool active {
get {
return _active;
}
set {
_active = value;
active_shape.save_easing_state ();
active_shape.set_easing_duration (200);
active_shape.opacity = _active ? 255 : 0;
active_shape.restore_easing_state ();
}
}
DragDropAction drag_action;
Clone? clone = null;
Meta.Rectangle? slot = null;
Actor prev_parent = null;
int prev_index = -1;
Actor close_button;
Actor active_shape;
GtkClutter.Texture window_icon;
public TiledWindow (Meta.Window window)
@ -28,8 +47,6 @@ namespace Gala
reactive = true;
load_clone ();
window.unmanaged.connect (unmanaged);
drag_action = new DragDropAction (DragDropActionType.SOURCE, "multitaskingview-window");
@ -73,8 +90,15 @@ namespace Gala
window_icon.set_from_pixbuf (Utils.get_icon_for_window (window, WINDOW_ICON_SIZE));
} catch (Error e) {}
active_shape = new Clutter.Actor ();
active_shape.background_color = { 255, 255, 255, 200 };
active_shape.opacity = 0;
add_child (active_shape);
add_child (window_icon);
add_child (close_button);
load_clone ();
}
~TiledWindow ()
@ -98,6 +122,10 @@ namespace Gala
clone = new Clone (actor);
add_child (clone);
set_child_below_sibling (active_shape, clone);
set_child_above_sibling (close_button, clone);
set_child_above_sibling (window_icon, clone);
var outer_rect = window.get_outer_rect ();
set_position (outer_rect.x, outer_rect.y);
@ -135,10 +163,18 @@ namespace Gala
base.allocate (box, flags);
foreach (var child in get_children ()) {
if (child != clone)
if (child != clone && child != active_shape)
child.allocate_preferred_size (flags);
}
ActorBox shape_alloc = {
-ACTIVE_SHAPE_SIZE,
-ACTIVE_SHAPE_SIZE,
box.get_width () + ACTIVE_SHAPE_SIZE,
box.get_height () + ACTIVE_SHAPE_SIZE
};
active_shape.allocate (shape_alloc, flags);
if (clone == null)
return;
@ -314,6 +350,8 @@ namespace Gala
}
}
TiledWindow? current_window = null;
public TiledWorkspaceContainer (HashTable<int,int> stacking_order)
{
_stacking_order = stacking_order;
@ -400,15 +438,81 @@ namespace Gala
(int)height - padding_top - padding_bottom
};
var result = InternalUtils.calculate_grid_placement (area, windows);
var window_positions = InternalUtils.calculate_grid_placement (area, windows);
foreach (var tilable in result) {
foreach (var tilable in window_positions) {
var window = (TiledWindow)tilable.id;
window.take_slot (tilable.rect);
window.place_widgets (tilable.rect.width, tilable.rect.height);
}
}
public void select_next_window (MotionDirection direction)
{
// TODO
return;
if (get_n_children () < 1)
return;
if (current_window == null) {
current_window = get_child_at_index (0) as TiledWindow;
return;
}
var current_center = rect_center (current_window.slot);
TiledWindow? closest = null;
var closest_distance = int.MAX;
foreach (var window in get_children ()) {
if (window == current_window)
continue;
var window_center = rect_center ((window as TiledWindow).slot);
int window_coord = 0, current_coord = 0;
switch (direction) {
case MotionDirection.LEFT:
case MotionDirection.RIGHT:
window_coord = window_center.x;
current_coord = current_center.x;
if ((direction == MotionDirection.LEFT && window_coord > current_coord)
|| (direction == MotionDirection.RIGHT && window_coord < current_coord))
continue;
break;
case MotionDirection.UP:
case MotionDirection.DOWN:
window_coord = window_center.y;
current_coord = window_center.y;
if ((direction == MotionDirection.UP && window_coord > current_coord)
|| (direction == MotionDirection.DOWN && window_coord < current_coord))
continue;
break;
}
if ((window_coord - current_coord).abs () < closest_distance)
closest = window as TiledWindow;
}
if (closest == null)
return;
if (current_window != null)
current_window.active = false;
closest.active = true;
current_window = closest;
}
Gdk.Point rect_center (Meta.Rectangle rect)
{
return { rect.x + rect.width / 2, rect.y + rect.height / 2 };
}
public void transition_to_original_state ()
{
foreach (var child in get_children ()) {

View File

@ -31,6 +31,8 @@ namespace Gala
public WorkspaceManager workspace_manager { get; private set; }
public bool block_keybindings_in_modal { get; set; default = true; }
Meta.PluginInfo info;
WindowSwitcher? winswitcher = null;
@ -1090,9 +1092,7 @@ namespace Gala
public override bool keybinding_filter (Meta.KeyBinding binding)
{
// for now we'll just block all keybindings if we're in modal mode,
// do something useful with this later
return modal_count > 0;
return block_keybindings_in_modal && modal_count > 0;
}
public override unowned Meta.PluginInfo? plugin_info ()