Merge branch 'custom-window-preview'

This commit is contained in:
Charles Gagnon
2019-06-22 17:44:38 -04:00
13 changed files with 2505 additions and 2131 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,6 @@ const Workspace = imports.ui.workspace;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Utils = Me.imports.utils;
const WindowPreview = Me.imports.windowPreview;
const Taskbar = Me.imports.taskbar;
const _ = imports.gettext.domain(Utils.TRANSLATION_DOMAIN).gettext;
@@ -99,7 +98,7 @@ var taskbarAppIcon = Utils.defineClass({
Extends: AppDisplay.AppIcon,
ParentConstrParams: [[1, 'app'], [3]],
_init: function(settings, appInfo, panelWrapper, iconParams) {
_init: function(settings, appInfo, panelWrapper, iconParams, previewMenu) {
// a prefix is required to avoid conflicting with the parent class variable
this._dtpSettings = settings;
@@ -107,6 +106,7 @@ var taskbarAppIcon = Utils.defineClass({
this._nWindows = 0;
this.window = appInfo.window;
this.isLauncher = appInfo.isLauncher;
this._previewMenu = previewMenu;
// Fix touchscreen issues before the listener is added by the parent constructor.
this._onTouchEvent = function(actor, event) {
@@ -183,11 +183,9 @@ var taskbarAppIcon = Utils.defineClass({
Lang.bind(this, this._onFocusAppChanged));
this._windowEnteredMonitorId = this._windowLeftMonitorId = 0;
this._stateChangedId = this.app.connect('windows-changed', Lang.bind(this, this.onWindowsChanged));
if (!this.window) {
this._stateChangedId = this.app.connect('windows-changed',
Lang.bind(this, this.onWindowsChanged));
if (this._dtpSettings.get_boolean('isolate-monitors')) {
this._windowEnteredMonitorId = Utils.DisplayWrapper.getScreen().connect('window-entered-monitor', this.onWindowEnteredOrLeft.bind(this));
this._windowLeftMonitorId = Utils.DisplayWrapper.getScreen().connect('window-left-monitor', this.onWindowEnteredOrLeft.bind(this));
@@ -204,6 +202,8 @@ var taskbarAppIcon = Utils.defineClass({
this._switchWorkspaceId = global.window_manager.connect('switch-workspace',
Lang.bind(this, this._onSwitchWorkspace));
this._hoverChangeId = this.actor.connect('notify::hover', () => this._onAppIconHoverChanged());
this._dtpSettingsSignalIds = [
this._dtpSettings.connect('changed::dot-position', Lang.bind(this, this._settingsChangeRefresh)),
@@ -236,93 +236,6 @@ var taskbarAppIcon = Utils.defineClass({
this.forcedOverview = false;
this._numberOverlay();
this._signalsHandler = new Utils.GlobalSignalsHandler();
},
_createWindowPreview: function() {
// Abort if already activated
if (this.menuManagerWindowPreview)
return;
// Creating a new menu manager for window previews as adding it to the
// using the secondary menu's menu manager (which uses the "ignoreRelease"
// function) caused the extension to crash.
this.menuManagerWindowPreview = new PopupMenu.PopupMenuManager(this);
this.windowPreview = new WindowPreview.thumbnailPreviewMenu(this, this._dtpSettings, this.menuManagerWindowPreview);
this.windowPreview.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
if (!isPoppedUp)
this._onMenuPoppedDown();
}));
this.menuManagerWindowPreview.addMenu(this.windowPreview);
// grabHelper.grab() is usually called when the menu is opened. However, there seems to be a bug in the
// underlying gnome-shell that causes all window contents to freeze if the grab and ungrab occur
// in quick succession in timeouts from the Mainloop (for example, clicking the icon as the preview window is opening)
// So, instead wait until the mouse is leaving the icon (and might be moving toward the open window) to trigger the grab
// in windowPreview.js
let windowPreviewMenuData = this.menuManagerWindowPreview._menus[this.menuManagerWindowPreview._findMenu(this.windowPreview)];
this.windowPreview.disconnect(windowPreviewMenuData.openStateChangeId);
windowPreviewMenuData.openStateChangeId = this.windowPreview.connect('open-state-changed', Lang.bind(this.menuManagerWindowPreview, function(menu, open) {
if (open) {
if (this.activeMenu)
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
// don't grab here, we are grabbing in onLeave in windowPreview.js
//this._grabHelper.grab({ actor: menu.actor, focus: menu.sourceActor, onUngrab: Lang.bind(this, this._closeMenu, menu) });
} else {
this._grabHelper.ungrab({ actor: menu.actor });
}
}));
},
enableWindowPreview: function(appIcons) {
this._createWindowPreview();
// We first remove to ensure there are no duplicates
this._signalsHandler.removeWithLabel('window-preview');
this._signalsHandler.addWithLabel('window-preview', [
this.windowPreview,
'menu-closed',
// enter-event doesn't fire on an app icon when the popup menu from a previously
// hovered app icon is still open, so when a preview menu closes we need to
// see if a new app icon is hovered and open its preview menu now.
// also, for some reason actor doesn't report being hovered by get_hover()
// if the hover started when a popup was opened. So, look for the actor by mouse position.
menu => this.syncWindowPreview(appIcons, menu)
]);
this.windowPreview.enableWindowPreview();
},
syncWindowPreview: function(appIcons, menu) {
let [x, y,] = global.get_pointer();
let hoveredActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
let appIconToOpen;
appIcons.forEach(function (appIcon) {
if(appIcon.actor == hoveredActor) {
appIconToOpen = appIcon;
} else if(appIcon.windowPreview && appIcon.windowPreview.isOpen) {
appIcon.windowPreview.close();
}
});
if(appIconToOpen) {
appIconToOpen.actor.sync_hover();
if(appIconToOpen.windowPreview && appIconToOpen.windowPreview != menu)
appIconToOpen.windowPreview._onEnter();
}
return GLib.SOURCE_REMOVE;
},
disableWindowPreview: function() {
this._signalsHandler.removeWithLabel('window-preview');
if (this.windowPreview)
this.windowPreview.disableWindowPreview();
},
shouldShowTooltip: function() {
@@ -333,7 +246,20 @@ var taskbarAppIcon = Utils.defineClass({
} else {
return this.actor.hover && !this.window &&
(!this._menu || !this._menu.isOpen) &&
(!this.windowPreview || !this.windowPreview.isOpen);
(this._previewMenu.getCurrentAppIcon() !== this);
}
},
_onAppIconHoverChanged: function() {
if (!this._dtpSettings.get_boolean('show-window-previews') ||
(!this.window && !this._nWindows)) {
return;
}
if (this.actor.hover) {
this._previewMenu.requestOpen(this);
} else {
this._previewMenu.requestClose();
}
},
@@ -341,6 +267,8 @@ var taskbarAppIcon = Utils.defineClass({
this.callParent('_onDestroy');
this._destroyed = true;
this._previewMenu.close(true);
// Disconect global signals
// stateChangedId is already handled by parent)
@@ -364,19 +292,23 @@ var taskbarAppIcon = Utils.defineClass({
if(this._scaleFactorChangedId)
St.ThemeContext.get_for_stage(global.stage).disconnect(this._scaleFactorChangedId);
if (this._hoverChangeId) {
this.actor.disconnect(this._hoverChangeId);
}
for (let i = 0; i < this._dtpSettingsSignalIds.length; ++i) {
this._dtpSettings.disconnect(this._dtpSettingsSignalIds[i]);
}
},
onWindowsChanged: function() {
this._updateCounterClass();
this._updateWindows();
this.updateIcon();
},
onWindowEnteredOrLeft: function() {
if (this._checkIfFocusedApp()) {
this._updateCounterClass();
this._updateWindows();
this._displayProperIndicator();
}
},
@@ -405,7 +337,7 @@ var taskbarAppIcon = Utils.defineClass({
_showDots: function() {
// Just update style if dots already exist
if (this._focusedDots && this._unfocusedDots) {
this._updateCounterClass();
this._updateWindows();
return;
}
@@ -449,7 +381,7 @@ var taskbarAppIcon = Utils.defineClass({
this._dotsContainer.add_child(this._unfocusedDots);
this._updateCounterClass();
this._updateWindows();
}
this._dotsContainer.add_child(this._focusedDots);
@@ -465,7 +397,7 @@ var taskbarAppIcon = Utils.defineClass({
_settingsChangeRefresh: function() {
if (this._isGroupApps) {
this._updateCounterClass();
this._updateWindows();
this._focusedDots.queue_repaint();
this._unfocusedDots.queue_repaint();
}
@@ -588,8 +520,7 @@ var taskbarAppIcon = Utils.defineClass({
this.emit('menu-state-changed', true);
if (this.windowPreview)
this.windowPreview.close();
this._previewMenu.close(true);
this.actor.set_hover(true);
this._menu.actor.add_style_class_name('dashtopanelSecondaryMenu');
@@ -612,10 +543,7 @@ var taskbarAppIcon = Utils.defineClass({
},
_onSwitchWorkspace: function(windowTracker) {
Mainloop.timeout_add(0, Lang.bind(this, function () {
this._displayProperIndicator();
return GLib.SOURCE_REMOVE;
}));
this._displayProperIndicator();
},
_displayProperIndicator: function (force) {
@@ -774,8 +702,8 @@ var taskbarAppIcon = Utils.defineClass({
}
let appCount = this.getAppIconInterestingWindows().length;
if (this.windowPreview && (!(buttonAction == "TOGGLE-SHOWPREVIEW") || (appCount <= 1)))
this.windowPreview.requestCloseMenu();
if (!(buttonAction == "TOGGLE-SHOWPREVIEW") || (appCount <= 1))
this._previewMenu.close(true);
// We check if the app is running, and that the # of windows is > 0 in
// case we use workspace isolation,
@@ -922,16 +850,24 @@ var taskbarAppIcon = Utils.defineClass({
}
},
_updateCounterClass: function() {
this._nWindows = this.getAppIconInterestingWindows().length;
for (let i = 1; i <= MAX_INDICATORS; i++){
let className = 'running'+i;
if(i != this._nWindows)
this.actor.remove_style_class_name(className);
else
this.actor.add_style_class_name(className);
_updateWindows: function() {
let windows = [this.window];
if (!this.window) {
windows = this.getAppIconInterestingWindows();
this._nWindows = windows.length;
for (let i = 1; i <= MAX_INDICATORS; i++){
let className = 'running'+i;
if(i != this._nWindows)
this.actor.remove_style_class_name(className);
else
this.actor.add_style_class_name(className);
}
}
this._previewMenu.update(this, windows);
},
_getRunningIndicatorCount: function() {
@@ -1149,7 +1085,7 @@ var taskbarAppIcon = Utils.defineClass({
handleDragOver: function(source, actor, x, y, time) {
if (source == Main.xdndHandler) {
this.windowPreview.close();
this._previewMenu.close(true);
}
return DND.DragMotionResult.CONTINUE;

View File

@@ -187,10 +187,12 @@ var Intellihide = Utils.defineClass({
[
this._panelBox,
'notify::hover',
() => {
this._hoveredOut = !this._panelBox.hover;
this._queueUpdatePanelPosition();
}
() => this._onHoverChanged()
],
[
this._dtpPanel.taskbar.previewMenu,
'open-state-changed',
() => this._queueUpdatePanelPosition()
],
[
Main.overview,
@@ -203,6 +205,11 @@ var Intellihide = Utils.defineClass({
);
},
_onHoverChanged: function() {
this._hoveredOut = !this._panelBox.hover;
this._queueUpdatePanelPosition();
},
_setTrackPanel: function(reset, enable) {
if (!reset) {
Main.layoutManager._untrackActor(this._panelBox);
@@ -291,7 +298,8 @@ var Intellihide = Utils.defineClass({
},
_checkIfShouldBeVisible: function(fromRevealMechanism) {
if (Main.overview.visibleTarget || this._checkIfGrab() || this._panelBox.get_hover()) {
if (Main.overview.visibleTarget || this._dtpPanel.taskbar.previewMenu.opened ||
this._panelBox.get_hover() || this._checkIfGrab()) {
return true;
}

View File

@@ -42,6 +42,7 @@ var dtpOverview = Utils.defineClass({
_init: function(settings) {
this._numHotkeys = 10;
this._currentHotkeyFocusIndex = -1;
this._dtpSettings = settings;
},
@@ -179,56 +180,34 @@ var dtpOverview = Utils.defineClass({
if (appIndex < apps.length) {
let appIcon = apps[appIndex];
let windowCount = !appIcon.window ? appIcon._nWindows : seenApps[appIcon.app];
let seenAppCount = seenApps[appIcon.app];
let windowCount = appIcon.window || appIcon._hotkeysCycle ? seenAppCount : appIcon._nWindows;
if (this._dtpSettings.get_boolean('shortcut-previews') && windowCount > 1) {
let windowIndex = 0;
let currentWindow = appIcon.window;
let hotkeyPrefix = this._dtpSettings.get_string('hotkey-prefix-text');
let shortcutKeys = (hotkeyPrefix == 'Super' ? [Clutter.Super_L] : [Clutter.Super_L, Clutter.Alt_L]).concat([Clutter['KEY_' + (appIndex + 1)]]);
let currentKeys = shortcutKeys.slice();
let setFocus = windowIndex => global.stage.set_key_focus(appIcon.windowPreview._previewBox.box.get_children()[windowIndex]);
let capturedEventId = global.stage.connect('captured-event', (actor, event) => {
if (event.type() == Clutter.EventType.KEY_PRESS) {
let pressedKey = event.get_key_symbol();
if (this._currentHotkeyFocusIndex < 0) {
let currentWindow = appIcon.window;
let keyFocusOutId = appIcon.actor.connect('key-focus-out', () => appIcon.actor.grab_key_focus());
let capturedEventId = global.stage.connect('captured-event', (actor, e) => {
if (e.type() == Clutter.EventType.KEY_RELEASE && e.get_key_symbol() == Clutter.Super_L) {
global.stage.disconnect(capturedEventId);
appIcon.actor.disconnect(keyFocusOutId);
if (shortcutKeys.indexOf(pressedKey) >= 0 && currentKeys.indexOf(pressedKey) < 0) {
currentKeys.push(pressedKey);
if (shortcutKeys.length === currentKeys.length) {
windowIndex = windowIndex < windowCount - 1 ? windowIndex + 1 : 0;
setFocus(windowIndex);
}
}
} else if (event.type() == Clutter.EventType.KEY_RELEASE) {
let releasedKey = event.get_key_symbol();
let keyIndex = currentKeys.indexOf(releasedKey);
if (releasedKey == Clutter.Super_L) {
let thumbnails = appIcon.windowPreview._previewBox.box.get_children();
let focusedThumbnail = thumbnails.filter(c => c.has_key_focus())[0];
focusedThumbnail._delegate.activate();
} else if (keyIndex >= 0) {
currentKeys.splice(keyIndex, 1);
appIcon._previewMenu.activateFocused();
appIcon.window = currentWindow;
delete appIcon._hotkeysCycle;
this._currentHotkeyFocusIndex = -1;
}
}
return Clutter.EVENT_PROPAGATE;
});
return Clutter.EVENT_PROPAGATE;
});
let hotkeyOpenStateChangedId = appIcon.windowPreview.connect('open-state-changed', (menu, isOpen) => {
if (!isOpen) {
global.stage.disconnect(capturedEventId);
appIcon.windowPreview.disconnect(hotkeyOpenStateChangedId);
appIcon.windowPreview._previewBox._resetPreviews();
appIcon.window = currentWindow;
}
});
appIcon.window = null;
appIcon.windowPreview.popup();
appIcon.menuManagerWindowPreview._onMenuOpenState(appIcon.windowPreview, true);
setFocus(windowIndex);
appIcon._hotkeysCycle = appIcon.window;
appIcon.window = null;
appIcon._previewMenu.open(appIcon);
appIcon.actor.grab_key_focus();
}
this._currentHotkeyFocusIndex = appIcon._previewMenu.focusNext();
} else {
// Activate with button = 1, i.e. same as left click
let button = 1;

View File

@@ -161,6 +161,7 @@ var dtpPanelWrapper = Utils.defineClass({
//the timeout makes sure the theme's styles are computed before initially applying the transparency
this.startDynamicTransparencyId = Mainloop.timeout_add(0, () => {
this.startDynamicTransparencyId = 0;
this.dynamicTransparency = new Transparency.DynamicTransparency(this);
});
@@ -269,7 +270,6 @@ var dtpPanelWrapper = Utils.defineClass({
this._setAppmenuVisible(false);
if(this.appMenu)
this.panel._leftBox.add_child(this.appMenu.container);
this.taskbar.destroy();
if (this.startIntellihideId) {
Mainloop.source_remove(this.startIntellihideId);
@@ -290,6 +290,8 @@ var dtpPanelWrapper = Utils.defineClass({
this.dynamicTransparency.destroy();
}
this.taskbar.destroy();
// reset stored icon size to the default dash
Main.overview.dashIconSize = Main.overview._controls.dash.iconSize;

View File

@@ -283,7 +283,7 @@ var dtpPanelManager = Utils.defineClass({
},
_getBoxPointerPreferredHeight: function(boxPointer, alloc, monitor) {
if (boxPointer._dtpInPanel && this._dtpSettings.get_boolean('intellihide')) {
if (boxPointer._dtpInPanel && boxPointer.sourceActor && this._dtpSettings.get_boolean('intellihide')) {
monitor = monitor || Main.layoutManager.findMonitorForActor(boxPointer.sourceActor);
let excess = alloc.natural_size + this._dtpSettings.get_int('panel-size') + 10 - monitor.height; // 10 is arbitrary
@@ -387,7 +387,7 @@ var dtpPanelManager = Utils.defineClass({
},
_newGetShowAppsButton: function() {
let focusedMonitorIndex = Taskbar.findIndex(this.allPanels, p => this.checkIfFocusedMonitor(p.monitor));
let focusedMonitorIndex = Utils.findIndex(this.allPanels, p => this.checkIfFocusedMonitor(p.monitor));
return this.allPanels[focusedMonitorIndex].taskbar.showAppsButton;
},

209
prefs.js
View File

@@ -990,6 +990,22 @@ const Settings = new Lang.Class({
'active',
Gio.SettingsBindFlags.DEFAULT);
switch (this._settings.get_string('window-preview-title-position')) {
case 'BOTTOM':
this._builder.get_object('preview_title_position_bottom_button').set_active(true);
break;
case 'TOP':
this._builder.get_object('preview_title_position_top_button').set_active(true);
break;
}
this._builder.get_object('grid_preview_title_font_color_colorbutton').connect('notify::color', Lang.bind(this, function (button) {
let rgba = button.get_rgba();
let css = rgba.to_string();
let hexString = cssHexString(css);
this._settings.set_string('window-preview-title-font-color', hexString);
}));
this._builder.get_object('show_window_previews_button').connect('clicked', Lang.bind(this, function() {
let dialog = new Gtk.Dialog({ title: _('Window preview options'),
@@ -1001,55 +1017,109 @@ const Settings = new Lang.Class({
// Use +1 for the reset action
dialog.add_button(_('Reset to defaults'), 1);
let box = this._builder.get_object('box_window_preview_options');
dialog.get_content_area().add(box);
let scrolledWindow = this._builder.get_object('box_window_preview_options');
adjustScrollableHeight(this._builder.get_object('viewport_window_preview_options'), scrolledWindow);
dialog.get_content_area().add(scrolledWindow);
this._builder.get_object('preview_timeout_spinbutton').set_value(this._settings.get_int('show-window-previews-timeout'));
this._builder.get_object('preview_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('show-window-previews-timeout', widget.get_value());
}));
this._settings.bind('peek-mode',
this._builder.get_object('peek_mode_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('preview_show_title_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('peek-mode',
this._builder.get_object('listboxrow_enter_peek_mode_timeout'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('peek-mode',
this._builder.get_object('listboxrow_peek_mode_opacity'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('preview-middle-click-close',
this._builder.get_object('preview_middle_click_close_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('enter_peek_mode_timeout_spinbutton').set_value(this._settings.get_int('enter-peek-mode-timeout'));
this._settings.bind('window-preview-fixed-x',
this._builder.get_object('preview_aspect_ratio_x_fixed_togglebutton'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-fixed-y',
this._builder.get_object('preview_aspect_ratio_y_fixed_togglebutton'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('preview-use-custom-opacity',
this._builder.get_object('preview_custom_opacity_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('preview-use-custom-opacity',
this._builder.get_object('preview_custom_opacity_spinbutton'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('preview_custom_opacity_spinbutton').set_value(this._settings.get_int('preview-custom-opacity'));
this._builder.get_object('preview_custom_opacity_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('preview-custom-opacity', widget.get_value());
}));
this._settings.bind('peek-mode',
this._builder.get_object('peek_mode_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('peek-mode',
this._builder.get_object('grid_enter_peek_mode_timeout'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('peek-mode',
this._builder.get_object('grid_peek_mode_opacity'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('preview_show_title_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('grid_preview_title_size'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('grid_preview_title_weight'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._settings.bind('window-preview-show-title',
this._builder.get_object('grid_preview_title_font_color'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
this._builder.get_object('enter_peek_mode_timeout_spinbutton').set_value(this._settings.get_int('enter-peek-mode-timeout'));
this._builder.get_object('enter_peek_mode_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('enter-peek-mode-timeout', widget.get_value());
}));
this._builder.get_object('peek_mode_opacity_spinbutton').set_value(this._settings.get_int('peek-mode-opacity'));
this._builder.get_object('leave_timeout_spinbutton').set_value(this._settings.get_int('leave-timeout'));
this._builder.get_object('leave_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('leave-timeout', widget.get_value());
}));
this._builder.get_object('animation_time_spinbutton').set_value(this._settings.get_int('window-preview-animation-time'));
this._builder.get_object('animation_time_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-animation-time', widget.get_value());
}));
this._builder.get_object('peek_mode_opacity_spinbutton').set_value(this._settings.get_int('peek-mode-opacity'));
this._builder.get_object('peek_mode_opacity_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('peek-mode-opacity', widget.get_value());
}));
this._builder.get_object('preview_width_spinbutton').set_value(this._settings.get_int('window-preview-width'));
this._builder.get_object('preview_width_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-width', widget.get_value());
this._builder.get_object('preview_size_spinbutton').set_value(this._settings.get_int('window-preview-size'));
this._builder.get_object('preview_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-size', widget.get_value());
}));
this._builder.get_object('preview_height_spinbutton').set_value(this._settings.get_int('window-preview-height'));
this._builder.get_object('preview_height_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-height', widget.get_value());
this._builder.get_object('preview_aspect_ratio_x_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-x').toString());
this._builder.get_object('preview_aspect_ratio_x_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-aspect-ratio-x', parseInt(widget.get_active_id(), 10));
}));
this._builder.get_object('preview_aspect_ratio_y_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-y').toString());
this._builder.get_object('preview_aspect_ratio_y_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-aspect-ratio-y', parseInt(widget.get_active_id(), 10));
}));
this._builder.get_object('preview_padding_spinbutton').set_value(this._settings.get_int('window-preview-padding'));
@@ -1057,12 +1127,39 @@ const Settings = new Lang.Class({
this._settings.set_int('window-preview-padding', widget.get_value());
}));
this._builder.get_object('preview_title_size_spinbutton').set_value(this._settings.get_int('window-preview-title-font-size'));
this._builder.get_object('preview_title_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('window-preview-title-font-size', widget.get_value());
}));
this._builder.get_object('grid_preview_title_weight_combo').set_active_id(this._settings.get_string('window-preview-title-font-weight'));
this._builder.get_object('grid_preview_title_weight_combo').connect('changed', Lang.bind (this, function(widget) {
this._settings.set_string('window-preview-title-font-weight', widget.get_active_id());
}));
(function() {
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('window-preview-title-font-color'));
this._builder.get_object('grid_preview_title_font_color_colorbutton').set_rgba(rgba);
}).apply(this);
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('show-window-previews-timeout', this._settings.get_default_value('show-window-previews-timeout'));
this._builder.get_object('preview_timeout_spinbutton').set_value(this._settings.get_int('show-window-previews-timeout'));
this._settings.set_value('leave-timeout', this._settings.get_default_value('leave-timeout'));
this._builder.get_object('leave_timeout_spinbutton').set_value(this._settings.get_int('leave-timeout'));
this._settings.set_value('window-preview-animation-time', this._settings.get_default_value('window-preview-animation-time'));
this._builder.get_object('animation_time_spinbutton').set_value(this._settings.get_int('window-preview-animation-time'));
this._settings.set_value('preview-use-custom-opacity', this._settings.get_default_value('preview-use-custom-opacity'));
this._settings.set_value('preview-custom-opacity', this._settings.get_default_value('preview-custom-opacity'));
this._builder.get_object('preview_custom_opacity_spinbutton').set_value(this._settings.get_int('preview-custom-opacity'));
this._settings.set_value('peek-mode', this._settings.get_default_value('peek-mode'));
this._settings.set_value('window-preview-show-title', this._settings.get_default_value('window-preview-show-title'));
this._settings.set_value('enter-peek-mode-timeout', this._settings.get_default_value('enter-peek-mode-timeout'));
@@ -1070,20 +1167,37 @@ const Settings = new Lang.Class({
this._settings.set_value('peek-mode-opacity', this._settings.get_default_value('peek-mode-opacity'));
this._builder.get_object('peek_mode_opacity_spinbutton').set_value(this._settings.get_int('peek-mode-opacity'));
this._settings.set_value('window-preview-width', this._settings.get_default_value('window-preview-width'));
this._builder.get_object('preview_width_spinbutton').set_value(this._settings.get_int('window-preview-width'));
this._settings.set_value('window-preview-height', this._settings.get_default_value('window-preview-height'));
this._builder.get_object('preview_height_spinbutton').set_value(this._settings.get_int('window-preview-height'));
this._settings.set_value('window-preview-size', this._settings.get_default_value('window-preview-size'));
this._builder.get_object('preview_size_spinbutton').set_value(this._settings.get_int('window-preview-size'));
this._settings.set_value('window-preview-fixed-x', this._settings.get_default_value('window-preview-fixed-x'));
this._settings.set_value('window-preview-fixed-y', this._settings.get_default_value('window-preview-fixed-y'));
this._settings.set_value('window-preview-aspect-ratio-x', this._settings.get_default_value('window-preview-aspect-ratio-x'));
this._builder.get_object('preview_aspect_ratio_x_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-x').toString());
this._settings.set_value('window-preview-aspect-ratio-y', this._settings.get_default_value('window-preview-aspect-ratio-y'));
this._builder.get_object('preview_aspect_ratio_y_combo').set_active_id(this._settings.get_int('window-preview-aspect-ratio-y').toString());
this._settings.set_value('window-preview-padding', this._settings.get_default_value('window-preview-padding'));
this._builder.get_object('preview_padding_spinbutton').set_value(this._settings.get_int('window-preview-padding'));
this._settings.set_value('preview-middle-click-close', this._settings.get_default_value('preview-middle-click-close'));
this._settings.set_value('window-preview-title-font-size', this._settings.get_default_value('window-preview-title-font-size'));
this._builder.get_object('preview_title_size_spinbutton').set_value(this._settings.get_int('window-preview-title-font-size'));
this._settings.set_value('window-preview-title-font-weight', this._settings.get_default_value('window-preview-title-font-weight'));
this._builder.get_object('grid_preview_title_weight_combo').set_active_id(this._settings.get_string('window-preview-title-font-weight'));
this._settings.set_value('window-preview-title-font-color', this._settings.get_default_value('window-preview-title-font-color'));
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('window-preview-title-font-color'));
this._builder.get_object('grid_preview_title_font_color_colorbutton').set_rgba(rgba);
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
dialog.get_content_area().remove(scrolledWindow);
dialog.destroy();
}
return;
@@ -1414,17 +1528,10 @@ const Settings = new Lang.Class({
let box = this._builder.get_object('box_advanced_options');
dialog.get_content_area().add(box);
this._builder.get_object('leave_timeout_spinbutton').set_value(this._settings.get_int('leave-timeout'));
this._builder.get_object('leave_timeout_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
this._settings.set_int('leave-timeout', widget.get_value());
}));
dialog.connect('response', Lang.bind(this, function(dialog, id) {
if (id == 1) {
// restore default settings
this._settings.set_value('leave-timeout', this._settings.get_default_value('leave-timeout'));
this._builder.get_object('leave_timeout_spinbutton').set_value(this._settings.get_int('leave-timeout'));
} else {
// remove the settings box so it doesn't get destroyed;
dialog.get_content_area().remove(box);
@@ -1585,6 +1692,16 @@ const Settings = new Lang.Class({
this._settings.set_string('dot-position', "TOP");
},
preview_title_position_bottom_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('window-preview-title-position', 'BOTTOM');
},
preview_title_position_top_button_toggled_cb: function(button) {
if (button.get_active())
this._settings.set_string('window-preview-title-position', 'TOP');
},
panel_size_scale_format_value_cb: function(scale, value) {
return value+ ' px';
},
@@ -1726,10 +1843,14 @@ function buildPrefsWidget() {
// I'd like the scrolled window to default to a size large enough to show all without scrolling, if it fits on the screen
// But, it doesn't seem possible, so I'm setting a minimum size if there seems to be enough screen real estate
widget.show_all();
let viewportSize = settings.viewport.size_request();
let screenHeight = widget.get_screen().get_height() - 120;
widget.set_size_request(viewportSize.width, viewportSize.height > screenHeight ? screenHeight : viewportSize.height);
adjustScrollableHeight(settings.viewport, widget);
return widget;
}
function adjustScrollableHeight(viewport, scrollableWindow) {
let viewportSize = viewport.size_request();
let screenHeight = scrollableWindow.get_screen().get_height() - 120;
scrollableWindow.set_size_request(viewportSize.width, viewportSize.height > screenHeight ? screenHeight : viewportSize.height);
}

View File

@@ -44,11 +44,7 @@
</enum>
<!-- this is mean to Match StSide. LEFT and RIGHT actual position in reversed in
rtl languages -->
<enum id='org.gnome.shell.extensions.dash-to-panel.panelPosition'>
<value value='0' nick='BOTTOM'/>
<value value='1' nick='TOP'/>
</enum>
<enum id='org.gnome.shell.extensions.dash-to-panel.dotPosition'>
<enum id='org.gnome.shell.extensions.dash-to-panel.position'>
<value value='0' nick='BOTTOM'/>
<value value='1' nick='TOP'/>
</enum>
@@ -65,7 +61,7 @@
<value value='4' nick='bolder'/>
</enum>
<schema path="/org/gnome/shell/extensions/dash-to-panel/" id="org.gnome.shell.extensions.dash-to-panel">
<key name="panel-position" enum="org.gnome.shell.extensions.dash-to-panel.panelPosition">
<key name="panel-position" enum="org.gnome.shell.extensions.dash-to-panel.position">
<default>'BOTTOM'</default>
<summary>Panel position</summary>
<description>Panel is shown on the Bottom or Top of the screen.</description>
@@ -75,7 +71,7 @@
<summary>Panel size</summary>
<description>Set the size of the panel.</description>
</key>
<key name="dot-position" enum="org.gnome.shell.extensions.dash-to-panel.dotPosition">
<key name="dot-position" enum="org.gnome.shell.extensions.dash-to-panel.position">
<default>'BOTTOM'</default>
<summary>Dot position</summary>
<description>Running indicators are shown on the Bottom or Top of the screen.</description>
@@ -410,21 +406,61 @@
<summary>Display title in preview</summary>
<description>Display window title in preview</description>
</key>
<key type="i" name="window-preview-width">
<default>350</default>
<summary>Window previews width</summary>
<description>The width of the window previews</description>
<key name="window-preview-title-position" enum="org.gnome.shell.extensions.dash-to-panel.position">
<default>'TOP'</default>
<summary>Title position</summary>
<description>Position of the window title, close button and icon in preview.</description>
</key>
<key type="i" name="window-preview-height">
<default>200</default>
<summary>Window previews height</summary>
<description>The height of the window previews</description>
<key type="s" name="window-preview-title-font-color">
<default>"#dddddd"</default>
<summary>Window previews title font color</summary>
<description>This defines the window preview titles font color.</description>
</key>
<key type="i" name="window-preview-title-font-size">
<default>14</default>
<summary>Window previews title font size</summary>
<description>This defines the window preview titles font size.</description>
</key>
<key type="i" name="window-preview-animation-time">
<default>260</default>
<summary>Window previews animation time</summary>
<description>This defines the window previews animation time.</description>
</key>
<key name="window-preview-title-font-weight" enum="org.gnome.shell.extensions.dash-to-panel.fontWeight">
<default>'inherit'</default>
<summary>Font weight of window preview titles</summary>
<description>This defines the font weight of window preview titles. Supported values: inherit (from theme), normal, lighter, bold and bolder.</description>
</key>
<key type="i" name="window-preview-size">
<default>240</default>
<summary>Window previews size</summary>
<description>Preferred window previews size</description>
</key>
<key type="b" name="window-preview-fixed-x">
<default>false</default>
<summary>Fixed aspect ratio X</summary>
<description>This defines if the window previews use a fixed aspect ratio X.</description>
</key>
<key type="b" name="window-preview-fixed-y">
<default>true</default>
<summary>Fixed aspect ratio Y</summary>
<description>This defines if the window previews use a fixed aspect ratio Y.</description>
</key>
<key type="i" name="window-preview-padding">
<default>20</default>
<default>8</default>
<summary>Window previews padding</summary>
<description>The padding of the window previews</description>
</key>
<key type="i" name="window-preview-aspect-ratio-x">
<default>16</default>
<summary>Aspect ratio X</summary>
<description>The window previews respected aspect ratio X.</description>
</key>
<key type="i" name="window-preview-aspect-ratio-y">
<default>9</default>
<summary>Aspect ratio Y</summary>
<description>The window previews respected aspect ratio Y.</description>
</key>
<key type="b" name="isolate-workspaces">
<default>false</default>
<summary>Provide workspace isolation</summary>
@@ -553,6 +589,16 @@
<summary>Middle click preview to close window</summary>
<description>Middle click on the window preview to close that window</description>
</key>
<key type="b" name="preview-use-custom-opacity">
<default>true</default>
<summary>Window previews use custom opacity</summary>
<description>Window previews background use a different opacity from the panel</description>
</key>
<key type="i" name="preview-custom-opacity">
<default>80</default>
<summary>Window previews background opacity</summary>
<description>Window previews use this custom background opacity.</description>
</key>
<key type="i" name="tray-size">
<default>0</default>
<summary>Tray font size</summary>

View File

@@ -41,10 +41,6 @@
padding-right: 8px;
}
#dashtopanelThumbnailScrollview {
-st-hfade-offset: 48px;
}
#dashtopanelScrollview .app-well-app:hover .overview-icon,
#dashtopanelScrollview .app-well-app:focus .overview-icon {
background: none;

View File

@@ -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();
@@ -84,21 +83,6 @@ function extendDashItemContainer(dashItemContainer) {
* - modified chldBox calculations for when 'show-apps-at-top' option is checked
* - handle horizontal dash
*/
function findIndex(array, predicate) {
if (Array.prototype.findIndex) {
return array.findIndex(predicate);
}
for (let i = 0, l = array.length; i < l; ++i) {
if (predicate(array[i])) {
return i;
}
}
return -1;
};
var taskbarActor = Utils.defineClass({
Name: 'DashToPanel-TaskbarActor',
Extends: St.Widget,
@@ -239,6 +223,9 @@ var taskbar = Utils.defineClass({
coordinate: Clutter.BindCoordinate.HEIGHT
}));
this.previewMenu = new WindowPreview.PreviewMenu(settings, panelWrapper);
this.previewMenu.enable();
if (!this._dtpSettings.get_boolean('show-show-apps-button'))
this.hideShowAppsButton();
@@ -326,11 +313,6 @@ var taskbar = Utils.defineClass({
'notify::checked',
Lang.bind(this, this._syncShowAppsButtonToggled)
],
[
this._dtpSettings,
'changed::show-window-previews',
Lang.bind(this, this._toggleWindowPreview)
],
[
this._dtpSettings,
'changed::show-show-apps-button',
@@ -380,6 +362,7 @@ var taskbar = Utils.defineClass({
this._showAppsIconWrapper.destroy();
this._container.destroy();
this.previewMenu.disable();
this._disconnectWorkspaceSignals();
},
@@ -553,20 +536,18 @@ var taskbar = Utils.defineClass({
setSizeManually: true,
showLabel: false,
isDraggable: !this._dtpSettings.get_boolean('taskbar-locked'),
}
},
this.previewMenu
);
if (appIcon._draggable) {
appIcon._draggable.connect('drag-begin',
Lang.bind(this, function() {
appIcon.actor.opacity = 50;
this._disableWindowPreview();
}));
appIcon._draggable.connect('drag-end',
Lang.bind(this, function() {
appIcon.actor.opacity = 255;
this._enableWindowPreview();
appIcon.syncWindowPreview(this._getAppIcons());
}));
}
@@ -585,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;
}));
@@ -599,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.
@@ -624,29 +605,6 @@ var taskbar = Utils.defineClass({
return item;
},
_toggleWindowPreview: function() {
if (this._dtpSettings.get_boolean('show-window-previews'))
this._enableWindowPreview();
else
this._disableWindowPreview();
},
_enableWindowPreview: function() {
let appIcons = this._getAppIcons();
appIcons.filter(appIcon => !appIcon.isLauncher)
.forEach(function (appIcon) {
appIcon.enableWindowPreview(appIcons);
});
},
_disableWindowPreview: function() {
let appIcons = this._getAppIcons();
appIcons.forEach(function (appIcon) {
appIcon.disableWindowPreview();
});
},
// Return an array with the "proper" appIcons currently in the taskbar
_getAppIcons: function() {
// Only consider children which are "proper" icons and which are not
@@ -783,10 +741,6 @@ var taskbar = Utils.defineClass({
getAppStableSequence(appB, this._dtpSettings, this.panelWrapper.monitor);
},
sortWindowsCompareFunction: function(windowA, windowB) {
return getWindowStableSequence(windowA) - getWindowStableSequence(windowB);
},
_redisplay: function () {
if (!this._signalsHandler) {
return;
@@ -815,8 +769,8 @@ var taskbar = Utils.defineClass({
//remove the appIcons which are not in the expected apps list
for (let i = currentAppIcons.length - 1; i > -1; --i) {
let appIcon = currentAppIcons[i].child._delegate;
let appIndex = findIndex(expectedAppInfos, appInfo => appInfo.app == appIcon.app &&
appInfo.isLauncher == appIcon.isLauncher);
let appIndex = Utils.findIndex(expectedAppInfos, appInfo => appInfo.app == appIcon.app &&
appInfo.isLauncher == appIcon.isLauncher);
if (appIndex < 0 ||
(appIcon.window && (this.isGroupApps || expectedAppInfos[appIndex].windows.indexOf(appIcon.window) < 0)) ||
@@ -836,8 +790,8 @@ var taskbar = Utils.defineClass({
for (let j = 0, ll = neededAppIcons.length; j < ll; ++j) {
//check if the icon already exists
let matchingAppIconIndex = findIndex(currentAppIcons, appIcon => appIcon.child._delegate.app == neededAppIcons[j].app &&
appIcon.child._delegate.window == neededAppIcons[j].window);
let matchingAppIconIndex = Utils.findIndex(currentAppIcons, appIcon => appIcon.child._delegate.app == neededAppIcons[j].app &&
appIcon.child._delegate.window == neededAppIcons[j].window);
if (matchingAppIconIndex > 0 && matchingAppIconIndex != currentPosition) {
//moved icon, reposition it
@@ -873,9 +827,6 @@ var taskbar = Utils.defineClass({
this._updateNumberOverlay();
}
// Connect windows previews to hover events
this._toggleWindowPreview();
this._shownInitially = true;
},
@@ -905,7 +856,7 @@ var taskbar = Utils.defineClass({
app: app,
isLauncher: defaultIsLauncher || false,
windows: defaultWindows || AppIcons.getInterestingWindows(app, this._dtpSettings, this.panelWrapper.monitor)
.sort(this.sortWindowsCompareFunction)
.sort(sortWindowsCompareFunction)
}));
},
@@ -984,9 +935,9 @@ var taskbar = Utils.defineClass({
let currentAppIcons = this._getAppIcons();
let sourceIndex = currentAppIcons.indexOf(source);
let hoveredIndex = findIndex(currentAppIcons,
appIcon => x >= appIcon._dashItemContainer.x &&
x <= (appIcon._dashItemContainer.x + appIcon._dashItemContainer.width));
let hoveredIndex = Utils.findIndex(currentAppIcons,
appIcon => x >= appIcon._dashItemContainer.x &&
x <= (appIcon._dashItemContainer.x + appIcon._dashItemContainer.width));
if (!this._dragInfo) {
this._dragInfo = [sourceIndex, source];
@@ -1008,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);
}
}
@@ -1259,70 +1210,10 @@ function getAppStableSequence(app, settings, monitor) {
}, Infinity);
}
function sortWindowsCompareFunction(windowA, windowB) {
return getWindowStableSequence(windowA) - getWindowStableSequence(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];
}
}

View File

@@ -136,7 +136,7 @@ var DynamicTransparency = Utils.defineClass({
},
_updateAnimationDuration: function() {
this._animationDuration = (this._dtpSettings.get_int('trans-dynamic-anim-time') * 0.001) + 's;';
this.animationDuration = (this._dtpSettings.get_int('trans-dynamic-anim-time') * 0.001) + 's;';
},
_updateAllAndSet: function() {
@@ -172,18 +172,18 @@ var DynamicTransparency = Utils.defineClass({
},
_updateColor: function(themeBackground) {
this._backgroundColor = this._dtpSettings.get_boolean('trans-use-custom-bg') ?
this._dtpSettings.get_string('trans-bg-color') :
(themeBackground || this._getThemeBackground());
this.backgroundColorRgb = this._dtpSettings.get_boolean('trans-use-custom-bg') ?
this._dtpSettings.get_string('trans-bg-color') :
(themeBackground || this._getThemeBackground());
},
_updateAlpha: function(themeBackground) {
if (this._windowOverlap && !Main.overview.visibleTarget && this._dtpSettings.get_boolean('trans-use-dynamic-opacity')) {
this._alpha = this._dtpSettings.get_double('trans-dynamic-anim-target');
this.alpha = this._dtpSettings.get_double('trans-dynamic-anim-target');
} else {
this._alpha = this._dtpSettings.get_boolean('trans-use-custom-opacity') ?
this._dtpSettings.get_double('trans-panel-opacity') :
(themeBackground || this._getThemeBackground()).alpha * 0.003921569; // 1 / 255 = 0.003921569
this.alpha = this._dtpSettings.get_boolean('trans-use-custom-opacity') ?
this._dtpSettings.get_double('trans-panel-opacity') :
(themeBackground || this._getThemeBackground()).alpha * 0.003921569; // 1 / 255 = 0.003921569
}
},
@@ -192,17 +192,17 @@ var DynamicTransparency = Utils.defineClass({
if (this._dtpSettings.get_boolean('trans-use-custom-gradient')) {
this._gradientStyle += 'background-gradient-direction: vertical; ' +
'background-gradient-start: ' + this._getrgbaColor(this._dtpSettings.get_string('trans-gradient-top-color'),
'background-gradient-start: ' + Utils.getrgbaColor(this._dtpSettings.get_string('trans-gradient-top-color'),
this._dtpSettings.get_double('trans-gradient-top-opacity')) +
'background-gradient-end: ' + this._getrgbaColor(this._dtpSettings.get_string('trans-gradient-bottom-color'),
'background-gradient-end: ' + Utils.getrgbaColor(this._dtpSettings.get_string('trans-gradient-bottom-color'),
this._dtpSettings.get_double('trans-gradient-bottom-opacity'));
}
},
_setBackground: function() {
this.currentBackgroundColor = this._getrgbaColor(this._backgroundColor, this._alpha);
this.currentBackgroundColor = Utils.getrgbaColor(this.backgroundColorRgb, this.alpha);
let transition = 'transition-duration:' + this._animationDuration;
let transition = 'transition-duration:' + this.animationDuration;
let cornerStyle = '-panel-corner-background-color: ' + this.currentBackgroundColor + transition;
this._dtpPanel.panelBg.set_style('background-color: ' + this.currentBackgroundColor + transition + this._complementaryStyles);
@@ -216,22 +216,10 @@ var DynamicTransparency = Utils.defineClass({
'border-image: none; ' +
'background-image: none; ' +
this._gradientStyle +
'transition-duration:' + this._animationDuration
'transition-duration:' + this.animationDuration
);
},
_getrgbaColor: function(color, alpha) {
if (alpha <= 0) {
return 'transparent; ';
}
if (typeof color === 'string') {
color = Clutter.color_from_string(color)[1];
}
return 'rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + (Math.floor(alpha * 100) * 0.01) + '); ' ;
},
_getThemeBackground: function(reload) {
if (reload || !this._themeBackground) {
let fakePanel = new St.Bin({ name: 'panel' });

130
utils.js
View File

@@ -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'];
@@ -94,7 +96,7 @@ var defineClass = function (classDef) {
.forEach(k => C.prototype[k] = classDef[k]);
if (isGObject) {
C = GObject.registerClass(C);
C = GObject.registerClass({ Signals: classDef.Signals || {} }, C);
}
return C;
@@ -271,6 +273,50 @@ var DisplayWrapper = {
}
};
var getCurrentWorkspace = function() {
return DisplayWrapper.getWorkspaceManager().get_active_workspace();
};
var getWorkspaceByIndex = function(index) {
return DisplayWrapper.getWorkspaceManager().get_workspace_by_index(index);
};
var getWorkspaceCount = function() {
return DisplayWrapper.getWorkspaceManager().n_workspaces;
};
var checkIfWindowHasTransient = function(window) {
let hasTransient;
window.foreach_transient(t => !(hasTransient = true));
return hasTransient;
};
var findIndex = function(array, predicate) {
if (Array.prototype.findIndex) {
return array.findIndex(predicate);
}
for (let i = 0, l = array.length; i < l; ++i) {
if (predicate(array[i])) {
return i;
}
}
return -1;
};
var mergeObjects = function(main, bck) {
for (var prop in bck) {
if (!main.hasOwnProperty(prop) && bck.hasOwnProperty(prop)) {
main[prop] = bck[prop];
}
}
return main;
};
var hookVfunc = function(proto, symbol, func) {
if (Gi.hook_up_vfunc_symbol) {
//gjs > 1.53.3
@@ -305,6 +351,88 @@ var removeKeybinding = function(key) {
Main.wm.removeKeybinding(key);
}
};
var getrgbaColor = function(color, alpha, offset) {
if (alpha <= 0) {
return 'transparent; ';
}
color = typeof color === 'string' ? Clutter.color_from_string(color)[1] : color;
let rgb = { red: color.red, green: color.green, blue: color.blue };
if (offset) {
['red', 'green', 'blue'].forEach(k => {
rgb[k] = Math.min(255, Math.max(0, rgb[k] + offset));
if (rgb[k] == color[k]) {
rgb[k] = Math.min(255, Math.max(0, rgb[k] - 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, onComplete) {
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);
let tweenOpts = {
time: Util.SCROLL_TIME,
onComplete: onComplete || (() => {}),
transition: 'easeOutQuad'
};
if (vvalue !== vvalue0) {
Tweener.addTween(vadjustment, mergeObjects(tweenOpts, { value: vvalue }));
}
if (hvalue !== hvalue0) {
Tweener.addTween(hadjustment, mergeObjects(tweenOpts, { value: hvalue }));
}
return [hvalue- hvalue0, vvalue - vvalue0];
}
/**
* ColorUtils is adapted from https://github.com/micheleg/dash-to-dock

File diff suppressed because it is too large Load Diff