mirror of
https://github.com/morgan9e/dash-to-panel
synced 2026-04-14 00:04:17 +09:00
Scroll previews using mouse pointer
This commit is contained in:
77
taskbar.js
77
taskbar.js
@@ -41,7 +41,6 @@ const IconGrid = imports.ui.iconGrid;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Util = imports.misc.util;
|
||||
const Workspace = imports.ui.workspace;
|
||||
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
@@ -567,7 +566,7 @@ var taskbar = Utils.defineClass({
|
||||
appIcon.actor.connect('notify::hover', Lang.bind(this, function() {
|
||||
if (appIcon.actor.hover){
|
||||
this._ensureAppIconVisibilityTimeoutId = Mainloop.timeout_add(100, Lang.bind(this, function(){
|
||||
ensureActorVisibleInScrollView(this._scrollView, appIcon.actor);
|
||||
Utils.ensureActorVisibleInScrollView(this._scrollView, appIcon.actor, this._scrollView._dtpFadeSize);
|
||||
this._ensureAppIconVisibilityTimeoutId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
@@ -581,11 +580,11 @@ var taskbar = Utils.defineClass({
|
||||
|
||||
appIcon.actor.connect('clicked',
|
||||
Lang.bind(this, function(actor) {
|
||||
ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
Utils.ensureActorVisibleInScrollView(this._scrollView, actor, this._scrollView._dtpFadeSize);
|
||||
}));
|
||||
|
||||
appIcon.actor.connect('key-focus-in', Lang.bind(this, function(actor) {
|
||||
let [x_shift, y_shift] = ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
let [x_shift, y_shift] = Utils.ensureActorVisibleInScrollView(this._scrollView, actor, this._scrollView._dtpFadeSize);
|
||||
|
||||
// This signal is triggered also by mouse click. The popup menu is opened at the original
|
||||
// coordinates. Thus correct for the shift which is going to be applied to the scrollview.
|
||||
@@ -960,9 +959,9 @@ var taskbar = Utils.defineClass({
|
||||
// Ensure the next and previous icon are visible when moving the icon
|
||||
// (I assume there's room for both of them)
|
||||
if (hoveredIndex > 1)
|
||||
ensureActorVisibleInScrollView(this._scrollView, this._box.get_children()[hoveredIndex-1]);
|
||||
ensureActorVisibleInScrollView(this._scrollView, this._box.get_children()[hoveredIndex-1], this._scrollView._dtpFadeSize);
|
||||
if (hoveredIndex < this._box.get_children().length-1)
|
||||
ensureActorVisibleInScrollView(this._scrollView, this._box.get_children()[hoveredIndex+1]);
|
||||
ensureActorVisibleInScrollView(this._scrollView, this._box.get_children()[hoveredIndex+1], this._scrollView._dtpFadeSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1217,68 +1216,4 @@ function sortWindowsCompareFunction(windowA, windowB) {
|
||||
|
||||
function getWindowStableSequence(window) {
|
||||
return ('_dtpPosition' in window ? window._dtpPosition : window.get_stable_sequence());
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a copy of the same function in utils.js, but also adjust horizontal scrolling
|
||||
* and perform few further cheks on the current value to avoid changing the values when
|
||||
* it would be clamp to the current one in any case.
|
||||
* Return the amount of shift applied
|
||||
*/
|
||||
function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
|
||||
let adjust_v = true;
|
||||
let adjust_h = true;
|
||||
|
||||
let vadjustment = scrollView.vscroll.adjustment;
|
||||
let hadjustment = scrollView.hscroll.adjustment;
|
||||
let [vvalue, vlower, vupper, vstepIncrement, vpageIncrement, vpageSize] = vadjustment.get_values();
|
||||
let [hvalue, hlower, hupper, hstepIncrement, hpageIncrement, hpageSize] = hadjustment.get_values();
|
||||
|
||||
let [hvalue0, vvalue0] = [hvalue, vvalue];
|
||||
|
||||
let voffset = 0;
|
||||
let hoffset = scrollView._dtpFadeSize;
|
||||
|
||||
let box = actor.get_allocation_box();
|
||||
let y1 = box.y1, y2 = box.y2, x1 = box.x1, x2 = box.x2;
|
||||
|
||||
let parent = actor.get_parent();
|
||||
while (parent != scrollView) {
|
||||
if (!parent)
|
||||
throw new Error("actor not in scroll view");
|
||||
|
||||
let box = parent.get_allocation_box();
|
||||
y1 += box.y1;
|
||||
y2 += box.y1;
|
||||
x1 += box.x1;
|
||||
x2 += box.x1;
|
||||
parent = parent.get_parent();
|
||||
}
|
||||
|
||||
if (y1 < vvalue + voffset)
|
||||
vvalue = Math.max(0, y1 - voffset);
|
||||
else if (vvalue < vupper - vpageSize && y2 > vvalue + vpageSize - voffset)
|
||||
vvalue = Math.min(vupper -vpageSize, y2 + voffset - vpageSize);
|
||||
|
||||
if (x1 < hvalue + hoffset)
|
||||
hvalue = Math.max(0, x1 - hoffset);
|
||||
else if (hvalue < hupper - hpageSize && x2 > hvalue + hpageSize - hoffset)
|
||||
hvalue = Math.min(hupper - hpageSize, x2 + hoffset - hpageSize);
|
||||
|
||||
if (vvalue !== vvalue0) {
|
||||
Tweener.addTween(vadjustment,
|
||||
{ value: vvalue,
|
||||
time: Util.SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
|
||||
if (hvalue !== hvalue0) {
|
||||
Tweener.addTween(hadjustment,
|
||||
{ value: hvalue,
|
||||
time: Util.SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
|
||||
return [hvalue- hvalue0, vvalue - vvalue0];
|
||||
}
|
||||
}
|
||||
62
utils.js
62
utils.js
@@ -32,6 +32,8 @@ const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
var TRANSLATION_DOMAIN = imports.misc.extensionUtils.getCurrentExtension().metadata['gettext-domain'];
|
||||
|
||||
@@ -371,6 +373,66 @@ var getrgbaColor = function(color, alpha, offset) {
|
||||
|
||||
return 'rgba(' + rgb.red + ',' + rgb.green + ',' + rgb.blue + ',' + (Math.floor(alpha * 100) * 0.01) + '); ' ;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a copy of the same function in utils.js, but also adjust horizontal scrolling
|
||||
* and perform few further cheks on the current value to avoid changing the values when
|
||||
* it would be clamp to the current one in any case.
|
||||
* Return the amount of shift applied
|
||||
*/
|
||||
var ensureActorVisibleInScrollView = function(scrollView, actor, fadeSize) {
|
||||
let vadjustment = scrollView.vscroll.adjustment;
|
||||
let hadjustment = scrollView.hscroll.adjustment;
|
||||
let [vvalue, vlower, vupper, vstepIncrement, vpageIncrement, vpageSize] = vadjustment.get_values();
|
||||
let [hvalue, hlower, hupper, hstepIncrement, hpageIncrement, hpageSize] = hadjustment.get_values();
|
||||
|
||||
let [hvalue0, vvalue0] = [hvalue, vvalue];
|
||||
|
||||
let voffset = fadeSize;
|
||||
let hoffset = fadeSize;
|
||||
|
||||
let box = actor.get_allocation_box();
|
||||
let y1 = box.y1, y2 = box.y2, x1 = box.x1, x2 = box.x2;
|
||||
|
||||
let parent = actor.get_parent();
|
||||
while (parent != scrollView) {
|
||||
if (!parent)
|
||||
throw new Error("actor not in scroll view");
|
||||
|
||||
let box = parent.get_allocation_box();
|
||||
y1 += box.y1;
|
||||
y2 += box.y1;
|
||||
x1 += box.x1;
|
||||
x2 += box.x1;
|
||||
parent = parent.get_parent();
|
||||
}
|
||||
|
||||
if (y1 < vvalue + voffset)
|
||||
vvalue = Math.max(0, y1 - voffset);
|
||||
else if (vvalue < vupper - vpageSize && y2 > vvalue + vpageSize - voffset)
|
||||
vvalue = Math.min(vupper -vpageSize, y2 + voffset - vpageSize);
|
||||
|
||||
if (x1 < hvalue + hoffset)
|
||||
hvalue = Math.max(0, x1 - hoffset);
|
||||
else if (hvalue < hupper - hpageSize && x2 > hvalue + hpageSize - hoffset)
|
||||
hvalue = Math.min(hupper - hpageSize, x2 + hoffset - hpageSize);
|
||||
|
||||
if (vvalue !== vvalue0) {
|
||||
Tweener.addTween(vadjustment,
|
||||
{ value: vvalue,
|
||||
time: Util.SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
|
||||
if (hvalue !== hvalue0) {
|
||||
Tweener.addTween(hadjustment,
|
||||
{ value: hvalue,
|
||||
time: Util.SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
|
||||
return [hvalue- hvalue0, vvalue - vvalue0];
|
||||
}
|
||||
|
||||
/**
|
||||
* ColorUtils is adapted from https://github.com/micheleg/dash-to-dock
|
||||
|
||||
@@ -33,10 +33,14 @@ const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const Taskbar = Me.imports.taskbar;
|
||||
const Utils = Me.imports.utils;
|
||||
|
||||
//timeout intervals
|
||||
const ENSURE_VISIBLE_MS = 200;
|
||||
|
||||
//timeout names
|
||||
const T1 = 'openMenuTimeout';
|
||||
const T2 = 'closeMenuTimeout';
|
||||
const T3 = 'peekTimeout';
|
||||
const T4 = 'ensureVisibleTimeout';
|
||||
|
||||
const MAX_TRANSLATION = 40;
|
||||
const HEADER_HEIGHT = 38;
|
||||
@@ -69,8 +73,8 @@ var PreviewMenu = Utils.defineClass({
|
||||
this.peekInitialWorkspaceIndex = -1;
|
||||
this.opened = false;
|
||||
this._position = Taskbar.getPosition();
|
||||
let isLeftOrRight = this._checkIfLeftOrRight();
|
||||
this._translationProp = 'translation_' + (isLeftOrRight ? 'x' : 'y');
|
||||
this.isLeftOrRight = this._position == St.Side.LEFT || this._position == St.Side.RIGHT;
|
||||
this._translationProp = 'translation_' + (this.isLeftOrRight ? 'x' : 'y');
|
||||
this._translationDirection = (this._position == St.Side.TOP || this._position == St.Side.LEFT ? -1 : 1);
|
||||
this._translationOffset = Math.min(this._dtpSettings.get_int('panel-size'), MAX_TRANSLATION) * this._translationDirection;
|
||||
|
||||
@@ -82,14 +86,12 @@ var PreviewMenu = Utils.defineClass({
|
||||
y_expand: true,
|
||||
y_align: Clutter.ActorAlign[this._translationDirection > 0 ? 'END' : 'START']
|
||||
});
|
||||
this._box = new St.BoxLayout({ vertical: isLeftOrRight });
|
||||
this._box = new St.BoxLayout({ vertical: this.isLeftOrRight });
|
||||
this._scrollView = new St.ScrollView({
|
||||
name: 'dashtopanelPreviewScrollview',
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
vscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
enable_mouse_scrolling: true,
|
||||
y_expand: !isLeftOrRight,
|
||||
x_expand: isLeftOrRight
|
||||
enable_mouse_scrolling: true
|
||||
});
|
||||
|
||||
this._scrollView.add_actor(this._box);
|
||||
@@ -251,6 +253,18 @@ var PreviewMenu = Utils.defineClass({
|
||||
this._endPeek(true);
|
||||
},
|
||||
|
||||
ensureVisible: function(preview) {
|
||||
let [ , , upper, , , pageSize] = this._scrollView[this.isLeftOrRight ? 'v' : 'h' + 'scroll'].adjustment.get_values();
|
||||
|
||||
if (upper > pageSize) {
|
||||
this._timeoutsHandler.add([
|
||||
T4,
|
||||
ENSURE_VISIBLE_MS,
|
||||
() => Utils.ensureActorVisibleInScrollView(this._scrollView, preview, MIN_DIMENSION)
|
||||
]);
|
||||
}
|
||||
},
|
||||
|
||||
_setReactive: function(reactive) {
|
||||
this._box.get_children().forEach(c => c.reactive = reactive);
|
||||
this.menu.reactive = reactive;
|
||||
@@ -337,7 +351,7 @@ var PreviewMenu = Utils.defineClass({
|
||||
|
||||
_onScrollEvent: function(actor, event) {
|
||||
if (!event.is_pointer_emulated()) {
|
||||
let vOrh = this._checkIfLeftOrRight() ? 'v' : 'h';
|
||||
let vOrh = this.isLeftOrRight ? 'v' : 'h';
|
||||
let adjustment = this._scrollView['get_' + vOrh + 'scroll_bar']().get_adjustment();
|
||||
let increment = adjustment.step_increment;
|
||||
let delta = increment;
|
||||
@@ -362,6 +376,7 @@ var PreviewMenu = Utils.defineClass({
|
||||
_endOpenCloseTimeouts: function() {
|
||||
this._timeoutsHandler.remove(T1);
|
||||
this._timeoutsHandler.remove(T2);
|
||||
this._timeoutsHandler.remove(T4);
|
||||
},
|
||||
|
||||
_refreshGlobals: function() {
|
||||
@@ -401,7 +416,7 @@ var PreviewMenu = Utils.defineClass({
|
||||
let previewSize = (this._dtpSettings.get_int('window-preview-size') +
|
||||
this._dtpSettings.get_int('window-preview-padding') * 2) * scaleFactor;
|
||||
|
||||
if (this._checkIfLeftOrRight()) {
|
||||
if (this.isLeftOrRight) {
|
||||
w = previewSize;
|
||||
h = this._panelWrapper.monitor.height;
|
||||
y = this._panelWrapper.monitor.y;
|
||||
@@ -437,7 +452,7 @@ var PreviewMenu = Utils.defineClass({
|
||||
previewsWidth = Math.min(previewsWidth, this._panelWrapper.monitor.width);
|
||||
previewsHeight = Math.min(previewsHeight, this._panelWrapper.monitor.height) + headerHeight;
|
||||
|
||||
if (this._checkIfLeftOrRight()) {
|
||||
if (this.isLeftOrRight) {
|
||||
y = sourceAllocation.y1 + appIconMargin - this._panelWrapper.monitor.y + (sourceContentBox.y2 - sourceContentBox.y1 - previewsHeight) * .5;
|
||||
y = Math.max(y, 0);
|
||||
y = Math.min(y, this._panelWrapper.monitor.height - previewsHeight);
|
||||
@@ -463,7 +478,7 @@ var PreviewMenu = Utils.defineClass({
|
||||
if (!c.animatingOut) {
|
||||
let [width, height] = c.getSize();
|
||||
|
||||
if (this._checkIfLeftOrRight()) {
|
||||
if (this.isLeftOrRight) {
|
||||
previewsWidth = Math.max(width, previewsWidth);
|
||||
previewsHeight += height;
|
||||
} else {
|
||||
@@ -495,10 +510,6 @@ var PreviewMenu = Utils.defineClass({
|
||||
Tweener.addTween(this.menu, getTweenOpts(tweenOpts));
|
||||
},
|
||||
|
||||
_checkIfLeftOrRight: function() {
|
||||
return this._position == St.Side.LEFT || this._position == St.Side.RIGHT;
|
||||
},
|
||||
|
||||
_peek: function(window) {
|
||||
let currentWorkspace = Utils.getCurrentWorkspace();
|
||||
let windowWorkspace = window.get_workspace();
|
||||
@@ -746,6 +757,7 @@ var Preview = Utils.defineClass({
|
||||
this.set_style(this._getBackgroundColor(FOCUSED_COLOR_OFFSET, focused ? '-' : 0));
|
||||
|
||||
if (focused) {
|
||||
this._previewMenu.ensureVisible(this);
|
||||
this._previewMenu.requestPeek(this.window);
|
||||
}
|
||||
},
|
||||
@@ -954,7 +966,7 @@ var Preview = Utils.defineClass({
|
||||
let size = this._previewMenu._dtpSettings.get_int('window-preview-size') * scaleFactor;
|
||||
let w, h;
|
||||
|
||||
if (this._previewMenu._checkIfLeftOrRight()) {
|
||||
if (this._previewMenu.isLeftOrRight) {
|
||||
w = size;
|
||||
h = w * aspectRatio.y.size / aspectRatio.x.size;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user