diff --git a/Settings.ui b/Settings.ui
index ed7ef905..09b45bb2 100644
--- a/Settings.ui
+++ b/Settings.ui
@@ -4331,6 +4331,16 @@
5
10
+
+
+
+
+
True
diff --git a/appIcons.js b/appIcons.js
index e79eae89..469ed525 100644
--- a/appIcons.js
+++ b/appIcons.js
@@ -250,6 +250,7 @@ var taskbarAppIcon = Utils.defineClass({
Me.settings.connect('changed::focus-highlight', Lang.bind(this, this._settingsChangeRefresh)),
Me.settings.connect('changed::focus-highlight-dominant', Lang.bind(this, this._settingsChangeRefresh)),
Me.settings.connect('changed::focus-highlight-color', Lang.bind(this, this._settingsChangeRefresh)),
+ Me.settings.connect('changed::focus-dominant-color', Lang.bind(this, this._settingsChangeRefresh)),
Me.settings.connect('changed::focus-highlight-opacity', Lang.bind(this, this._settingsChangeRefresh)),
Me.settings.connect('changed::group-apps-label-font-size', Lang.bind(this, this._updateWindowTitleStyle)),
Me.settings.connect('changed::group-apps-label-font-weight', Lang.bind(this, this._updateWindowTitleStyle)),
@@ -606,7 +607,15 @@ var taskbarAppIcon = Utils.defineClass({
let highlightColor = this._getFocusHighlightColor();
inlineStyle += "background-color: " + cssHexTocssRgba(highlightColor, Me.settings.get_int('focus-highlight-opacity') * 0.01);
}
-
+
+ if (this._checkIfFocusedApp() && !this.isLauncher &&
+ (!this.window || isFocused) && !this._isThemeProvidingIndicator() && this._checkIfMonitorHasFocus()){
+ let dominantColor = this._getAppDominantColor();
+ if (dominantColor && this.parentPanelColor != dominantColor){
+ global.dashToPanel.emit('changed::focus-dominant-color', dominantColor);
+ }
+
+ }
if(this._dotsContainer.get_style() != inlineStyle && this._dotsContainer.mapped) {
if (!this._isGroupApps) {
//when the apps are ungrouped, set the style synchronously so the icons don't jump around on taskbar redraw
@@ -1083,11 +1092,17 @@ var taskbarAppIcon = Utils.defineClass({
return color;
},
+ _getAppDominantColor: function() {
+ let dce = new Utils.DominantColorExtractor(this.app);
+ let palette = dce._getColorPalette();
+ if (palette) return palette.original;
+ return undefined;
+ },
+
_getFocusHighlightColor: function() {
if (Me.settings.get_boolean('focus-highlight-dominant')) {
- let dce = new Utils.DominantColorExtractor(this.app);
- let palette = dce._getColorPalette();
- if (palette) return palette.original;
+ let domColor = this._getAppDominantColor();
+ if (domColor !== undefined) return domColor;
}
return Me.settings.get_string('focus-highlight-color');
},
diff --git a/prefs.js b/prefs.js
index 30407876..ec9a701a 100644
--- a/prefs.js
+++ b/prefs.js
@@ -965,6 +965,16 @@ const Preferences = new Lang.Class({
this._builder.get_object('trans_bg_color_colorbutton'),
'sensitive',
Gio.SettingsBindFlags.DEFAULT);
+
+ this._settings.bind('trans-use-dominant-icon-color',
+ this._builder.get_object('trans_bg_icon_switch'),
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT);
+
+ this._settings.bind('trans-apply-dominant-color-to-preview',
+ this._builder.get_object('trans_bg_icon_preview_switch'),
+ 'active',
+ Gio.SettingsBindFlags.DEFAULT);
let rgba = new Gdk.RGBA();
rgba.parse(this._settings.get_string('trans-bg-color'));
@@ -997,6 +1007,30 @@ const Preferences = new Lang.Class({
this._settings.set_double('trans-panel-opacity', widget.get_value() * 0.01);
}));
+ this._builder.get_object('trans_bg_icon_brightness_spinbutton').set_value(this._settings.get_double('trans-panel-dominant-color-brightness') * 100);
+ this._builder.get_object('trans_bg_icon_brightness_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
+ if (widget.get_value() < 1){
+ // Somehow fixes bug that resets brightness to 0.5 when user sets to 0
+ this._settings.set_double('trans-panel-dominant-color-brightness', 0.001);
+ }
+ else
+ {
+ this._settings.set_double('trans-panel-dominant-color-brightness', widget.get_value() * 0.01);
+ }
+ }));
+
+ this._builder.get_object('trans_bg_icon_preview_brightness_spinbutton').set_value(this._settings.get_double('trans-preview-dominant-color-brightness') * 100);
+ this._builder.get_object('trans_bg_icon_preview_brightness_spinbutton').connect('value-changed', Lang.bind(this, function (widget) {
+ if (widget.get_value() < 1){
+ // Somehow fixes bug that resets brightness to 0.5 when user sets to 0
+ this._settings.set_double('trans-preview-dominant-color-brightness', 0.001);
+ }
+ else
+ {
+ this._settings.set_double('trans-preview-dominant-color-brightness', widget.get_value() * 0.01);
+ }
+ }));
+
this._settings.bind('trans-use-dynamic-opacity',
this._builder.get_object('trans_dyn_switch'),
'active',
diff --git a/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml b/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml
index 7e8ea3a9..2fb33ad2 100644
--- a/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml
@@ -239,6 +239,16 @@
Override theme background color
Replace current theme background color for the panel
+
+ false
+ Override panel theme background color with dominant icon color
+ Replace current theme background color for the panel with the dominant color of the focused app icon. Falls back to overridden background color or theme color if no app is focused or if the Activities overlay is opened.
+
+
+ false
+ Apply to window preview
+ Apply dominant color to window preview
+
"#000"
Custom background color
@@ -259,6 +269,16 @@
Panel opacity
Custom opacity for the panel
+
+ 0.5
+ Panel dominant color brightness
+ Modify brightness of dominant color of app icon used as panel background color
+
+
+ 0.15
+ Window preview dominant color brightness
+ Modify brightness of dominant color of app icon used as window preview background color
+
'ALL_WINDOWS'
Dynamic opacity behavior
diff --git a/taskbar.js b/taskbar.js
index 4f74d1ef..5f4b702f 100644
--- a/taskbar.js
+++ b/taskbar.js
@@ -391,6 +391,13 @@ var taskbar = Utils.defineClass({
'notify::pageSize'
],
() => this._onScrollSizeChange(adjustment)
+ ],
+ [
+ global.dashToPanel,
+ 'changed::focus-dominant-color',
+ Lang.bind(this, function(_, color){
+ this._updatePanelAppColor(color);
+ })
]
);
@@ -689,9 +696,9 @@ var taskbar = Utils.defineClass({
}
appIcon.connect('menu-state-changed',
- Lang.bind(this, function(appIcon, opened) {
- this._itemMenuStateChanged(item, opened);
- }));
+ Lang.bind(this, function(appIcon, opened) {
+ this._itemMenuStateChanged(item, opened);
+ }));
let item = new TaskbarItemContainer();
@@ -700,6 +707,11 @@ var taskbar = Utils.defineClass({
item.setChild(appIcon.actor);
appIcon._dashItemContainer = item;
+ this._signalsHandler.add(
+ global.dashToPanel,
+ 'changed::focus-dominant-color',
+ (_, color) => appIcon.parentPanelColor = this.dtpPanel.dynamicTransparency.currentBackgroundAppColor
+ );
appIcon.actor.connect('notify::hover', Lang.bind(this, function() {
if (appIcon.actor.hover){
@@ -739,7 +751,7 @@ var taskbar = Utils.defineClass({
appIcon._menu._boxPointer.yOffset = -y_shift;
}
}));
-
+
// Override default AppIcon label_actor, now the
// accessible_name is set at DashItemContainer.setLabelText
appIcon.actor.label_actor = null;
@@ -751,6 +763,12 @@ var taskbar = Utils.defineClass({
return item;
},
+ _updatePanelAppColor: function (color){
+ if (color){
+ this.dtpPanel.dynamicTransparency.setBackgroundColorToAppColor(color);
+ }
+ },
+
// Return an array with the "proper" appIcons currently in the taskbar
_getAppIcons: function() {
// Only consider children which are "proper" icons and which are not
diff --git a/transparency.js b/transparency.js
index aa86d7ac..308cec26 100644
--- a/transparency.js
+++ b/transparency.js
@@ -26,6 +26,9 @@ const Me = imports.misc.extensionUtils.getCurrentExtension();
const Panel = Me.imports.panel;
const Proximity = Me.imports.proximity;
const Utils = Me.imports.utils;
+const Shell = imports.gi.Shell;
+
+let tracker = Shell.WindowTracker.get_default();
var DynamicTransparency = Utils.defineClass({
Name: 'DashToPanel.DynamicTransparency',
@@ -49,6 +52,18 @@ var DynamicTransparency = Utils.defineClass({
this._updateAnimationDuration();
this._updateAllAndSet();
this._updateProximityWatch();
+
+ this._focusWindowChangedId = global.display.connect('notify::focus-window',
+ Lang.bind(this, this._onFocusAppChanged));
+ },
+
+ _onDestroy: function(){
+ if(this._focusWindowChangedId)
+ global.display.disconnect(this._focusWindowChangedId);
+ },
+
+ _onFocusAppChanged: function(){
+ this._updateColorAndSet();
},
destroy: function() {
@@ -87,7 +102,11 @@ var DynamicTransparency = Utils.defineClass({
Me.settings,
[
'changed::trans-use-custom-bg',
- 'changed::trans-bg-color'
+ 'changed::trans-bg-color',
+ 'changed::trans-use-dominant-icon-color',
+ 'changed::trans-panel-dominant-color-brightness',
+ 'changed::trans-apply-dominant-color-to-preview',
+ 'changed::trans-preview-dominant-color-brightness'
],
() => this._updateColorAndSet()
],
@@ -186,10 +205,51 @@ var DynamicTransparency = Utils.defineClass({
this._complementaryStyles = 'border-radius: ' + panelThemeNode.get_border_radius(0) + 'px;';
},
+ _linearLight: function(color, value){
+ let applyBlend = function(comp){
+ let comp01 = comp/256; // Scale from 0-256 to 0-1
+ return ((value > 0.5)*(comp01 + 2*(value-0.5)) + (value <= 0.5)*(comp01 + 2*value-1))*256
+ }
+ return {
+ red: applyBlend(color.red),
+ green: applyBlend(color.green),
+ blue: applyBlend(color.blue)
+ }
+ },
+
+ _modifyColorToDominantAppColor: function(inputColor, overrideValue){
+ let outputColor = inputColor;
+ if (Me.settings.get_boolean('trans-use-dominant-icon-color') && this.currentBackgroundAppColor){
+ outputColor = this.currentBackgroundAppColor;
+ outputColor = Utils.getrgbColor(outputColor) // Convert to RGB object
+
+ let blendValue = overrideValue || Me.settings.get_double('trans-panel-dominant-color-brightness') || 0.5;
+
+ // Apply Linear Light blending (black if value is 0, white if value is 1, same color as input if value is 0.5)
+ outputColor = this._linearLight(outputColor, blendValue);
+ }
+ return outputColor;
+ },
+
_updateColor: function(themeBackground) {
- this.backgroundColorRgb = Me.settings.get_boolean('trans-use-custom-bg') ?
- Me.settings.get_string('trans-bg-color') :
- (themeBackground || this._getThemeBackground());
+ this.backgroundColorRgb = (themeBackground || this._getThemeBackground());
+ this.backgroundColorRgbPreview = this.backgroundColorRgb;
+ if (Me.settings.get_boolean('trans-use-custom-bg')){
+ this.backgroundColorRgb = Me.settings.get_string('trans-bg-color');
+ this.backgroundColorRgbPreview = this.backgroundColorRgb;
+ }
+ if (Me.settings.get_boolean('trans-apply-dominant-color-to-preview') && tracker.focus_app){
+ let prevBgColor = this.backgroundColorRgb;
+ this.backgroundColorRgb = this._modifyColorToDominantAppColor(this.backgroundColorRgb);
+ this.backgroundColorRgbPreview = this._modifyColorToDominantAppColor(
+ prevBgColor,
+ Me.settings.get_double('trans-preview-dominant-color-brightness')
+ );
+ }
+ else if (tracker.focus_app)
+ {
+ this.backgroundColorRgb = this._modifyColorToDominantAppColor(this.backgroundColorRgb);
+ }
},
_updateAlpha: function(themeBackground) {
@@ -214,12 +274,16 @@ var DynamicTransparency = Utils.defineClass({
}
},
+ setBackgroundColorToAppColor: function(color){
+ this.currentBackgroundAppColor = Utils.getrgbaColor(color, this.alpha);
+ this._updateColorAndSet();
+ },
+
_setBackground: function() {
this.currentBackgroundColor = Utils.getrgbaColor(this.backgroundColorRgb, this.alpha);
let transition = 'transition-duration:' + this.animationDuration;
let cornerStyle = '-panel-corner-background-color: ' + this.currentBackgroundColor + transition;
-
this._dtpPanel.set_style('background-color: ' + this.currentBackgroundColor + transition + this._complementaryStyles);
if (this._dtpPanel.geom.position == St.Side.TOP) {
diff --git a/windowPreview.js b/windowPreview.js
index 45d08a04..ebf87dbb 100644
--- a/windowPreview.js
+++ b/windowPreview.js
@@ -193,7 +193,7 @@ var PreviewMenu = Utils.defineClass({
this.set_height(this.clipHeight);
this.menu.show();
- setStyle(this.menu, 'background: ' + Utils.getrgbaColor(this.panel.dynamicTransparency.backgroundColorRgb, alphaBg));
+ setStyle(this.menu, 'background: ' + Utils.getrgbaColor(this.panel.dynamicTransparency.backgroundColorRgbPreview, alphaBg));
}
this._mergeWindows(appIcon);
@@ -519,8 +519,8 @@ var PreviewMenu = Utils.defineClass({
_getFadeWidget: function(end) {
let x = 0, y = 0;
- let startBg = Utils.getrgbaColor(this.panel.dynamicTransparency.backgroundColorRgb, Math.min(alphaBg + .1, 1));
- let endBg = Utils.getrgbaColor(this.panel.dynamicTransparency.backgroundColorRgb, 0)
+ let startBg = Utils.getrgbaColor(this.panel.dynamicTransparency.backgroundColorRgbPreview, Math.min(alphaBg + .1, 1));
+ let endBg = Utils.getrgbaColor(this.panel.dynamicTransparency.backgroundColorRgbPreview, 0)
let fadeStyle = 'background-gradient-start:' + startBg +
'background-gradient-end:' + endBg +
'background-gradient-direction:' + this.panel.getOrientation();
@@ -997,7 +997,7 @@ var Preview = Utils.defineClass({
alpha = alphaBg;
}
- return Utils.getrgbaColor(this._previewMenu.panel.dynamicTransparency.backgroundColorRgb, alpha, offset);
+ return Utils.getrgbaColor(this._previewMenu.panel.dynamicTransparency.backgroundColorRgbPreview, alpha, offset);
},
_addClone: function(newCloneBin, animateSize) {