mirror of
https://github.com/morgan9e/dash-to-panel
synced 2026-04-14 00:04:17 +09:00
336
appIcons.js
336
appIcons.js
@@ -39,14 +39,14 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';
|
||||
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
|
||||
import * as Util from 'resource:///org/gnome/shell/misc/util.js';
|
||||
import * as BoxPointer from 'resource:///org/gnome/shell/ui/boxpointer.js';
|
||||
import {EventEmitter} from 'resource:///org/gnome/shell/misc/signals.js';
|
||||
import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js';
|
||||
|
||||
import * as Utils from './utils.js';
|
||||
import * as PanelSettings from './panelSettings.js';
|
||||
import * as Taskbar from './taskbar.js';
|
||||
import * as Progress from './progress.js';
|
||||
import {DTP_EXTENSION, SETTINGS, DESKTOPSETTINGS, TERMINALSETTINGS, EXTENSION_PATH} from './extension.js';
|
||||
import {gettext as _, ngettext} from 'resource:///org/gnome/shell/extensions/extension.js';
|
||||
import { DTP_EXTENSION, SETTINGS, DESKTOPSETTINGS, TERMINALSETTINGS, EXTENSION_PATH } from './extension.js';
|
||||
import { gettext as _, ngettext } from 'resource:///org/gnome/shell/extensions/extension.js';
|
||||
|
||||
//timeout names
|
||||
const T2 = 'mouseScrollTimeout';
|
||||
@@ -118,13 +118,16 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
this._previewMenu = previewMenu;
|
||||
this.iconAnimator = iconAnimator;
|
||||
this.lastClick = 0;
|
||||
this._appicon_normalstyle = '';
|
||||
this._appicon_hoverstyle = '';
|
||||
this._appicon_pressedstyle = '';
|
||||
|
||||
super._init(appInfo.app, iconParams);
|
||||
|
||||
this._timeoutsHandler = new Utils.TimeoutsHandler();
|
||||
|
||||
// Fix touchscreen issues before the listener is added by the parent constructor.
|
||||
this._onTouchEvent = function(actor, event) {
|
||||
this._onTouchEvent = function (actor, event) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_BEGIN) {
|
||||
// Open the popup menu on long press.
|
||||
this._setPopupTimeout();
|
||||
@@ -138,7 +141,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
return Clutter.EVENT_STOP;
|
||||
};
|
||||
// Hack for missing TOUCH_END event.
|
||||
this._onLeaveEvent = function(actor, event) {
|
||||
this._onLeaveEvent = function (actor, event) {
|
||||
this.fake_release();
|
||||
if (this._menuTimeoutId != 0) this.activate(1); // Activate/launch the application if TOUCH_END didn't fire.
|
||||
this._removeMenuTimeout();
|
||||
@@ -149,7 +152,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
this._isGroupApps = SETTINGS.get_boolean('group-apps');
|
||||
|
||||
this._container = new St.Widget({ style_class: 'dtp-container', layout_manager: new Clutter.BinLayout() });
|
||||
this._dotsContainer = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
this._dotsContainer = new St.Widget({ style_class: 'dtp-dots-container', layout_manager: new Clutter.BinLayout() });
|
||||
this._dtpIconContainer = new St.Widget({ layout_manager: new Clutter.BinLayout(), style: getIconContainerStyle(panel.checkIfVertical()) });
|
||||
|
||||
this.remove_child(this._iconContainer);
|
||||
@@ -187,18 +190,19 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
|
||||
// Monitor windows-changes instead of app state.
|
||||
// Keep using the same Id and function callback (that is extended)
|
||||
if(this._stateChangedId > 0) {
|
||||
if (this._stateChangedId > 0) {
|
||||
this.app.disconnect(this._stateChangedId);
|
||||
this._stateChangedId = 0;
|
||||
}
|
||||
|
||||
this._onAnimateAppiconHoverChanged();
|
||||
this._onAppIconHoverHighlightChanged();
|
||||
this._setAppIconPadding();
|
||||
this._setAppIconStyle();
|
||||
this._showDots();
|
||||
|
||||
this._focusWindowChangedId = global.display.connect('notify::focus-window',
|
||||
this._onFocusAppChanged.bind(this));
|
||||
this._onFocusAppChanged.bind(this));
|
||||
|
||||
this._windowEnteredMonitorId = this._windowLeftMonitorId = 0;
|
||||
this._stateChangedId = this.app.connect('windows-changed', this.onWindowsChanged.bind(this));
|
||||
@@ -223,24 +227,33 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
})
|
||||
} else {
|
||||
this._titleWindowChangeId = this.window.connect('notify::title',
|
||||
this._updateWindowTitle.bind(this));
|
||||
this._updateWindowTitle.bind(this));
|
||||
|
||||
this._minimizedWindowChangeId = this.window.connect('notify::minimized',
|
||||
this._updateWindowTitleStyle.bind(this));
|
||||
this._updateWindowTitleStyle.bind(this));
|
||||
}
|
||||
|
||||
this._scrollEventId = this.connect('scroll-event', this._onMouseScroll.bind(this));
|
||||
|
||||
this._overviewWindowDragEndId = Main.overview.connect('window-drag-end',
|
||||
this._onOverviewWindowDragEnd.bind(this));
|
||||
this._onOverviewWindowDragEnd.bind(this));
|
||||
|
||||
this._switchWorkspaceId = global.window_manager.connect('switch-workspace',
|
||||
this._onSwitchWorkspace.bind(this));
|
||||
this._onSwitchWorkspace.bind(this));
|
||||
|
||||
this._hoverChangeId = this.connect('notify::hover', () => this._onAppIconHoverChanged());
|
||||
|
||||
this._hoverChangeId2 = this.connect('notify::hover', () => this._onAppIconHoverChanged_GtkWorkaround());
|
||||
this._pressedChangedId = this.connect('notify::pressed', () => this._onAppIconPressedChanged_GtkWorkaround());
|
||||
|
||||
|
||||
this._dtpSettingsSignalIds = [
|
||||
SETTINGS.connect('changed::animate-appicon-hover', this._onAnimateAppiconHoverChanged.bind(this)),
|
||||
SETTINGS.connect('changed::animate-appicon-hover', this._onAppIconHoverHighlightChanged.bind(this)),
|
||||
SETTINGS.connect('changed::highlight-appicon-hover', this._onAppIconHoverHighlightChanged.bind(this)),
|
||||
SETTINGS.connect('changed::highlight-appicon-hover-background-color', this._onAppIconHoverHighlightChanged.bind(this)),
|
||||
SETTINGS.connect('changed::highlight-appicon-pressed-background-color', this._onAppIconHoverHighlightChanged.bind(this)),
|
||||
SETTINGS.connect('changed::highlight-appicon-hover-border-radius', this._onAppIconHoverHighlightChanged.bind(this)),
|
||||
SETTINGS.connect('changed::dot-position', this._settingsChangeRefresh.bind(this)),
|
||||
SETTINGS.connect('changed::dot-size', this._settingsChangeRefresh.bind(this)),
|
||||
SETTINGS.connect('changed::dot-style-focused', this._settingsChangeRefresh.bind(this)),
|
||||
@@ -266,8 +279,13 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
SETTINGS.connect('changed::group-apps-label-font-color-minimized', this._updateWindowTitleStyle.bind(this)),
|
||||
SETTINGS.connect('changed::group-apps-label-max-width', this._updateWindowTitleStyle.bind(this)),
|
||||
SETTINGS.connect('changed::group-apps-use-fixed-width', this._updateWindowTitleStyle.bind(this)),
|
||||
SETTINGS.connect('changed::group-apps-underline-unfocused', this._settingsChangeRefresh.bind(this))
|
||||
]
|
||||
SETTINGS.connect('changed::group-apps-underline-unfocused', this._settingsChangeRefresh.bind(this)),
|
||||
];
|
||||
|
||||
this._dtpSettingsSignalIds = this._dtpSettingsSignalIds.concat([
|
||||
SETTINGS.connect('changed::highlight-appicon-hover-border-radius', () => this._setIconStyle(this._isFocusedWindow())),
|
||||
]);
|
||||
|
||||
|
||||
this._progressIndicator = new Progress.ProgressIndicator(this, panel.progressManager);
|
||||
|
||||
@@ -280,12 +298,14 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
|
||||
// Used by TaskbarItemContainer to animate appIcons on hover
|
||||
getCloneButton() {
|
||||
// The source of the clone is this._container,
|
||||
// The source of the clone is this._dtpIconContainer,
|
||||
// which contains the icon but no highlighting elements
|
||||
// using this.actor directly would break DnD style.
|
||||
let cloneSource = this._dtpIconContainer;
|
||||
let clone = new Clutter.Clone({
|
||||
source: this.child,
|
||||
source: cloneSource,
|
||||
x: this.child.x, y: this.child.y,
|
||||
width: this.child.width, height: this.child.height,
|
||||
width: cloneSource.width, height: cloneSource.height,
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
opacity: 255,
|
||||
reactive: false,
|
||||
@@ -306,12 +326,12 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
shouldShowTooltip() {
|
||||
if (!SETTINGS.get_boolean('show-tooltip') ||
|
||||
(!this.isLauncher && SETTINGS.get_boolean("show-window-previews") &&
|
||||
this.getAppIconInterestingWindows().length > 0)) {
|
||||
this.getAppIconInterestingWindows().length > 0)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.hover && !this.window &&
|
||||
(!this._menu || !this._menu.isOpen) &&
|
||||
(this._previewMenu.getCurrentAppIcon() !== this);
|
||||
(!this._menu || !this._menu.isOpen) &&
|
||||
(this._previewMenu.getCurrentAppIcon() !== this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,19 +361,19 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
this._stateChangedId = 0;
|
||||
}
|
||||
|
||||
if(this._overviewWindowDragEndId)
|
||||
if (this._overviewWindowDragEndId)
|
||||
Main.overview.disconnect(this._overviewWindowDragEndId);
|
||||
|
||||
if(this._focusWindowChangedId)
|
||||
if (this._focusWindowChangedId)
|
||||
global.display.disconnect(this._focusWindowChangedId);
|
||||
|
||||
if (this._fullscreenId)
|
||||
Utils.DisplayWrapper.getScreen().disconnect(this._fullscreenId);
|
||||
|
||||
if(this._titleWindowChangeId)
|
||||
if (this._titleWindowChangeId)
|
||||
this.window.disconnect(this._titleWindowChangeId);
|
||||
|
||||
if(this._minimizedWindowChangeId)
|
||||
if (this._minimizedWindowChangeId)
|
||||
this.window.disconnect(this._minimizedWindowChangeId);
|
||||
|
||||
if (this._windowEnteredMonitorId) {
|
||||
@@ -361,15 +381,21 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
Utils.DisplayWrapper.getScreen().disconnect(this._windowLeftMonitorId);
|
||||
}
|
||||
|
||||
if(this._switchWorkspaceId)
|
||||
if (this._switchWorkspaceId)
|
||||
global.window_manager.disconnect(this._switchWorkspaceId);
|
||||
|
||||
if(this._scaleFactorChangedId)
|
||||
if (this._scaleFactorChangedId)
|
||||
Utils.getStageTheme().disconnect(this._scaleFactorChangedId);
|
||||
|
||||
if (this._hoverChangeId) {
|
||||
this.disconnect(this._hoverChangeId);
|
||||
}
|
||||
if (this._hoverChangeId2) {
|
||||
this.disconnect(this._hoverChangeId2);
|
||||
}
|
||||
if (this._pressedChangedId) {
|
||||
this.disconnect(this._pressedChangedId);
|
||||
}
|
||||
|
||||
if (this._scrollEventId) {
|
||||
this.disconnect(this._scrollEventId);
|
||||
@@ -415,7 +441,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
[rect.width, rect.height] = this.get_transformed_size();
|
||||
|
||||
let windows = this.window ? [this.window] : this.getAppIconInterestingWindows(true);
|
||||
windows.forEach(function(w) {
|
||||
windows.forEach(function (w) {
|
||||
w.set_icon_geometry(rect);
|
||||
});
|
||||
}
|
||||
@@ -452,6 +478,50 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
_onAppIconHoverHighlightChanged() {
|
||||
const background_color = SETTINGS.get_string('highlight-appicon-hover-background-color');
|
||||
const pressed_color = SETTINGS.get_string('highlight-appicon-pressed-background-color');
|
||||
const border_radius = SETTINGS.get_int('highlight-appicon-hover-border-radius');
|
||||
|
||||
// Some trickery needed to get the effect
|
||||
const br = `border-radius: ${border_radius}px;`;
|
||||
this._appicon_normalstyle = br;
|
||||
this._container.set_style(this._appicon_normalstyle);
|
||||
this._appicon_hoverstyle = `background-color: ${background_color}; ${br}`;
|
||||
this._appicon_pressedstyle = `background-color: ${pressed_color}; ${br}`;
|
||||
|
||||
if (SETTINGS.get_boolean('highlight-appicon-hover')) {
|
||||
this._container.remove_style_class_name('no-highlight');
|
||||
} else {
|
||||
this._container.add_style_class_name('no-highlight');
|
||||
this._appicon_normalstyle = '';
|
||||
this._appicon_hoverstyle = '';
|
||||
this._appicon_pressedstyle = '';
|
||||
}
|
||||
}
|
||||
|
||||
_onAppIconHoverChanged_GtkWorkaround() {
|
||||
if (this.hover && this._appicon_hoverstyle) {
|
||||
this._container.set_style(this._appicon_hoverstyle);
|
||||
} else if (this._appicon_normalstyle) {
|
||||
this._container.set_style(this._appicon_normalstyle);
|
||||
} else {
|
||||
this._container.set_style('');
|
||||
}
|
||||
}
|
||||
|
||||
_onAppIconPressedChanged_GtkWorkaround() {
|
||||
if (this.pressed && this._appicon_pressedstyle) {
|
||||
this._container.set_style(this._appicon_pressedstyle);
|
||||
} else if (this.hover && this._appicon_hoverstyle) {
|
||||
this._container.set_style(this._appicon_hoverstyle);
|
||||
} else if (this._appicon_normalstyle) {
|
||||
this._container.set_style(this._appicon_normalstyle);
|
||||
} else {
|
||||
this._container.set_style('');
|
||||
}
|
||||
}
|
||||
|
||||
_onMouseScroll(actor, event) {
|
||||
let scrollAction = SETTINGS.get_string('scroll-icon-action');
|
||||
|
||||
@@ -464,7 +534,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
let direction = Utils.getMouseScrollDirection(event);
|
||||
|
||||
if (direction && !this._timeoutsHandler.getId(T2)) {
|
||||
this._timeoutsHandler.add([T2, SETTINGS.get_int('scroll-icon-delay'), () => {}]);
|
||||
this._timeoutsHandler.add([T2, SETTINGS.get_int('scroll-icon-delay'), () => { }]);
|
||||
|
||||
let windows = this.getAppIconInterestingWindows();
|
||||
|
||||
@@ -493,7 +563,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
});
|
||||
} else {
|
||||
this._focusedDots = new St.DrawingArea(),
|
||||
this._unfocusedDots = new St.DrawingArea();
|
||||
this._unfocusedDots = new St.DrawingArea();
|
||||
|
||||
this._focusedDots.connect('repaint', () => {
|
||||
if (!this._dashItemContainer.animatingOut)
|
||||
@@ -560,8 +630,8 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
let fontWeight = SETTINGS.get_string('group-apps-label-font-weight');
|
||||
let fontScale = DESKTOPSETTINGS.get_double('text-scaling-factor');
|
||||
let fontColor = this.window.minimized ?
|
||||
SETTINGS.get_string('group-apps-label-font-color-minimized') :
|
||||
SETTINGS.get_string('group-apps-label-font-color');
|
||||
SETTINGS.get_string('group-apps-label-font-color-minimized') :
|
||||
SETTINGS.get_string('group-apps-label-font-color');
|
||||
let scaleFactor = Utils.getScaleFactor();
|
||||
let maxLabelWidth = SETTINGS.get_int('group-apps-label-max-width') * scaleFactor;
|
||||
let variableWidth = !useFixedWidth || this.dtpPanel.checkIfVertical() || this.dtpPanel.taskbar.fullScrollView;
|
||||
@@ -573,9 +643,9 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
this._windowTitle.clutter_text.natural_width_set = useFixedWidth;
|
||||
|
||||
this._windowTitle.set_style('font-size: ' + SETTINGS.get_int('group-apps-label-font-size') * fontScale + 'px;' +
|
||||
'font-weight: ' + fontWeight + ';' +
|
||||
(useFixedWidth ? '' : 'max-width: ' + maxLabelWidth + 'px;') +
|
||||
'color: ' + fontColor);
|
||||
'font-weight: ' + fontWeight + ';' +
|
||||
(useFixedWidth ? '' : 'max-width: ' + maxLabelWidth + 'px;') +
|
||||
'color: ' + fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,17 +662,17 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
_setIconStyle(isFocused) {
|
||||
let inlineStyle = 'margin: 0;';
|
||||
|
||||
if(SETTINGS.get_boolean('focus-highlight') &&
|
||||
this._checkIfFocusedApp() && !this.isLauncher &&
|
||||
(!this.window || isFocused) && !this._isThemeProvidingIndicator() && this._checkIfMonitorHasFocus()) {
|
||||
if (SETTINGS.get_boolean('focus-highlight') &&
|
||||
this._checkIfFocusedApp() && !this.isLauncher &&
|
||||
(!this.window || isFocused) && !this._isThemeProvidingIndicator() && this._checkIfMonitorHasFocus()) {
|
||||
let focusedDotStyle = SETTINGS.get_string('dot-style-focused');
|
||||
let pos = SETTINGS.get_string('dot-position');
|
||||
let highlightMargin = this._focusedIsWide ? SETTINGS.get_int('dot-size') : 0;
|
||||
|
||||
if(!this.window) {
|
||||
if (!this.window) {
|
||||
let containerWidth = this._dtpIconContainer.get_width() / Utils.getScaleFactor();
|
||||
let backgroundSize = containerWidth + "px " +
|
||||
(containerWidth - (pos == DOT_POSITION.BOTTOM ? highlightMargin : 0)) + "px;";
|
||||
(containerWidth - (pos == DOT_POSITION.BOTTOM ? highlightMargin : 0)) + "px;";
|
||||
|
||||
if (focusedDotStyle == DOT_STYLE.CILIORA || focusedDotStyle == DOT_STYLE.SEGMENTED)
|
||||
highlightMargin += 1;
|
||||
@@ -615,16 +685,17 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
}
|
||||
|
||||
inlineStyle += "background-image: url('" + EXTENSION_PATH + bgSvg + ".svg');" +
|
||||
"background-position: 0 " + (pos == DOT_POSITION.TOP ? highlightMargin : 0) + "px;" +
|
||||
"background-size: " + backgroundSize;
|
||||
"background-position: 0 " + (pos == DOT_POSITION.TOP ? highlightMargin : 0) + "px;" +
|
||||
"background-size: " + backgroundSize;
|
||||
}
|
||||
}
|
||||
|
||||
let highlightColor = this._getFocusHighlightColor();
|
||||
inlineStyle += "background-color: " + cssHexTocssRgba(highlightColor, SETTINGS.get_int('focus-highlight-opacity') * 0.01);
|
||||
inlineStyle += "background-color: " + cssHexTocssRgba(highlightColor, SETTINGS.get_int('focus-highlight-opacity') * 0.01) + ";";
|
||||
inlineStyle += this._appicon_normalstyle;
|
||||
}
|
||||
|
||||
if(this._dotsContainer.get_style() != inlineStyle) {
|
||||
if (this._dotsContainer.get_style() != inlineStyle) {
|
||||
this._dotsContainer.set_style(inlineStyle);
|
||||
}
|
||||
}
|
||||
@@ -635,16 +706,29 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
|
||||
_checkIfMonitorHasFocus() {
|
||||
return global.display.focus_window &&
|
||||
(!SETTINGS.get_boolean('multi-monitors') || // only check same monitor index if multi window is enabled.
|
||||
(!SETTINGS.get_boolean('multi-monitors') || // only check same monitor index if multi window is enabled.
|
||||
!SETTINGS.get_boolean('isolate-monitors') ||
|
||||
global.display.focus_window.get_monitor() === this.dtpPanel.monitor.index);
|
||||
}
|
||||
|
||||
_setAppIconPadding() {
|
||||
let padding = getIconPadding(this.dtpPanel.monitor.index);
|
||||
let margin = SETTINGS.get_int('appicon-margin');
|
||||
const padding = getIconPadding(this.dtpPanel.monitor.index);
|
||||
const margin = SETTINGS.get_int('appicon-margin');
|
||||
const margin_todesktop = SETTINGS.get_int('appicon-margin-todesktop');
|
||||
const margin_toscreenborder = SETTINGS.get_int('appicon-margin-toscreenborder');
|
||||
|
||||
this.set_style('padding:' + (this.dtpPanel.checkIfVertical() ? margin + 'px 0' : '0 ' + margin + 'px;'));
|
||||
let margin_style = '';
|
||||
const panelPosition = this.dtpPanel.getPosition();
|
||||
if (panelPosition == St.Side.TOP) {
|
||||
margin_style = `${margin_toscreenborder}px ${margin}px ${margin_todesktop}px ${margin}px`;
|
||||
} else if (panelPosition == St.Side.RIGHT) {
|
||||
margin_style = `${margin}px ${margin_toscreenborder}px ${margin}px ${margin_todesktop}px`;
|
||||
} else if (panelPosition == St.Side.LEFT) {
|
||||
margin_style = `${margin}px ${margin_todesktop}px ${margin}px ${margin_toscreenborder}px`;
|
||||
} else {
|
||||
margin_style = `${margin_todesktop}px ${margin}px ${margin_toscreenborder}px ${margin}px`;
|
||||
}
|
||||
this.set_style(`padding: ${margin_style};`);
|
||||
this._iconContainer.set_style('padding: ' + padding + 'px;');
|
||||
}
|
||||
|
||||
@@ -724,7 +808,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
|
||||
this._setIconStyle(isFocused);
|
||||
|
||||
if(!this._isGroupApps) {
|
||||
if (!this._isGroupApps) {
|
||||
if (this.window && (SETTINGS.get_boolean('group-apps-underline-unfocused') || isFocused)) {
|
||||
let align = Clutter.ActorAlign[position == DOT_POSITION.TOP || position == DOT_POSITION.LEFT ? 'START' : 'END'];
|
||||
|
||||
@@ -748,13 +832,13 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
isFocused = this._checkIfFocusedApp() && this._checkIfMonitorHasFocus();
|
||||
|
||||
this._timeoutsHandler.add([T6, 0, () => {
|
||||
if(isFocused)
|
||||
if (isFocused)
|
||||
this.add_style_class_name('focused');
|
||||
else
|
||||
this.remove_style_class_name('focused');
|
||||
}]);
|
||||
|
||||
if(this._focusedIsWide) {
|
||||
if (this._focusedIsWide) {
|
||||
newFocusedDotsSize = (isFocused && this._nWindows > 0) ? this._containerSize : 0;
|
||||
newFocusedDotsOpacity = 255;
|
||||
} else {
|
||||
@@ -762,7 +846,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
newFocusedDotsOpacity = (isFocused && this._nWindows > 0) ? 255 : 0;
|
||||
}
|
||||
|
||||
if(this._unfocusedIsWide) {
|
||||
if (this._unfocusedIsWide) {
|
||||
newUnfocusedDotsSize = (!isFocused && this._nWindows > 0) ? this._containerSize : 0;
|
||||
newUnfocusedDotsOpacity = 255;
|
||||
} else {
|
||||
@@ -775,8 +859,8 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
// AND (going from a wide style to a narrow style indicator or vice-versa
|
||||
// OR going from an open app to a closed app or vice versa)
|
||||
let animate = SETTINGS.get_boolean('animate-app-switch') &&
|
||||
((this._focusedIsWide != this._unfocusedIsWide) ||
|
||||
(this._focusedDots[sizeProp] != newUnfocusedDotsSize || this._unfocusedDots[sizeProp] != newFocusedDotsSize))
|
||||
((this._focusedIsWide != this._unfocusedIsWide) ||
|
||||
(this._focusedDots[sizeProp] != newUnfocusedDotsSize || this._unfocusedDots[sizeProp] != newFocusedDotsSize))
|
||||
let duration = animate ? Taskbar.DASH_ANIMATION_TIME : 0.001;
|
||||
|
||||
this._animateDotDisplay(this._focusedDots, newFocusedDotsSize, this._unfocusedDots, newUnfocusedDotsOpacity, sizeProp, duration);
|
||||
@@ -791,12 +875,12 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
time: duration,
|
||||
transition: 'easeInOutCubic',
|
||||
onComplete: () => {
|
||||
if(newOtherOpacity > 0)
|
||||
if (newOtherOpacity > 0)
|
||||
otherDots.opacity = newOtherOpacity;
|
||||
}
|
||||
};
|
||||
|
||||
if(newOtherOpacity == 0)
|
||||
if (newOtherOpacity == 0)
|
||||
otherDots.opacity = newOtherOpacity;
|
||||
|
||||
tweenOpts[sizeProp] = newSize;
|
||||
@@ -830,7 +914,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
// running indicator by way of a border image on the icon, for example in
|
||||
// the theme Ciliora
|
||||
return (this.icon.get_stage() &&
|
||||
this.icon.get_theme_node().get_border_image());
|
||||
this.icon.get_theme_node().get_border_image());
|
||||
}
|
||||
|
||||
activate(button, modifiers, handleAsGrouped) {
|
||||
@@ -854,7 +938,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
let buttonAction = 0;
|
||||
let doubleClick;
|
||||
|
||||
if (button && button == 2 ) {
|
||||
if (button && button == 2) {
|
||||
if (modifiers & Clutter.ModifierType.SHIFT_MASK)
|
||||
buttonAction = SETTINGS.get_string('shift-middle-click-action');
|
||||
else
|
||||
@@ -895,7 +979,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
if (!Main.overview._shown &&
|
||||
(buttonAction == 'MINIMIZE' || buttonAction == 'TOGGLE-SHOWPREVIEW' || buttonAction == 'TOGGLE-CYCLE' || buttonAction == 'CYCLE-MIN') &&
|
||||
(this._isFocusedWindow() || (buttonAction == 'MINIMIZE' && (button == 2 || modifiers & Clutter.ModifierType.SHIFT_MASK)))) {
|
||||
this.window.minimize();
|
||||
this.window.minimize();
|
||||
} else {
|
||||
Main.activateWindow(this.window);
|
||||
}
|
||||
@@ -927,13 +1011,13 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
case "MINIMIZE":
|
||||
// In overview just activate the app, unless the acion is explicitely
|
||||
// requested with a keyboard modifier
|
||||
if (!Main.overview._shown || modifiers){
|
||||
if (!Main.overview._shown || modifiers) {
|
||||
// If we have button=2 or a modifier, allow minimization even if
|
||||
// the app is not focused
|
||||
if (appHasFocus || button == 2 || modifiers & Clutter.ModifierType.SHIFT_MASK) {
|
||||
// minimize all windows on double click and always in the case of primary click without
|
||||
// additional modifiers
|
||||
let all_windows = (button == 1 && ! modifiers) || doubleClick;
|
||||
let all_windows = (button == 1 && !modifiers) || doubleClick;
|
||||
minimizeWindow(this.app, all_windows, monitor);
|
||||
}
|
||||
else
|
||||
@@ -944,7 +1028,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
break;
|
||||
|
||||
case "CYCLE":
|
||||
if (!Main.overview._shown){
|
||||
if (!Main.overview._shown) {
|
||||
if (appHasFocus)
|
||||
cycleThroughWindows(this.app, false, false, monitor);
|
||||
else {
|
||||
@@ -955,7 +1039,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
this.app.activate();
|
||||
break;
|
||||
case "CYCLE-MIN":
|
||||
if (!Main.overview._shown){
|
||||
if (!Main.overview._shown) {
|
||||
if (appHasFocus || (recentlyClickedApp == this.app && recentlyClickedAppWindows[recentlyClickedAppIndex % recentlyClickedAppWindows.length] == "MINIMIZE"))
|
||||
cycleThroughWindows(this.app, false, true, monitor);
|
||||
else {
|
||||
@@ -1044,9 +1128,9 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
|
||||
this._nWindows = windows.length;
|
||||
|
||||
for (let i = 1; i <= MAX_INDICATORS; i++){
|
||||
let className = 'running'+i;
|
||||
if(i != this._nWindows)
|
||||
for (let i = 1; i <= MAX_INDICATORS; i++) {
|
||||
let className = 'running' + i;
|
||||
if (i != this._nWindows)
|
||||
this.remove_style_class_name(className);
|
||||
else
|
||||
this.add_style_class_name(className);
|
||||
@@ -1078,15 +1162,15 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
color = themeNode.get_background_color();
|
||||
|
||||
// theme didn't provide one, use a default
|
||||
if(color.alpha == 0) color = fallbackColor;
|
||||
if (color.alpha == 0) color = fallbackColor;
|
||||
}
|
||||
} else if(SETTINGS.get_boolean('dot-color-override')) {
|
||||
} else if (SETTINGS.get_boolean('dot-color-override')) {
|
||||
let dotColorSettingPrefix = 'dot-color-';
|
||||
|
||||
if(!isFocused && SETTINGS.get_boolean('dot-color-unfocused-different'))
|
||||
if (!isFocused && SETTINGS.get_boolean('dot-color-unfocused-different'))
|
||||
dotColorSettingPrefix = 'dot-color-unfocused-';
|
||||
|
||||
color = Utils.ColorUtils.color_from_string(SETTINGS.get_string(dotColorSettingPrefix + (this._getRunningIndicatorCount() || 1) ))[1];
|
||||
color = Utils.ColorUtils.color_from_string(SETTINGS.get_string(dotColorSettingPrefix + (this._getRunningIndicatorCount() || 1)))[1];
|
||||
} else {
|
||||
// Re-use the style - background color, and border width and color -
|
||||
// of the default dot
|
||||
@@ -1094,7 +1178,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
color = themeNode.get_background_color();
|
||||
|
||||
// theme didn't provide one, use a default
|
||||
if(color.alpha == 0) color = fallbackColor;
|
||||
if (color.alpha == 0) color = fallbackColor;
|
||||
}
|
||||
|
||||
return color;
|
||||
@@ -1175,7 +1259,7 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
let dist;
|
||||
let indicatorSize;
|
||||
let translate;
|
||||
let preDraw = () => {};
|
||||
let preDraw = () => { };
|
||||
let draw;
|
||||
let drawDash = (i, dashLength) => {
|
||||
dist = i * dashLength + i * spacing;
|
||||
@@ -1271,12 +1355,12 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
// Set the font size to something smaller than the whole icon so it is
|
||||
// still visible. The border radius is large to make the shape circular
|
||||
let [minWidth, natWidth] = this._dtpIconContainer.get_preferred_width(-1);
|
||||
let font_size = Math.round(Math.max(12, 0.3 * natWidth) / Utils.getScaleFactor());
|
||||
let font_size = Math.round(Math.max(12, 0.3 * natWidth) / Utils.getScaleFactor());
|
||||
let size = Math.round(font_size * 1.3);
|
||||
let label = bin.child;
|
||||
let style = 'font-size: ' + font_size + 'px;' +
|
||||
'border-radius: ' + this.icon.iconSize + 'px;' +
|
||||
'height: ' + size +'px;';
|
||||
'border-radius: ' + this.icon.iconSize + 'px;' +
|
||||
'height: ' + size + 'px;';
|
||||
|
||||
if (fixedSize || label.get_text().length == 1) {
|
||||
style += 'width: ' + size + 'px;';
|
||||
@@ -1295,9 +1379,9 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
|
||||
toggleNumberOverlay(activate) {
|
||||
if (activate && this._numberOverlayOrder > -1)
|
||||
this._numberOverlayBin.show();
|
||||
this._numberOverlayBin.show();
|
||||
else
|
||||
this._numberOverlayBin.hide();
|
||||
this._numberOverlayBin.hide();
|
||||
}
|
||||
|
||||
handleDragOver(source, actor, x, y, time) {
|
||||
@@ -1312,19 +1396,19 @@ export const TaskbarAppIcon = GObject.registerClass({
|
||||
return getInterestingWindows(this.app, this.dtpPanel.monitor, isolateMonitors);
|
||||
}
|
||||
});
|
||||
TaskbarAppIcon.prototype.scaleAndFade = TaskbarAppIcon.prototype.undoScaleAndFade = () => {};
|
||||
TaskbarAppIcon.prototype.scaleAndFade = TaskbarAppIcon.prototype.undoScaleAndFade = () => { };
|
||||
|
||||
export function minimizeWindow(app, param, monitor){
|
||||
export function minimizeWindow(app, param, monitor) {
|
||||
// Param true make all app windows minimize
|
||||
let windows = getInterestingWindows(app, monitor);
|
||||
let current_workspace = Utils.DisplayWrapper.getWorkspaceManager().get_active_workspace();
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
let w = windows[i];
|
||||
if (w.get_workspace() == current_workspace && w.showing_on_its_workspace()){
|
||||
if (w.get_workspace() == current_workspace && w.showing_on_its_workspace()) {
|
||||
w.minimize();
|
||||
// Just minimize one window. By specification it should be the
|
||||
// focused window on the current workspace.
|
||||
if(!param)
|
||||
if (!param)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1334,7 +1418,7 @@ export function minimizeWindow(app, param, monitor){
|
||||
* By default only non minimized windows are activated.
|
||||
* This activates all windows in the current workspace.
|
||||
*/
|
||||
export function activateAllWindows(app, monitor){
|
||||
export function activateAllWindows(app, monitor) {
|
||||
|
||||
// First activate first window so workspace is switched if needed,
|
||||
// then activate all other app windows in the current workspace.
|
||||
@@ -1346,14 +1430,14 @@ export function activateAllWindows(app, monitor){
|
||||
if (windows.length <= 0)
|
||||
return;
|
||||
|
||||
for (let i = windows.length - 1; i >= 0; i--){
|
||||
if (windows[i].get_workspace().index() == activeWorkspace){
|
||||
for (let i = windows.length - 1; i >= 0; i--) {
|
||||
if (windows[i].get_workspace().index() == activeWorkspace) {
|
||||
Main.activateWindow(windows[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function activateFirstWindow(app, monitor){
|
||||
export function activateFirstWindow(app, monitor) {
|
||||
|
||||
let windows = getInterestingWindows(app, monitor);
|
||||
Main.activateWindow(windows[0]);
|
||||
@@ -1362,11 +1446,11 @@ export function activateFirstWindow(app, monitor){
|
||||
export function cycleThroughWindows(app, reversed, shouldMinimize, monitor) {
|
||||
// Store for a little amount of time last clicked app and its windows
|
||||
// since the order changes upon window interaction
|
||||
let MEMORY_TIME=3000;
|
||||
let MEMORY_TIME = 3000;
|
||||
|
||||
let app_windows = getInterestingWindows(app, monitor);
|
||||
|
||||
if(shouldMinimize)
|
||||
if (shouldMinimize)
|
||||
app_windows.push("MINIMIZE");
|
||||
|
||||
if (recentlyClickedAppLoopId > 0)
|
||||
@@ -1395,7 +1479,7 @@ export function cycleThroughWindows(app, reversed, shouldMinimize, monitor) {
|
||||
}
|
||||
let index = recentlyClickedAppIndex % recentlyClickedAppWindows.length;
|
||||
|
||||
if(recentlyClickedAppWindows[index] === "MINIMIZE")
|
||||
if (recentlyClickedAppWindows[index] === "MINIMIZE")
|
||||
minimizeWindow(app, true, monitor);
|
||||
else
|
||||
Main.activateWindow(recentlyClickedAppWindows[index]);
|
||||
@@ -1405,8 +1489,8 @@ export function resetRecentlyClickedApp() {
|
||||
if (recentlyClickedAppLoopId > 0)
|
||||
GLib.Source.remove(recentlyClickedAppLoopId);
|
||||
|
||||
recentlyClickedAppLoopId=0;
|
||||
recentlyClickedApp =null;
|
||||
recentlyClickedAppLoopId = 0;
|
||||
recentlyClickedApp = null;
|
||||
recentlyClickedAppWindows = null;
|
||||
recentlyClickedAppIndex = 0;
|
||||
recentlyClickedAppMonitorIndex = null;
|
||||
@@ -1424,21 +1508,21 @@ export function closeAllWindows(app, monitor) {
|
||||
// nautilus desktop window.
|
||||
export function getInterestingWindows(app, monitor, isolateMonitors) {
|
||||
let windows = (
|
||||
app ?
|
||||
app ?
|
||||
app.get_windows() :
|
||||
global.get_window_actors().map(wa => wa.get_meta_window())
|
||||
).filter(w => !w.skip_taskbar);
|
||||
).filter(w => !w.skip_taskbar);
|
||||
|
||||
// When using workspace or monitor isolation, we filter out windows
|
||||
// that are not in the current workspace or on the same monitor as the appicon
|
||||
if (SETTINGS.get_boolean('isolate-workspaces'))
|
||||
windows = windows.filter(function(w) {
|
||||
windows = windows.filter(function (w) {
|
||||
return w.get_workspace() &&
|
||||
w.get_workspace() == Utils.getCurrentWorkspace();
|
||||
w.get_workspace() == Utils.getCurrentWorkspace();
|
||||
});
|
||||
|
||||
if (monitor && SETTINGS.get_boolean('multi-monitors') && (isolateMonitors || SETTINGS.get_boolean('isolate-monitors'))) {
|
||||
windows = windows.filter(function(w) {
|
||||
windows = windows.filter(function (w) {
|
||||
return w.get_monitor() == monitor.index;
|
||||
});
|
||||
}
|
||||
@@ -1485,7 +1569,7 @@ export class TaskbarSecondaryMenu extends AppMenu.AppMenu {
|
||||
this._showSingleWindows = true;
|
||||
|
||||
// Remove "Show Details" menu item
|
||||
if(!SETTINGS.get_boolean('secondarymenu-contains-showdetails')) {
|
||||
if (!SETTINGS.get_boolean('secondarymenu-contains-showdetails')) {
|
||||
let existingMenuItems = this._getMenuItems();
|
||||
for (let i = 0; i < existingMenuItems.length; i++) {
|
||||
let item = existingMenuItems[i];
|
||||
@@ -1506,7 +1590,7 @@ export class TaskbarSecondaryMenu extends AppMenu.AppMenu {
|
||||
let count = this.sourceActor.window ? 1 :
|
||||
getInterestingWindows(this._app, this.sourceActor.dtpPanel.monitor).length;
|
||||
|
||||
if ( count > 0) {
|
||||
if (count > 0) {
|
||||
let quitFromTaskbarMenuText = "";
|
||||
if (count == 1)
|
||||
quitFromTaskbarMenuText = _("Quit");
|
||||
@@ -1521,8 +1605,8 @@ export class TaskbarSecondaryMenu extends AppMenu.AppMenu {
|
||||
let time = global.get_current_time()
|
||||
let windows =
|
||||
this.sourceActor.window ? // ungrouped applications
|
||||
[this.sourceActor.window] :
|
||||
getInterestingWindows(this._app, this.sourceActor.dtpPanel.monitor)
|
||||
[this.sourceActor.window] :
|
||||
getInterestingWindows(this._app, this.sourceActor.dtpPanel.monitor)
|
||||
|
||||
if (windows.length == this._app.get_windows().length)
|
||||
this._app.request_quit()
|
||||
@@ -1555,7 +1639,7 @@ export function ItemShowLabel() {
|
||||
let [stageX, stageY] = this.get_transformed_position();
|
||||
let node = this.label.get_theme_node();
|
||||
|
||||
let itemWidth = this.allocation.x2 - this.allocation.x1;
|
||||
let itemWidth = this.allocation.x2 - this.allocation.x1;
|
||||
let itemHeight = this.allocation.y2 - this.allocation.y1;
|
||||
|
||||
let labelWidth = this.label.get_width();
|
||||
@@ -1572,19 +1656,19 @@ export function ItemShowLabel() {
|
||||
let x = stageX + xOffset
|
||||
let y = stageY + (itemHeight - labelHeight) * .5;
|
||||
|
||||
switch(position) {
|
||||
case St.Side.TOP:
|
||||
y = stageY + labelOffset + itemHeight;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
y = stageY - labelHeight - labelOffset;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
x = stageX + labelOffset + itemWidth;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
x = stageX - labelWidth - labelOffset;
|
||||
break;
|
||||
switch (position) {
|
||||
case St.Side.TOP:
|
||||
y = stageY + labelOffset + itemHeight;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
y = stageY - labelHeight - labelOffset;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
x = stageX + labelOffset + itemWidth;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
x = stageX - labelWidth - labelOffset;
|
||||
break;
|
||||
}
|
||||
|
||||
// keep the label inside the screen border
|
||||
@@ -1593,10 +1677,10 @@ export function ItemShowLabel() {
|
||||
// Leave a few pixel gap
|
||||
let gap = LABEL_GAP;
|
||||
let monitor = Main.layoutManager.findMonitorForActor(this);
|
||||
if ( x - monitor.x < gap)
|
||||
if (x - monitor.x < gap)
|
||||
x += monitor.x - x + labelOffset;
|
||||
else if ( x + labelWidth > monitor.x + monitor.width - gap)
|
||||
x -= x + labelWidth -( monitor.x + monitor.width) + gap;
|
||||
else if (x + labelWidth > monitor.x + monitor.width - gap)
|
||||
x -= x + labelWidth - (monitor.x + monitor.width) + gap;
|
||||
|
||||
this.label.set_position(Math.round(x), Math.round(y));
|
||||
|
||||
@@ -1660,11 +1744,13 @@ export const ShowAppsIconWrapper = class extends EventEmitter {
|
||||
|
||||
let customIconPath = SETTINGS.get_string('show-apps-icon-file');
|
||||
|
||||
this.realShowAppsIcon.icon.createIcon = function(size) {
|
||||
this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
|
||||
icon_size: size,
|
||||
style_class: 'show-apps-icon',
|
||||
track_hover: true });
|
||||
this.realShowAppsIcon.icon.createIcon = function (size) {
|
||||
this._iconActor = new St.Icon({
|
||||
icon_name: 'view-app-grid-symbolic',
|
||||
icon_size: size,
|
||||
style_class: 'show-apps-icon',
|
||||
track_hover: true
|
||||
});
|
||||
|
||||
if (customIconPath) {
|
||||
this._iconActor.gicon = new Gio.FileIcon({ file: Gio.File.new_for_path(customIconPath) });
|
||||
@@ -1702,7 +1788,7 @@ export const ShowAppsIconWrapper = class extends EventEmitter {
|
||||
|
||||
_onTouchEvent(actor, event) {
|
||||
if (event.type() == Clutter.EventType.TOUCH_BEGIN)
|
||||
this._setPopupTimeout();
|
||||
this._setPopupTimeout();
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
@@ -1760,7 +1846,7 @@ export const ShowAppsIconWrapper = class extends EventEmitter {
|
||||
|
||||
shouldShowTooltip() {
|
||||
return SETTINGS.get_boolean('show-tooltip') &&
|
||||
(this.actor.hover && (!this._menu || !this._menu.isOpen));
|
||||
(this.actor.hover && (!this._menu || !this._menu.isOpen));
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@@ -1864,7 +1950,7 @@ export const MyShowAppsIconMenu = class extends PopupMenu.PopupMenu {
|
||||
let settingsMenuItem = this._appendMenuItem(_('Dash to Panel Settings'));
|
||||
settingsMenuItem.connect('activate', () => DTP_EXTENSION.openPreferences())
|
||||
|
||||
if(this.sourceActor == Main.layoutManager.dummyCursor) {
|
||||
if (this.sourceActor == Main.layoutManager.dummyCursor) {
|
||||
this._appendSeparator();
|
||||
let item = this._appendMenuItem(this._dtpPanel._restoreWindowList ? _('Restore Windows') : _('Show Desktop'));
|
||||
item.connect('activate', this._dtpPanel._onShowDesktopButtonPress.bind(this._dtpPanel));
|
||||
@@ -1877,7 +1963,7 @@ export const MyShowAppsIconMenu = class extends PopupMenu.PopupMenu {
|
||||
if (GLib.find_program_in_path(info.cmd[0])) {
|
||||
let item = this._appendMenuItem(_(info.title));
|
||||
|
||||
item.connect('activate', function() {
|
||||
item.connect('activate', function () {
|
||||
print("activated: " + info.title);
|
||||
Util.spawn(info.cmd);
|
||||
});
|
||||
@@ -1914,7 +2000,7 @@ export const MyShowAppsIconMenu = class extends PopupMenu.PopupMenu {
|
||||
};
|
||||
|
||||
|
||||
export const getIconContainerStyle = function(isVertical) {
|
||||
export const getIconContainerStyle = function (isVertical) {
|
||||
let style = 'padding: ';
|
||||
|
||||
if (SETTINGS.get_boolean('group-apps')) {
|
||||
|
||||
4
panel.js
4
panel.js
@@ -486,6 +486,8 @@ export const Panel = GObject.registerClass({
|
||||
SETTINGS,
|
||||
[
|
||||
'changed::panel-sizes',
|
||||
'changed::appicon-margin-todesktop',
|
||||
'changed::appicon-margin-toscreenborder',
|
||||
'changed::group-apps'
|
||||
],
|
||||
() => this._resetGeometry()
|
||||
@@ -619,7 +621,7 @@ export const Panel = GObject.registerClass({
|
||||
let x = 0, y = 0;
|
||||
let w = 0, h = 0;
|
||||
|
||||
const panelSize = PanelSettings.getPanelSize(SETTINGS, this.monitor.index);
|
||||
const panelSize = PanelSettings.getPanelSize(SETTINGS, this.monitor.index) + SETTINGS.get_int('appicon-margin-todesktop') + SETTINGS.get_int('appicon-margin-toscreenborder');
|
||||
this.dtpSize = panelSize * scaleFactor;
|
||||
|
||||
if (SETTINGS.get_boolean('stockgs-keep-top-panel') && Main.layoutManager.primaryMonitor == this.monitor) {
|
||||
|
||||
111
prefs.js
111
prefs.js
@@ -168,6 +168,7 @@ const Preferences = class {
|
||||
|
||||
// dialogs
|
||||
this._builder.add_from_file(this._path + '/ui/BoxAnimateAppIconHoverOptions.ui');
|
||||
this._builder.add_from_file(this._path + '/ui/BoxHighlightAppIconHoverOptions.ui');
|
||||
this._builder.add_from_file(this._path + '/ui/BoxDotOptions.ui');
|
||||
this._builder.add_from_file(this._path + '/ui/BoxShowDesktopOptions.ui');
|
||||
this._builder.add_from_file(this._path + '/ui/BoxDynamicOpacityOptions.ui');
|
||||
@@ -226,6 +227,8 @@ const Preferences = class {
|
||||
this._tray_size_timeout = 0;
|
||||
this._leftbox_size_timeout = 0;
|
||||
this._appicon_margin_timeout = 0;
|
||||
this._appicon_margin_todesktop_timeout = 0;
|
||||
this._appicon_margin_toscreenborder_timeout = 0;
|
||||
this._appicon_padding_timeout = 0;
|
||||
this._opacity_timeout = 0;
|
||||
this._tray_padding_timeout = 0;
|
||||
@@ -638,6 +641,14 @@ const Preferences = class {
|
||||
.set_format_value_func((scale, value) => {
|
||||
return value + ' px';
|
||||
});
|
||||
this._builder.get_object('appicon_margin_todesktop_scale')
|
||||
.set_format_value_func((scale, value) => {
|
||||
return value + ' px';
|
||||
});
|
||||
this._builder.get_object('appicon_margin_toscreenborder_scale')
|
||||
.set_format_value_func((scale, value) => {
|
||||
return value + ' px';
|
||||
});
|
||||
|
||||
this._builder.get_object('appicon_padding_scale')
|
||||
.set_format_value_func((scale, value) => {
|
||||
@@ -701,6 +712,12 @@ const Preferences = class {
|
||||
.set_format_value_func((scale, value) => {
|
||||
return ngettext("%d icon", "%d icons", value).format(value);
|
||||
});
|
||||
|
||||
// highlight appicon on hover dialog
|
||||
this._builder.get_object('highlight_appicon_borderradius')
|
||||
.set_format_value_func((scale, value) => {
|
||||
return value + ' px';
|
||||
});
|
||||
}
|
||||
|
||||
_bindSettings() {
|
||||
@@ -1952,11 +1969,14 @@ const Preferences = class {
|
||||
{objectName: 'tray_size_scale', valueName: 'tray-size', range: DEFAULT_FONT_SIZES },
|
||||
{objectName: 'leftbox_size_scale', valueName: 'leftbox-size', range: DEFAULT_FONT_SIZES },
|
||||
{objectName: 'appicon_margin_scale', valueName: 'appicon-margin', range: DEFAULT_MARGIN_SIZES },
|
||||
{objectName: 'appicon_margin_todesktop_scale', valueName: 'appicon-margin-todesktop', range: DEFAULT_MARGIN_SIZES },
|
||||
{objectName: 'appicon_margin_toscreenborder_scale', valueName: 'appicon-margin-toscreenborder', range: DEFAULT_MARGIN_SIZES },
|
||||
{objectName: 'appicon_padding_scale', valueName: 'appicon-padding', range: DEFAULT_MARGIN_SIZES },
|
||||
{objectName: 'tray_padding_scale', valueName: 'tray-padding', range: DEFAULT_PADDING_SIZES },
|
||||
{objectName: 'leftbox_padding_scale', valueName: 'leftbox-padding', range: DEFAULT_PADDING_SIZES },
|
||||
{objectName: 'statusicon_padding_scale', valueName: 'status-icon-padding', range: DEFAULT_PADDING_SIZES },
|
||||
{objectName: 'panel_length_scale', valueName: '', range: LENGTH_MARKS }
|
||||
{objectName: 'panel_length_scale', valueName: '', range: LENGTH_MARKS },
|
||||
{objectName: 'highlight_appicon_borderradius', valueName: 'highlight-appicon-hover-border-radius', range: [ 16, 12, 8, 4, 2, 0 ] },
|
||||
];
|
||||
|
||||
for(const idx in sizeScales) {
|
||||
@@ -2071,6 +2091,71 @@ const Preferences = class {
|
||||
|
||||
});
|
||||
|
||||
this._settings.bind('highlight-appicon-hover',
|
||||
this._builder.get_object('highlight_appicon_hover_switch'),
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
this._settings.bind('highlight-appicon-hover',
|
||||
this._builder.get_object('highlight_appicon_hover_button'),
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
{
|
||||
rgba.parse(this._settings.get_string('highlight-appicon-hover-background-color'));
|
||||
this._builder.get_object('highlight_appicon_color').set_rgba(rgba);
|
||||
this._builder.get_object('highlight_appicon_color').connect('color-set', (button) => {
|
||||
let rgba = button.get_rgba();
|
||||
let css = rgba.to_string();
|
||||
this._settings.set_string('highlight-appicon-hover-background-color', css);
|
||||
});
|
||||
|
||||
rgba.parse(this._settings.get_string('highlight-appicon-pressed-background-color'));
|
||||
this._builder.get_object('pressed_appicon_color').set_rgba(rgba);
|
||||
this._builder.get_object('pressed_appicon_color').connect('color-set', (button) => {
|
||||
let rgba = button.get_rgba();
|
||||
let css = rgba.to_string();
|
||||
this._settings.set_string('highlight-appicon-pressed-background-color', css);
|
||||
});
|
||||
|
||||
let scales = [
|
||||
['highlight_appicon_borderradius', 'highlight-appicon-hover-border-radius'],
|
||||
];
|
||||
|
||||
const updateScale = scale => {
|
||||
let [id, key] = scale;
|
||||
this._builder.get_object(id).set_value(this._settings.get_int(key));
|
||||
};
|
||||
scales.forEach(scale => {
|
||||
updateScale(scale);
|
||||
let [id, key] = scale;
|
||||
this._builder.get_object(id).connect('value-changed', widget => {
|
||||
this._settings.set_int(key, widget.get_value());
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
this._builder.get_object('highlight_appicon_hover_button').connect('clicked', () => {
|
||||
let box = this._builder.get_object('highlight_appicon_hover_options');
|
||||
|
||||
let dialog = this._createPreferencesDialog(_('App icon highlight options'), box, () =>
|
||||
{
|
||||
// restore default settings
|
||||
this._settings.set_value('highlight-appicon-hover-background-color', this._settings.get_default_value('highlight-appicon-hover-background-color'));
|
||||
rgba.parse(this._settings.get_string('highlight-appicon-hover-background-color'));
|
||||
this._builder.get_object('highlight_appicon_color').set_rgba(rgba);
|
||||
this._settings.set_value('highlight-appicon-pressed-background-color', this._settings.get_default_value('highlight-appicon-pressed-background-color'));
|
||||
rgba.parse(this._settings.get_string('highlight-appicon-pressed-background-color'));
|
||||
this._builder.get_object('pressed_appicon_color').set_rgba(rgba);
|
||||
this._settings.set_value('highlight-appicon-hover-border-radius', this._settings.get_default_value('highlight-appicon-hover-border-radius'));
|
||||
this._builder.get_object('highlight_appicon_borderradius').set_value(this._settings.get_int('highlight-appicon-hover-border-radius'));
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
|
||||
});
|
||||
|
||||
this._settings.bind('stockgs-keep-dash',
|
||||
this._builder.get_object('stockgs_dash_switch'),
|
||||
'active',
|
||||
@@ -2323,6 +2408,30 @@ const BuilderScope = GObject.registerClass({
|
||||
});
|
||||
}
|
||||
|
||||
appicon_margin_todesktop_scale_value_changed_cb(scale) {
|
||||
// Avoid settings the size consinuosly
|
||||
if (this._preferences._appicon_margin_todesktop_timeout > 0)
|
||||
GLib.Source.remove(this._preferences._appicon_margin_todesktop_timeout);
|
||||
|
||||
this._preferences._appicon_margin_todesktop_timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => {
|
||||
this._preferences._settings.set_int('appicon-margin-todesktop', scale.get_value());
|
||||
this._preferences._appicon_margin_todesktop_timeout = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
appicon_margin_toscreenborder_scale_value_changed_cb(scale) {
|
||||
// Avoid settings the size consinuosly
|
||||
if (this._preferences._appicon_margin_toscreenborder_timeout > 0)
|
||||
GLib.Source.remove(this._preferences._appicon_margin_toscreenborder_timeout);
|
||||
|
||||
this._preferences._appicon_margin_toscreenborder_timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => {
|
||||
this._preferences._settings.set_int('appicon-margin-toscreenborder', scale.get_value());
|
||||
this._preferences._appicon_margin_toscreenborder_timeout = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
appicon_padding_scale_value_changed_cb(scale) {
|
||||
// Avoid settings the size consinuosly
|
||||
if (this._preferences._appicon_padding_timeout > 0)
|
||||
|
||||
@@ -736,6 +736,16 @@
|
||||
<summary>App icon margin</summary>
|
||||
<description>Set the margin for application icons in the embedded dash.</description>
|
||||
</key>
|
||||
<key type="i" name="appicon-margin-todesktop">
|
||||
<default>0</default>
|
||||
<summary>App icon margin to desktop</summary>
|
||||
<description>Set the margin for application icons in the embedded dash towards the desktop (top margin if panel is on the bottom).</description>
|
||||
</key>
|
||||
<key type="i" name="appicon-margin-toscreenborder">
|
||||
<default>0</default>
|
||||
<summary>App icon margin to screen border</summary>
|
||||
<description>Set the margin for application icons in the embedded dash towards the desktop (bottom margin if panel is on the bottom).</description>
|
||||
</key>
|
||||
<key type="i" name="appicon-padding">
|
||||
<default>4</default>
|
||||
<summary>App icon padding</summary>
|
||||
@@ -796,6 +806,22 @@
|
||||
<default>{'SIMPLE':1,'RIPPLE':1.25,'PLANK':2}</default>
|
||||
<summary>App icon hover animation zoom scale in relation to the app icon size</summary>
|
||||
</key>
|
||||
<key type="b" name="highlight-appicon-hover">
|
||||
<default>true</default>
|
||||
<summary>Highlight app icon on hover</summary>
|
||||
</key>
|
||||
<key type="s" name="highlight-appicon-hover-background-color">
|
||||
<default>"rgba(238, 238, 236, 0.1)"</default>
|
||||
<summary>Highlight color</summary>
|
||||
</key>
|
||||
<key type="s" name="highlight-appicon-pressed-background-color">
|
||||
<default>"rgba(238, 238, 236, 0.18)"</default>
|
||||
<summary>Mouse down highlight color</summary>
|
||||
</key>
|
||||
<key type="i" name="highlight-appicon-hover-border-radius">
|
||||
<default>0</default>
|
||||
<summary>Highlight border radius</summary>
|
||||
</key>
|
||||
<key type="b" name="secondarymenu-contains-appmenu">
|
||||
<default>true</default>
|
||||
<summary>Integrate items from the gnome appmenu into the right click menu</summary>
|
||||
|
||||
@@ -39,22 +39,34 @@
|
||||
}
|
||||
|
||||
#dashtopanelScrollview .overview-tile:hover .dtp-container,
|
||||
#dashtopanelScrollview .overview-tile:focus .dtp-container,
|
||||
#dashtopanelScrollview .overview-tile:focus .dtp-container {
|
||||
background-color: rgba(238, 238, 236, 0.1);
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
#dashtopanelScrollview .overview-tile:hover .dtp-container > .dtp-dots-container,
|
||||
#dashtopanelScrollview .overview-tile:focus .dtp-container > .dtp-dots-container {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.dashtopanelMainPanel .dash-item-container .show-apps:hover {
|
||||
background-color: rgba(238, 238, 238, 0.1);
|
||||
}
|
||||
|
||||
.dashtopanelMainPanel .dash-item-container .show-apps .overview-icon {
|
||||
color: #FFF;
|
||||
}
|
||||
.dashtopanelMainPanel .dash-item-container .show-apps:hover .overview-icon {
|
||||
background: none;
|
||||
}
|
||||
|
||||
#dashtopanelTaskbar .dash-item-container .overview-tile:hover,
|
||||
#dashtopanelTaskbar .dash-item-container .overview-tile .dtp-container .overview-icon,
|
||||
#dashtopanelScrollview .overview-tile:hover .dtp-container.animate-appicon-hover,
|
||||
.dashtopanelMainPanel .dash-item-container .show-apps:hover .overview-icon {
|
||||
#dashtopanelScrollview .overview-tile:hover .dtp-container.no-highlight,
|
||||
#dashtopanelScrollview .overview-tile:focus .dtp-container.no-highlight {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
#dashtopanelScrollview .overview-tile:active .dtp-container {
|
||||
background-color: rgba(238, 238, 236, 0.18);
|
||||
}
|
||||
|
||||
10
taskbar.js
10
taskbar.js
@@ -153,11 +153,11 @@ const iconAnimationSettings = {
|
||||
},
|
||||
|
||||
get travel() {
|
||||
return Math.max(0, this._getDictValue('animate-appicon-hover-animation-travel'));
|
||||
return Math.max(-1, this._getDictValue('animate-appicon-hover-animation-travel'));
|
||||
},
|
||||
|
||||
get zoom() {
|
||||
return Math.max(1, this._getDictValue('animate-appicon-hover-animation-zoom'));
|
||||
return Math.max(0.5, this._getDictValue('animate-appicon-hover-animation-zoom'));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1446,7 +1446,7 @@ export const TaskbarItemContainer = GObject.registerClass({
|
||||
|
||||
let travel = iconAnimationSettings.travel;
|
||||
let zoom = iconAnimationSettings.zoom;
|
||||
return this._dtpPanel.dtpSize * (travel + (zoom - 1) / 2);
|
||||
return this._dtpPanel.dtpSize * Math.max(0, travel + (zoom - 1) / 2);
|
||||
}
|
||||
|
||||
_updateCloneContainerPosition(cloneContainer) {
|
||||
@@ -1542,10 +1542,10 @@ export const TaskbarItemContainer = GObject.registerClass({
|
||||
let translationMax = (vertical ? width : height) * (travel + (zoom - 1) / 2);
|
||||
let translationEnd = translationMax * level;
|
||||
let translationDone = vertical ? this._raisedClone.translation_x : this._raisedClone.translation_y;
|
||||
let translationTodo = Math.abs(translationEnd - translationDone);
|
||||
let translationTodo = Math.sign(travel)*Math.abs(translationEnd - translationDone);
|
||||
let scale = 1 + (zoom - 1) * level;
|
||||
let rotationAngleZ = rotationDirection * rotation * level;
|
||||
let time = duration * translationTodo / translationMax;
|
||||
let time = Math.abs(duration * translationTodo / translationMax);
|
||||
|
||||
let options = {
|
||||
scale_x: scale, scale_y: scale,
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
</object>
|
||||
|
||||
<object class="GtkAdjustment" id="animate_appicon_hover_options_travel_adjustment">
|
||||
<property name="lower">0</property>
|
||||
<property name="lower">-100</property>
|
||||
<property name="upper">100</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">5</property>
|
||||
</object>
|
||||
|
||||
<object class="GtkAdjustment" id="animate_appicon_hover_options_zoom_adjustment">
|
||||
<property name="lower">100</property>
|
||||
<property name="lower">10</property>
|
||||
<property name="upper">250</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">5</property>
|
||||
|
||||
70
ui/BoxHighlightAppIconHoverOptions.ui
Normal file
70
ui/BoxHighlightAppIconHoverOptions.ui
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
|
||||
<!-- adjustments -->
|
||||
<object class="GtkAdjustment" id="highlight_appicon_borderradius_adjustment">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">10</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">2</property>
|
||||
</object>
|
||||
|
||||
<object class="GtkBox" id="highlight_appicon_hover_options">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="width-request">600</property>
|
||||
<property name="spacing">24</property>
|
||||
<property name="margin-top">32</property>
|
||||
<property name="margin-bottom">32</property>
|
||||
<property name="margin-start">32</property>
|
||||
<property name="margin-end">32</property>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Highlight AppIcon color</property>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="highlight_appicon_color">
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use_alpha">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Pressed AppIcon color</property>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="pressed_appicon_color">
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use_alpha">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Highlight AppIcon border radius</property>
|
||||
<property name="subtitle" translatable="yes">(default is 0)</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="highlight_appicon_borderradius">
|
||||
<property name="width-request">300</property>
|
||||
<property name="adjustment">highlight_appicon_borderradius_adjustment</property>
|
||||
<property name="round_digits">0</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="value_pos">right</property>
|
||||
<property name="draw_value">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
|
||||
</object>
|
||||
|
||||
</interface>
|
||||
@@ -52,7 +52,7 @@
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Override Show Desktop line color</property>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="override_show_desktop_line_color_colorbutton">>
|
||||
<object class="GtkColorButton" id="override_show_desktop_line_color_colorbutton">
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use_alpha">True</property>
|
||||
|
||||
@@ -9,6 +9,20 @@
|
||||
<property name="page_increment">0.1</property>
|
||||
</object>
|
||||
|
||||
<object class="GtkAdjustment" id="appicon_margin_todesktop_adjustment">
|
||||
<property name="lower">0.33</property>
|
||||
<property name="upper">1</property>
|
||||
<property name="step_increment">0.01</property>
|
||||
<property name="page_increment">0.1</property>
|
||||
</object>
|
||||
|
||||
<object class="GtkAdjustment" id="appicon_margin_toscreenborder_adjustment">
|
||||
<property name="lower">0.33</property>
|
||||
<property name="upper">1</property>
|
||||
<property name="step_increment">0.01</property>
|
||||
<property name="page_increment">0.1</property>
|
||||
</object>
|
||||
|
||||
<object class="GtkAdjustment" id="appicon_padding_adjustment">
|
||||
<property name="lower">0.33</property>
|
||||
<property name="upper">1</property>
|
||||
@@ -61,6 +75,42 @@
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">App Icon Margin Towards Desktop</property>
|
||||
<property name="subtitle" translatable="yes">(default is 0)</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="appicon_margin_todesktop_scale">
|
||||
<property name="width-request">300</property>
|
||||
<property name="adjustment">appicon_margin_todesktop_adjustment</property>
|
||||
<property name="round_digits">0</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="value_pos">right</property>
|
||||
<property name="draw_value">True</property>
|
||||
<signal name="value-changed" handler="appicon_margin_todesktop_scale_value_changed_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">App Icon Margin Towards Screen Border</property>
|
||||
<property name="subtitle" translatable="yes">(default is 0)</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="appicon_margin_toscreenborder_scale">
|
||||
<property name="width-request">300</property>
|
||||
<property name="adjustment">appicon_margin_toscreenborder_adjustment</property>
|
||||
<property name="round_digits">0</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="value_pos">right</property>
|
||||
<property name="draw_value">True</property>
|
||||
<signal name="value-changed" handler="appicon_margin_toscreenborder_scale_value_changed_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">App Icon Padding</property>
|
||||
@@ -104,6 +154,31 @@
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Highlight hovering app icons</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="highlight_appicon_hover_button">
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="highlight_appicon_hover_options_image">
|
||||
<property name="icon_name">emblem-system-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="highlight_appicon_hover_switch">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Icon style</property>
|
||||
|
||||
Reference in New Issue
Block a user