Skip to content
Open
Changes from all commits
Commits
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
70 changes: 25 additions & 45 deletions dock.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,17 +526,12 @@ export let Dock = GObject.registerClass(
if (baseIcon.icon) return baseIcon.icon;
// GNOME 50: try _iconBin.child
if (baseIcon._iconBin && baseIcon._iconBin.child) return baseIcon._iconBin.child;
// Force icon creation if not yet initialized
try {
if (baseIcon.setIconSize) {
let size = (typeof baseIcon.iconSize === 'number' && baseIcon.iconSize > 0) ? baseIcon.iconSize : 48;
baseIcon._createIconTexture(size);
if (baseIcon.icon) return baseIcon.icon;
if (baseIcon._iconBin && baseIcon._iconBin.child) return baseIcon._iconBin.child;
}
} catch (err) {
// ignore initialization errors
}
// GNOME owns BaseIcon's child lifecycle. In particular, do not call
// _createIconTexture() here: _findIcons() can run while Dash._redisplay()
// is destroying an old DashItemContainer. Creating a replacement child
// during clutter_actor_destroy_all_children() makes Clutter abort the
// entire shell. The animator runs continuously, so an icon which is not
// ready yet can safely be picked up on a later frame.
return null;
}

Expand Down Expand Up @@ -665,12 +660,11 @@ export let Dock = GObject.registerClass(
Main.uiGroup.remove_child(c._menu.actor);
c._menu = null;
}
if (c._label) {
let p = c._label.get_parent();
if (p) {
p.remove_child(c._label);
}
}
// DashItemContainer owns its label. This cleanup is invoked from the
// icon's destroy signal, which can itself be part of GNOME Dash teardown.
// Detaching the label here re-enters the parent's child-destruction loop
// and can crash gnome-shell. Drop only our borrowed reference.
c._label = null;
}

_findIcons() {
Expand Down Expand Up @@ -707,16 +701,6 @@ export let Dock = GObject.registerClass(
this._inspectIcon(icon);
});

// hack: sometimes the Dash creates more than one separator
// workaround - remove all separators in such situation
//! pinpoint the cause of the errors
if (this._separators.length > 1) {
while (this._separators.length > 0) {
this.dash._box.remove_child(this._separators[0]);
this._separators.shift();
}
}

// hide separator between running apps and favorites - if not needed
if (this.extension.favorites_only) {
if (this._separators.length) {
Expand Down Expand Up @@ -745,10 +729,10 @@ export let Dock = GObject.registerClass(
if (this.dash._showAppsIcon) {
this.dash._showAppsIcon.visible = this.extension.apps_icon;
if (this._inspectIcon(this.dash._showAppsIcon)) {
let icon = this.dash._showAppsIcon._icon;
if (!icon._connected) {
icon._connected = true;
icon.connectObject(
let button = this.dash._showAppsIcon.child;
if (!button._d2dlConnected) {
button._d2dlConnected = true;
button.connectObject(
'button-press-event',
() => {
let overview = Main.uiGroup
Expand Down Expand Up @@ -777,8 +761,6 @@ export let Dock = GObject.registerClass(
}
}

let noAnimation = !this.extension.animate_icons_unmute;

let pv = new Point();
pv.x = 0.5;
pv.y = 0.5;
Expand All @@ -794,16 +776,13 @@ export let Dock = GObject.registerClass(
}
};
}
c._icon.track_hover = true;
c._icon.reactive = true;
c._icon.pivot_point = pv;
if (c._button) {
c._button.reactive = noAnimation;
c._button.track_hover = noAnimation;
c.toggle_mode = false;
if (c._appwell || c === this.dash._showAppsIcon) {
// Pointer input belongs to the owning AppIcon or button.
c._icon.reactive = false;
c._icon.track_hover = false;
}
if (c._grid) {
// c._grid.style = noAnimation ? '' : 'background: none !important;';
c._grid.style = 'background: none !important;';
}
if (c._appwell && !c._appwell._activate) {
Expand All @@ -821,11 +800,12 @@ export let Dock = GObject.registerClass(
};
}
let icon = c._icon;
if (icon && !icon._destroyConnectId) {
icon._destroyConnectId = icon.connect('destroy', () => {
this._cleanupIcon(c);
});
}
// Do not attach cleanup callbacks to GNOME-owned StIcons. Their
// destroy signal runs recursively inside DashItemContainer teardown;
// mutating other actor trees from there can make Clutter's
// destroy_all_children() abort the entire shell. The container's own
// destroy handler invalidates the cache, and destroyDash() performs
// explicit extension-owned cleanup when the dock is disabled.
let { _draggable } = c.child;
if (_draggable && !_draggable._dragBeginId) {
_draggable._dragBeginId = _draggable.connect('drag-begin', () => {
Expand Down