WindowClone: support differing scales

This commit is contained in:
David Hewitt 2023-04-12 10:07:51 +01:00 committed by Corentin Noël
parent 82ca34cbed
commit 14767bfde7
5 changed files with 90 additions and 41 deletions

View File

@ -43,7 +43,9 @@ namespace Gala {
background = new BackgroundManager (display, monitor, false);
window_container = new WindowCloneContainer (wm, gesture_tracker);
var scale = display.get_monitor_scale (monitor);
window_container = new WindowCloneContainer (wm, gesture_tracker, scale);
window_container.window_selected.connect ((w) => { window_selected (w); });
display.window_entered_monitor.connect (window_entered);

View File

@ -52,6 +52,18 @@ public class Gala.WindowClone : Clutter.Actor {
public bool overview_mode { get; construct; }
public GestureTracker? gesture_tracker { get; construct; }
private float _monitor_scale_factor = 1.0f;
public float monitor_scale_factor {
get {
return _monitor_scale_factor;
}
set {
if (value != _monitor_scale_factor) {
_monitor_scale_factor = value;
reallocate ();
}
}
}
[CCode (notify = false)]
public uint8 shadow_opacity {
@ -80,8 +92,14 @@ public class Gala.WindowClone : Clutter.Actor {
private Clutter.Actor window_icon;
private Tooltip window_title;
public WindowClone (WindowManager wm, Meta.Window window, GestureTracker? gesture_tracker, bool overview_mode = false) {
Object (wm: wm, window: window, gesture_tracker: gesture_tracker, overview_mode: overview_mode);
public WindowClone (WindowManager wm, Meta.Window window, GestureTracker? gesture_tracker, float scale, bool overview_mode = false) {
Object (
wm: wm,
window: window,
gesture_tracker: gesture_tracker,
monitor_scale_factor: scale,
overview_mode: overview_mode
);
}
construct {
@ -111,26 +129,6 @@ public class Gala.WindowClone : Clutter.Actor {
add_action (drag_action);
}
var window_frame_rect = window.get_frame_rect ();
unowned var display = wm.get_display ();
var scale_factor = display.get_monitor_scale (display.get_monitor_index_for_rect (window_frame_rect));
var close_button_action = new Clutter.ClickAction ();
close_button_action.clicked.connect (() => {
close_window ();
});
close_button = Utils.create_close_button (scale_factor);
close_button.opacity = 0;
// block propagation of button release event to window clone
close_button.button_release_event.connect (() => { return Clutter.EVENT_STOP; });
close_button.add_action (close_button_action);
window_icon = new WindowIcon (window, WINDOW_ICON_SIZE, (int)Math.round (scale_factor));
window_icon.opacity = 0;
window_icon.set_pivot_point (0.5f, 0.5f);
set_window_icon_position (window_frame_rect.width, window_frame_rect.height, scale_factor);
window_title = new Tooltip ();
window_title.opacity = 0;
@ -138,11 +136,11 @@ public class Gala.WindowClone : Clutter.Actor {
active_shape.opacity = 0;
add_child (active_shape);
add_child (window_icon);
add_child (window_title);
add_child (close_button);
load_clone ();
reallocate ();
}
~WindowClone () {
@ -153,6 +151,31 @@ public class Gala.WindowClone : Clutter.Actor {
window.notify["maximized-vertically"].disconnect (check_shadow_requirements);
}
private void reallocate () {
var window_frame_rect = window.get_frame_rect ();
var close_button_action = new Clutter.ClickAction ();
close_button_action.clicked.connect (() => {
close_window ();
});
close_button = Utils.create_close_button (monitor_scale_factor);
close_button.opacity = 0;
// block propagation of button release event to window clone
close_button.button_release_event.connect (() => { return Clutter.EVENT_STOP; });
close_button.add_action (close_button_action);
window_icon = new WindowIcon (window, WINDOW_ICON_SIZE, (int)Math.round (monitor_scale_factor));
window_icon.opacity = 0;
window_icon.set_pivot_point (0.5f, 0.5f);
set_window_icon_position (window_frame_rect.width, window_frame_rect.height, monitor_scale_factor);
add_child (close_button);
add_child (window_icon);
set_child_below_sibling (window_icon, window_title);
set_child_above_sibling (close_button, clone);
}
/**
* Waits for the texture of a new Meta.WindowActor to be available
* and makes a close of it. If it was already was assigned a slot
@ -253,7 +276,8 @@ public class Gala.WindowClone : Clutter.Actor {
unowned var display = window.get_display ();
var monitor_geom = display.get_monitor_geometry (window.get_monitor ());
var scale = display.get_monitor_scale (window.get_monitor ());
var initial_scale = monitor_scale_factor;
var target_scale = display.get_monitor_scale (window.get_monitor ());
var offset_x = monitor_geom.x;
var offset_y = monitor_geom.y;
@ -267,13 +291,14 @@ public class Gala.WindowClone : Clutter.Actor {
active = false;
in_slot_animation = true;
place_widgets (outer_rect.width, outer_rect.height, scale);
place_widgets (outer_rect.width, outer_rect.height, initial_scale);
GestureTracker.OnUpdate on_animation_update = (percentage) => {
var x = GestureTracker.animation_value (initial_x, target_x, percentage);
var y = GestureTracker.animation_value (initial_y, target_y, percentage);
var width = GestureTracker.animation_value (initial_width, outer_rect.width, percentage);
var height = GestureTracker.animation_value (initial_height, outer_rect.height, percentage);
var scale = GestureTracker.animation_value (initial_scale, target_scale, percentage);
var opacity = GestureTracker.animation_value (255f, 0f, percentage);
set_size (width, height);
@ -281,6 +306,7 @@ public class Gala.WindowClone : Clutter.Actor {
window_icon.opacity = (uint) opacity;
set_window_icon_position (width, height, scale, false);
place_widgets ((int)width, (int)height, scale);
shadow_opacity = (uint8) opacity;
};
@ -313,18 +339,18 @@ public class Gala.WindowClone : Clutter.Actor {
window_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
window_icon.set_easing_duration (duration);
window_icon.opacity = 0;
set_window_icon_position (outer_rect.width, outer_rect.height, scale);
set_window_icon_position (outer_rect.width, outer_rect.height, target_scale);
window_icon.restore_easing_state ();
var transition = window_icon.get_transition ("opacity");
if (transition != null) {
transition.completed.connect (() => {
in_slot_animation = false;
place_widgets (outer_rect.width, outer_rect.height, scale);
place_widgets (outer_rect.width, outer_rect.height, target_scale);
});
} else {
in_slot_animation = false;
place_widgets (outer_rect.width, outer_rect.height, scale);
place_widgets (outer_rect.width, outer_rect.height, target_scale);
}
};
@ -779,9 +805,7 @@ public class Gala.WindowClone : Clutter.Actor {
window_icon.set_easing_duration (duration);
window_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
unowned var display = wm.get_display ();
var scale = display.get_monitor_scale (display.get_monitor_index_for_rect (slot));
set_window_icon_position (slot.width, slot.height, scale);
set_window_icon_position (slot.width, slot.height, monitor_scale_factor);
window_icon.restore_easing_state ();
}
@ -801,7 +825,7 @@ public class Gala.WindowClone : Clutter.Actor {
private void set_window_title_position (float window_width, float window_height, float scale_factor) {
var x = (int)Math.round ((window_width - window_title.width) / 2);
var y = (int)Math.round (window_height - (WINDOW_ICON_SIZE * scale_factor) * 0.75f - (window_title.height / 2) - (18 * scale_factor));
var y = (int)Math.round (window_height - InternalUtils.scale_to_int (WINDOW_ICON_SIZE, scale_factor) * 0.75f - (window_title.height / 2) - InternalUtils.scale_to_int (18, scale_factor));
window_title.set_position (x, y);
}

View File

@ -31,6 +31,19 @@ namespace Gala {
public GestureTracker? gesture_tracker { get; construct; }
public bool overview_mode { get; construct; }
private float _monitor_scale = 1.0f;
public float monitor_scale {
get {
return _monitor_scale;
}
set {
if (value != _monitor_scale) {
_monitor_scale = value;
reallocate ();
}
}
}
private bool opened = false;
/**
@ -39,8 +52,15 @@ namespace Gala {
*/
private WindowClone? current_window = null;
public WindowCloneContainer (WindowManager wm, GestureTracker? gesture_tracker, bool overview_mode = false) {
Object (wm: wm, gesture_tracker: gesture_tracker, overview_mode: overview_mode);
public WindowCloneContainer (WindowManager wm, GestureTracker? gesture_tracker, float scale, bool overview_mode = false) {
Object (wm: wm, gesture_tracker: gesture_tracker, monitor_scale: scale, overview_mode: overview_mode);
}
private void reallocate () {
foreach (unowned var child in get_children ()) {
unowned var clone = (WindowClone) child;
clone.monitor_scale_factor = monitor_scale;
}
}
/**
@ -60,7 +80,7 @@ namespace Gala {
var windows_ordered = InternalUtils.sort_windows (display, windows);
var new_window = new WindowClone (wm, window, gesture_tracker, overview_mode);
var new_window = new WindowClone (wm, window, gesture_tracker, monitor_scale, overview_mode);
new_window.selected.connect (window_selected_cb);
new_window.destroy.connect (window_destroyed);

View File

@ -117,10 +117,13 @@ public class Gala.WindowOverview : Clutter.Actor, ActivatableComponent {
modal_proxy = wm.push_modal (this);
modal_proxy.set_keybinding_filter (keybinding_filter);
for (var i = 0; i < wm.get_display ().get_n_monitors (); i++) {
var geometry = wm.get_display ().get_monitor_geometry (i);
unowned var display = wm.get_display ();
var container = new WindowCloneContainer (wm, null, true) {
for (var i = 0; i < display.get_n_monitors (); i++) {
var geometry = display.get_monitor_geometry (i);
var scale = display.get_monitor_scale (i);
var container = new WindowCloneContainer (wm, null, scale, true) {
padding_top = TOP_GAP,
padding_left = BORDER,
padding_right = BORDER,

View File

@ -178,7 +178,7 @@ namespace Gala {
background = new FramedBackground (display);
background.add_action (background_click_action);
window_container = new WindowCloneContainer (wm, gesture_tracker);
window_container = new WindowCloneContainer (wm, gesture_tracker, scale_factor);
window_container.window_selected.connect ((w) => { window_selected (w); });
window_container.set_size (monitor_geometry.width, monitor_geometry.height);