mirror of
https://github.com/elementary/gala.git
synced 2024-12-29 20:21:39 +03:00
allow keybindings to pass through while in multitaskingview, start implementing selecting windows via keyboard
This commit is contained in:
parent
5d8d3b0f71
commit
5adb6566f6
@ -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;
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
|
@ -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 ()) {
|
||||
|
@ -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 ()
|
||||
|
Loading…
Reference in New Issue
Block a user