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); 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); }); window_container.window_selected.connect ((w) => { window_selected (w); });
display.window_entered_monitor.connect (window_entered); 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 bool overview_mode { get; construct; }
public GestureTracker? gesture_tracker { 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)] [CCode (notify = false)]
public uint8 shadow_opacity { public uint8 shadow_opacity {
@ -80,8 +92,14 @@ public class Gala.WindowClone : Clutter.Actor {
private Clutter.Actor window_icon; private Clutter.Actor window_icon;
private Tooltip window_title; private Tooltip window_title;
public WindowClone (WindowManager wm, Meta.Window window, GestureTracker? gesture_tracker, bool overview_mode = false) { 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, overview_mode: overview_mode); Object (
wm: wm,
window: window,
gesture_tracker: gesture_tracker,
monitor_scale_factor: scale,
overview_mode: overview_mode
);
} }
construct { construct {
@ -111,26 +129,6 @@ public class Gala.WindowClone : Clutter.Actor {
add_action (drag_action); 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 = new Tooltip ();
window_title.opacity = 0; window_title.opacity = 0;
@ -138,11 +136,11 @@ public class Gala.WindowClone : Clutter.Actor {
active_shape.opacity = 0; active_shape.opacity = 0;
add_child (active_shape); add_child (active_shape);
add_child (window_icon);
add_child (window_title); add_child (window_title);
add_child (close_button);
load_clone (); load_clone ();
reallocate ();
} }
~WindowClone () { ~WindowClone () {
@ -153,6 +151,31 @@ public class Gala.WindowClone : Clutter.Actor {
window.notify["maximized-vertically"].disconnect (check_shadow_requirements); 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 * 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 * 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 (); unowned var display = window.get_display ();
var monitor_geom = display.get_monitor_geometry (window.get_monitor ()); 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_x = monitor_geom.x;
var offset_y = monitor_geom.y; var offset_y = monitor_geom.y;
@ -267,13 +291,14 @@ public class Gala.WindowClone : Clutter.Actor {
active = false; active = false;
in_slot_animation = true; 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) => { GestureTracker.OnUpdate on_animation_update = (percentage) => {
var x = GestureTracker.animation_value (initial_x, target_x, percentage); var x = GestureTracker.animation_value (initial_x, target_x, percentage);
var y = GestureTracker.animation_value (initial_y, target_y, percentage); var y = GestureTracker.animation_value (initial_y, target_y, percentage);
var width = GestureTracker.animation_value (initial_width, outer_rect.width, percentage); var width = GestureTracker.animation_value (initial_width, outer_rect.width, percentage);
var height = GestureTracker.animation_value (initial_height, outer_rect.height, 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); var opacity = GestureTracker.animation_value (255f, 0f, percentage);
set_size (width, height); set_size (width, height);
@ -281,6 +306,7 @@ public class Gala.WindowClone : Clutter.Actor {
window_icon.opacity = (uint) opacity; window_icon.opacity = (uint) opacity;
set_window_icon_position (width, height, scale, false); set_window_icon_position (width, height, scale, false);
place_widgets ((int)width, (int)height, scale);
shadow_opacity = (uint8) opacity; 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_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
window_icon.set_easing_duration (duration); window_icon.set_easing_duration (duration);
window_icon.opacity = 0; 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 (); window_icon.restore_easing_state ();
var transition = window_icon.get_transition ("opacity"); var transition = window_icon.get_transition ("opacity");
if (transition != null) { if (transition != null) {
transition.completed.connect (() => { transition.completed.connect (() => {
in_slot_animation = false; in_slot_animation = false;
place_widgets (outer_rect.width, outer_rect.height, scale); place_widgets (outer_rect.width, outer_rect.height, target_scale);
}); });
} else { } else {
in_slot_animation = false; 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_duration (duration);
window_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); window_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
unowned var display = wm.get_display (); set_window_icon_position (slot.width, slot.height, monitor_scale_factor);
var scale = display.get_monitor_scale (display.get_monitor_index_for_rect (slot));
set_window_icon_position (slot.width, slot.height, scale);
window_icon.restore_easing_state (); 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) { 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 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); window_title.set_position (x, y);
} }

View File

@ -31,6 +31,19 @@ namespace Gala {
public GestureTracker? gesture_tracker { get; construct; } public GestureTracker? gesture_tracker { get; construct; }
public bool overview_mode { 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; private bool opened = false;
/** /**
@ -39,8 +52,15 @@ namespace Gala {
*/ */
private WindowClone? current_window = null; private WindowClone? current_window = null;
public WindowCloneContainer (WindowManager wm, GestureTracker? gesture_tracker, bool overview_mode = false) { public WindowCloneContainer (WindowManager wm, GestureTracker? gesture_tracker, float scale, bool overview_mode = false) {
Object (wm: wm, gesture_tracker: gesture_tracker, overview_mode: overview_mode); 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 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.selected.connect (window_selected_cb);
new_window.destroy.connect (window_destroyed); 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 = wm.push_modal (this);
modal_proxy.set_keybinding_filter (keybinding_filter); modal_proxy.set_keybinding_filter (keybinding_filter);
for (var i = 0; i < wm.get_display ().get_n_monitors (); i++) { unowned var display = wm.get_display ();
var geometry = wm.get_display ().get_monitor_geometry (i);
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_top = TOP_GAP,
padding_left = BORDER, padding_left = BORDER,
padding_right = BORDER, padding_right = BORDER,

View File

@ -178,7 +178,7 @@ namespace Gala {
background = new FramedBackground (display); background = new FramedBackground (display);
background.add_action (background_click_action); 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.window_selected.connect ((w) => { window_selected (w); });
window_container.set_size (monitor_geometry.width, monitor_geometry.height); window_container.set_size (monitor_geometry.width, monitor_geometry.height);