Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Widgets/MultitaskingView/MonitorClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Gala.MonitorClone : Widget {

background = new BackgroundManager (display, monitor, false);

var windows = new WindowListModel (display, STACKING, true, monitor);
var windows = new WindowListModel (display, STACKING, true, true, monitor);

window_container = new WindowCloneContainer (wm, windows, monitor_scale);
window_container.add_constraint (new Clutter.BindConstraint (this, SIZE, 0.0f));
Expand Down
119 changes: 95 additions & 24 deletions src/Widgets/MultitaskingView/WindowClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ public class Gala.WindowClone : Widget, RootTarget {
private ulong check_confirm_dialog_cb = 0;

private Clutter.Actor clone_container;
private Clutter.Actor child_clone_container;
private Gala.CloseButton close_button;
private ActiveShape active_shape;
private Clutter.Actor window_icon;
private Tooltip window_title;
private GLib.ListModel window_list_model;

private GestureController gesture_controller;

Expand Down Expand Up @@ -131,9 +133,14 @@ public class Gala.WindowClone : Widget, RootTarget {
};
bind_property ("monitor-scale", active_shape, "monitor-scale");

clone_container = new Clutter.Actor () {
pivot_point = { 0.5f, 0.5f }
};
window_list_model = new WindowListModel (wm.get_display (), STACKING, true, false, -1, null, new ChildFilter (window));
window_list_model.items_changed.connect_after (update_targets);

child_clone_container = new Clutter.Actor ();
child_clone_container.bind_model (window_list_model, create_child_func);

clone_container = new Clutter.Actor ();
clone_container.add_child (child_clone_container);

window_title = new Tooltip (monitor_scale);
bind_property ("monitor-scale", window_title, "monitor-scale");
Expand Down Expand Up @@ -176,6 +183,18 @@ public class Gala.WindowClone : Widget, RootTarget {
active_shape.restore_easing_state ();
}

private static Clutter.Actor create_child_func (Object obj) requires (obj is Meta.Window) {
unowned var child_window = (Meta.Window) obj;
unowned var child_window_actor = (Meta.WindowActor) child_window.get_compositor_private ();

if (child_window_actor == null) {
critical ("WindowClone: WindowListModel gave us a bad window");
return new Clutter.Actor ();
}

return new Clutter.Clone (child_window_actor);
}

private void reallocate () {
window_icon = new WindowIcon (window, WINDOW_ICON_SIZE, (int)Math.round (monitor_scale)) {
visible = mode != SINGLE_APP_OVERVIEW
Expand All @@ -197,7 +216,7 @@ public class Gala.WindowClone : Widget, RootTarget {
*/
private void load_clone (Meta.WindowActor actor) {
clone = new Clutter.Clone (actor);
clone_container.add_child (clone);
clone_container.insert_child_below (clone, null);

check_shadow_requirements ();
}
Expand Down Expand Up @@ -276,6 +295,42 @@ public class Gala.WindowClone : Widget, RootTarget {
add_target (new PropertyTarget (MULTITASKING_VIEW, window_title, "opacity", typeof (uint8), (uint8) 0u, (uint8) 255u));

add_target (new PropertyTarget (MULTITASKING_VIEW, close_button, "opacity", typeof (uint8), (uint8) 0u, (uint8) 255u));

var window_buffer_rect = window.get_buffer_rect ();
var window_shadow_spread_x = window_rect.x - window_buffer_rect.x;
var window_shadow_spread_y = window_rect.y - window_buffer_rect.y;

var i = 0u;
for (unowned var child_clone = child_clone_container.get_first_child ();
child_clone != null;
child_clone = child_clone.get_next_sibling ()
) {
var child_window = (Meta.Window) window_list_model.get_item (i);

var child_buffer_rect = child_window.get_buffer_rect ();
var child_frame_rect = child_window.get_frame_rect ();

var scale = 1.0f;
if (child_frame_rect.width > window_rect.width || child_frame_rect.height > window_rect.height) {
scale = float.min ((float) window_rect.width / child_frame_rect.width, (float) window_rect.height / child_frame_rect.height);

add_target (new PropertyTarget (MULTITASKING_VIEW, child_clone, "width", typeof (float), (float) child_buffer_rect.width, child_buffer_rect.width * scale));
add_target (new PropertyTarget (MULTITASKING_VIEW, child_clone, "height", typeof (float), (float) child_buffer_rect.height, child_buffer_rect.height * scale));
}

var child_parent_x_diff = child_buffer_rect.x - window_buffer_rect.x;
var child_parent_y_diff = child_buffer_rect.y - window_buffer_rect.y;
// Center the window
var child_shadow_spread_x = (child_frame_rect.x - child_buffer_rect.x) * scale;
var child_shadow_spread_y = (child_frame_rect.y - child_buffer_rect.y) * scale;
var target_x = window_shadow_spread_x - child_shadow_spread_x + (window_rect.width - child_frame_rect.width * scale) / 2.0f;
var target_y = window_shadow_spread_y - child_shadow_spread_y + (window_rect.height - child_frame_rect.height * scale) / 2.0f;

add_target (new PropertyTarget (MULTITASKING_VIEW, child_clone, "x", typeof (float), (float) child_parent_x_diff, target_x));
add_target (new PropertyTarget (MULTITASKING_VIEW, child_clone, "y", typeof (float), (float) child_parent_y_diff, target_y));

i++;
}
}

public override void update_progress (Gala.GestureAction action, double progress) {
Expand Down Expand Up @@ -325,7 +380,7 @@ public class Gala.WindowClone : Widget, RootTarget {

unowned var display = wm.get_display ();

clone.set_scale (clone_scale_factor, clone_scale_factor);
clone_container.set_scale (clone_scale_factor, clone_scale_factor);

Clutter.ActorBox shape_alloc = {
-ACTIVE_SHAPE_SIZE,
Expand Down Expand Up @@ -418,14 +473,14 @@ public class Gala.WindowClone : Widget, RootTarget {
drag_action.cancel ();
}

if (clone != null) {
clone.destroy ();
}
clone?.destroy ();

if (check_confirm_dialog_cb != 0) {
SignalHandler.disconnect (window.get_display (), check_confirm_dialog_cb);
check_confirm_dialog_cb = 0;
}

child_clone_container.bind_model (null, (Clutter.ActorCreateChildFunc) null);
}

private void actor_clicked (uint32 button, Clutter.InputDeviceType device_type = POINTER_DEVICE) {
Expand All @@ -443,18 +498,21 @@ public class Gala.WindowClone : Widget, RootTarget {
private Clutter.Actor drag_begin (float click_x, float click_y) requires (drag_handle == null) {
active_shape.hide ();

var scale = window_icon.width / clone.width;
var scale = window_icon.width / clone_container.width;
var duration = Utils.get_animation_duration (FADE_ANIMATION_DURATION);

float abs_x, abs_y;
clone.get_transformed_position (out abs_x, out abs_y);
clone.save_easing_state ();
clone.set_easing_duration (duration);
clone.set_easing_mode (Clutter.AnimationMode.EASE_IN_CUBIC);
clone.set_pivot_point ((click_x - abs_x) / clone.width, (click_y - abs_y) / clone.height);
clone.set_scale (scale, scale);
clone.opacity = 0;
clone.restore_easing_state ();
clone_container.get_transformed_position (out abs_x, out abs_y);
clone_container.save_easing_state ();
clone_container.set_easing_duration (duration);
clone_container.set_easing_mode (Clutter.AnimationMode.EASE_IN_CUBIC);
clone_container.set_pivot_point (
(click_x - abs_x) / clone_container.width,
(click_y - abs_y) / clone_container.height
);
clone_container.set_scale (scale, scale);
clone_container.opacity = 0;
clone_container.restore_easing_state ();

get_transformed_position (out abs_x, out abs_y);

Expand Down Expand Up @@ -565,13 +623,13 @@ public class Gala.WindowClone : Widget, RootTarget {
drag_handle.set_position (target_x, target_y);
drag_handle.restore_easing_state ();

clone.set_pivot_point (0.0f, 0.0f);
clone.save_easing_state ();
clone.set_easing_duration (duration);
clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
clone.set_scale (1, 1);
clone.opacity = 255;
clone.restore_easing_state ();
clone_container.set_pivot_point (0.0f, 0.0f);
clone_container.save_easing_state ();
clone_container.set_easing_duration (duration);
clone_container.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
clone_container.set_scale (1, 1);
clone_container.opacity = 255;
clone_container.restore_easing_state ();

close_button.visible = true;
window_title.visible = true;
Expand Down Expand Up @@ -645,4 +703,17 @@ public class Gala.WindowClone : Widget, RootTarget {
});
}
}

private class ChildFilter : Gtk.Filter {
public Meta.Window parent_window { private get; construct; }

public ChildFilter (Meta.Window parent_window) {
Object (parent_window: parent_window);
}

public override bool match (GLib.Object? item) requires (item is Meta.Window) {
unowned var window = (Meta.Window) item;
return parent_window.is_ancestor_of_transient (window);
}
}
}
2 changes: 1 addition & 1 deletion src/Widgets/MultitaskingView/WorkspaceClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public class Gala.WorkspaceClone : Widget {
background = new FramedBackground (display);
background.add_action (background_click_action);

windows = new WindowListModel (display, STACKING, true, display.get_primary_monitor (), workspace);
windows = new WindowListModel (display, STACKING, true, true, display.get_primary_monitor (), workspace);

window_container = new WindowCloneContainer (wm, windows, monitor_scale) {
width = monitor_geometry.width,
Expand Down
2 changes: 1 addition & 1 deletion src/Widgets/WindowOverview.vala
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public class Gala.WindowOverview : Root, RootTarget, ActivatableComponent {
var scale = Utils.get_ui_scaling_factor (display, i);

var custom_filter = new Gtk.CustomFilter (window_filter_func);
var model = new WindowListModel (display, STACKING, true, i, null, custom_filter);
var model = new WindowListModel (display, STACKING, true, true, i, null, custom_filter);
model.items_changed.connect (on_items_changed);

var window_clone_container = new WindowCloneContainer (wm, model, scale, mode) {
Expand Down
30 changes: 25 additions & 5 deletions src/WindowListModel.vala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public class Gala.WindowListModel : Object, ListModel {
*/
public bool normal_filter { get; construct set; }

/**
* If true only present windows that are toplevel windows and not transients.
*/
public bool not_transient_filter { get; construct set; }

/**
* If >= 0 only present windows that are on this monitor.
*/
Expand All @@ -41,14 +46,21 @@ public class Gala.WindowListModel : Object, ListModel {
private Gee.ArrayList<Meta.Window> windows;

public WindowListModel (
Meta.Display display, SortMode sort_mode = NONE,
bool normal_filter = false, int monitor_filter = -1,
Meta.Display display,
SortMode sort_mode = NONE,
bool normal_filter = false,
bool not_transient_filter = false,
int monitor_filter = -1,
Meta.Workspace? workspace_filter = null,
Gtk.Filter? custom_filter = null
) {
Object (
display: display, sort_mode: sort_mode, normal_filter: normal_filter,
monitor_filter: monitor_filter, workspace_filter: workspace_filter,
display: display,
sort_mode: sort_mode,
normal_filter: normal_filter,
not_transient_filter: not_transient_filter,
monitor_filter: monitor_filter,
workspace_filter: workspace_filter,
custom_filter: custom_filter
);
}
Expand All @@ -70,7 +82,7 @@ public class Gala.WindowListModel : Object, ListModel {

private void on_window_created (Meta.Window window) {
window.unmanaging.connect (on_window_unmanaging);
InternalUtils.wait_for_window_actor (window, (actor) => check_window (actor.meta_window));
InternalUtils.wait_for_window_actor_visible (window, (actor) => check_window (actor.meta_window));
}

private void on_window_unmanaging (Meta.Window window) {
Expand Down Expand Up @@ -102,6 +114,10 @@ public class Gala.WindowListModel : Object, ListModel {
}

private bool should_present_window (Meta.Window window) {
if (window.get_compositor_private () == null) {
return false;
}

if (monitor_filter >= 0 && monitor_filter != window.get_monitor ()) {
return false;
}
Expand All @@ -117,6 +133,10 @@ public class Gala.WindowListModel : Object, ListModel {
return false;
}

if (not_transient_filter && window.find_root_ancestor () != window) {
return false;
}

if (custom_filter != null) {
return custom_filter.match (window);
}
Expand Down