Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions data/org.cinnamon.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@
</description>
</key>

<key name="panels-dodge-all" type="as">
<default>['1:false']</default>
<summary>Panel dodges the current active window when autohide is enabled</summary>
<description>Only dodge the active window rather than dodging all windows</description>
</key>

<key name="panels-show-delay" type="as">
<default>['1:0']</default>
<summary>Duration of the delay before a hidden panel is shown</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ def can_show(vlist, possible):
if item.split(":")[0] == panel_id:
return item.split(":")[1] != "false"

def can_show_dodge_all(vlist, possible):
for item in vlist:
if item.split(":")[0] == panel_id:
return item.split(":")[1] == "intel"

section = SettingsSection(_("Panel Visibility"))
self.add(section)

Expand All @@ -61,6 +66,9 @@ def can_show(vlist, possible):
widget = PanelComboBox(_("Auto-hide panel"), "org.cinnamon", "panels-autohide", self.panel_id, options, size_group=self.size_group)
section.add_row(widget)

widget = PanelSwitch(_("Include non-focased windows"), "org.cinnamon", "panels-dodge-all", self.panel_id)
section.add_reveal_row(widget, "org.cinnamon", "panels-autohide", check_func=can_show_dodge_all)

widget = PanelSpinButton(_("Show delay"), "org.cinnamon", "panels-show-delay", self.panel_id, _("milliseconds"), 0, 2000, 50, 200)#, dep_key="org.cinnamon/panels-autohide")
section.add_reveal_row(widget, "org.cinnamon", "panels-autohide", check_func=can_show)

Expand Down
143 changes: 99 additions & 44 deletions js/ui/panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ const DEFAULT_PANEL_VALUES = {
"panels-autohide": "false",
"panels-show-delay": "0",
"panels-hide-delay": "0",
"panels-height": "40"
"panels-height": "40",
"panels-dodge-all": "false"
};

const DEFAULT_FULLCOLOR_ICON_SIZE_VALUES = {
Expand Down Expand Up @@ -73,6 +74,7 @@ const MIN_TEXT_SIZE_PTS = 6.0;
const MAX_TEXT_SIZE_PTS = 16.0;

const PANEL_AUTOHIDE_KEY = "panels-autohide";
const PANEL_DODGE_KEY = "panels-dodge-all";
const PANEL_SHOW_DELAY_KEY = "panels-show-delay";
const PANEL_HIDE_DELAY_KEY = "panels-hide-delay";
const PANEL_HEIGHT_KEY = "panels-height";
Expand Down Expand Up @@ -1604,6 +1606,7 @@ var Panel = GObject.registerClass({
this.connect('queue-relayout', () => this._setPanelHeight());

this._signalManager.connect(global.settings, "changed::" + PANEL_AUTOHIDE_KEY, this._processPanelAutoHide, this);
this._signalManager.connect(global.settings, "changed::" + PANEL_DODGE_KEY, this._processPanelAutoHide, this);
this._signalManager.connect(global.settings, "changed::" + PANEL_HEIGHT_KEY, this._moveResizePanel, this);
this._signalManager.connect(global.settings, "changed::" + PANEL_ZONE_ICON_SIZES, this._onPanelZoneSizesChanged, this);
this._signalManager.connect(global.settings, "changed::" + PANEL_ZONE_SYMBOLIC_ICON_SIZES, this._onPanelZoneSizesChanged, this);
Expand Down Expand Up @@ -2104,16 +2107,23 @@ var Panel = GObject.registerClass({

_processPanelAutoHide() {
this._autohideSettings = this._getProperty(PANEL_AUTOHIDE_KEY, "s");
this._dodgeAll = this._getProperty(PANEL_DODGE_KEY, "s");

if (this._autohideSettings == "intel") {
this._signalManager.connect(global.display, "notify::focus-window", this._onFocusChanged, this);
/* focus-window signal is emitted when the workspace change
* animation starts. When the animation ends, we do the position
* check again because the windows have moved. We cannot use
* _onFocusChanged because _onFocusChanged does nothing when there
* is no actual focus change. */
this._signalManager.connect(global.window_manager, "switch-workspace-complete", this._updatePanelVisibility, this);
this._onFocusChanged();
if (this._dodgeAll == "false") {
this._signalManager.connect(global.display, "notify::focus-window", this._onFocusChanged, this);
/* focus-window signal is emitted when the workspace change
* animation starts. When the animation ends, we do the position
* check again because the windows have moved. We cannot use
* _onFocusChanged because _onFocusChanged does nothing when there
* is no actual focus change. */
this._signalManager.connect(global.window_manager, "switch-workspace-complete", this._updatePanelVisibility, this);
this._onFocusChanged();
} else {
this._signalManager.connect(global.display, "notify::focus-window", this._onFocusChanged, this);
this._signalManager.connect(global.window_group, "actor-removed", this._updatePanelVisibility, this);
this._signalManager.connect(global.window_group, "actor-added", this._updatePanelVisibility, this);
}
} else {
this._signalManager.disconnect("notify::focus-window");
this._signalManager.disconnect("switch-workspace-complete");
Expand Down Expand Up @@ -2954,14 +2964,58 @@ var Panel = GObject.registerClass({
return false;
}

/**
* _panelPositionOverlap:
*
* Returns true if the panel overlaps the given window, false if it does not.
*/
_panelPositionHasOverlap: function(meta) {
/* Calculate the x or y instead of getting it from the actor since the
* actor might be hidden */
let x, y;
switch (this.panelPosition) {
case PanelLoc.top:
y = this.monitor.y;
break;
case PanelLoc.bottom:
y = this.monitor.y + this.monitor.height - this.actor.height;
break;
case PanelLoc.left:
x = this.monitor.x;
break;
case PanelLoc.right:
x = this.monitor.x + this.monitor.width - this.actor.width;
break;
default:
global.log("updatePanelVisibility - unrecognised panel position "+this.panelPosition);
}

/* Magic to check whether the panel position overlaps with the
* current focused window*/
let a = this.actor;
let b = meta.get_frame_rect();
if (this.panelPosition == PanelLoc.top || this.panelPosition == PanelLoc.bottom) {
show = (Math.max(a.x, b.x) < Math.min(a.x + a.width, b.x + b.width) &&
Math.max(y, b.y) < Math.min(y + a.height, b.y + b.height));
} else {
show = (Math.max(x, b.x) < Math.min(x + a.width, b.x + b.width) &&
Math.max(a.y, b.y) < Math.min(a.y + a.height, b.y + b.height));
}

return show;
},

/**
* _updatePanelVisibility:
*
* Checks whether the panel should show based on the autohide settings and
* position of mouse/active window. It then calls the _queueShowHidePanel
* function to show or hide the panel as necessary.
*
* true = autohide, false = always show, intel = Intelligent
* true = autohide,
* false = always show,
* intel = Intelligent (dodge active window),
* dodgeall = Itelligent (dodge all windows)
*/
_updatePanelVisibility() {
this._mouseEntered = this._mouseOnPanel();
Expand All @@ -2976,49 +3030,50 @@ var Panel = GObject.registerClass({
case "true":
this._shouldShow = this._mouseEntered;
break;
default:
if (this._mouseEntered || !global.display.focus_window ||
global.display.focus_window.get_window_type() == Meta.WindowType.DESKTOP) {
case "intel":
if (this._mouseEntered) {
this._shouldShow = true;
break;
}

if (global.display.focus_window.get_monitor() != this.monitorIndex) {
this._shouldShow = false;
break;
}
let x, y;

/* Calculate the x or y instead of getting it from the actor since the
* actor might be hidden*/
switch (this.panelPosition) {
case PanelLoc.top:
y = this.monitor.y;
if (this._dodgeAll == "false") {
if (!global.display.focus_window || global.display.focus_window.minimized ||
global.display.focus_window.get_window_type() == Meta.WindowType.DESKTOP) {
this._shouldShow = true;
break;
case PanelLoc.bottom:
y = this.monitor.y + this.monitor.height - this.get_height();
break;
case PanelLoc.left:
x = this.monitor.x;
break;
case PanelLoc.right:
x = this.monitor.x + this.monitor.width - this.get_width();
}

if (global.display.focus_window.get_monitor() != this.monitorIndex) {
this._shouldShow = false;
break;
default:
global.log("updatePanelVisibility - unrecognised panel position "+this.panelPosition);
}
}

let rect = global.display.focus_window.get_frame_rect();
/* Magic to check whether the panel position overlaps with the
* current focused window */
if (this.panelPosition == PanelLoc.top || this.panelPosition == PanelLoc.bottom) {
this._shouldShow = !(Math.max(this.x, rect.x) < Math.min(this.x + this.get_width(), rect.x + rect.width) &&
Math.max(y, rect.y) < Math.min(y + this.get_height(), rect.y + rect.height));
this._shouldShow = !(this._panelPositionHasOverlap(global.display.focus_window));
} else {
this._shouldShow = !(Math.max(x, rect.x) < Math.min(x + this.get_width(), rect.x + rect.width) &&
Math.max(this.y, rect.y) < Math.min(this.y + this.get_height(), rect.y + rect.height));
}
// Assume the panel should be shown
this._shouldShow = true;

let actors = global.get_window_actors();
let currentWorkspaceIndex = global.workspace_manager.get_active_workspace_index();
for (let i = 0; i < actors.length; i++) {
let window = actors[i];
let metaWin = window.get_meta_window();
let winWorkspace = metaWin.get_workspace();
let onCurrentWorkspace = (winWorkspace && winWorkspace.index() === currentWorkspaceIndex);

if (metaWin === null || metaWin.get_window_type() == Meta.WindowType.DESKTOP ||
!onCurrentWorkspace || metaWin.minimized ||
metaWin.get_monitor() !== this.monitorIndex) {
continue;
}

// Exit loop if previous assumption that panel should be shown is wrong
if (this._panelPositionHasOverlap(metaWin) == true) {
this._shouldShow = false;
break;
}
}
}
} // end of switch on autohidesettings
}

Expand Down
Loading