Merge branch 'fix/workspace-indicator-dot-animation' into 'main'

fix: workspace indicator dots

See merge request june/top-bar-organizer!4
This commit is contained in:
Ben Leppke 2026-10-28 15:58:15 +00:00
commit a59050e438

View file

@ -125,8 +125,8 @@ export default class TopBarOrganizerExtension extends Extension {
/// Go through the items of the validBoxOrder and order the GNOME Shell /// Go through the items of the validBoxOrder and order the GNOME Shell
/// top bar box accordingly. /// top bar box accordingly.
for (let i = 0; i < validBoxOrder.length; i++) { const indicatorContainers: St.Bin[] = [];
const item = validBoxOrder[i]; for (const item of validBoxOrder) {
// Get the indicator container associated with the current role. // Get the indicator container associated with the current role.
const associatedIndicatorContainer = (Main.panel.statusArea as any)[item.role]?.container; const associatedIndicatorContainer = (Main.panel.statusArea as any)[item.role]?.container;
if (!(associatedIndicatorContainer instanceof St.Bin)) { if (!(associatedIndicatorContainer instanceof St.Bin)) {
@ -134,29 +134,23 @@ export default class TopBarOrganizerExtension extends Extension {
continue; continue;
} }
indicatorContainers.push(associatedIndicatorContainer);
// Save whether or not the indicator container is visible. // Save whether or not the indicator container is visible.
const isVisible = associatedIndicatorContainer.visible; const isVisible = associatedIndicatorContainer.visible;
const parent = associatedIndicatorContainer.get_parent(); // Only remove the indicator container from its current parent if
if (parent !== null) { // it actually changes boxes. `remove_child()` stops all running
parent.remove_child(associatedIndicatorContainer); // transitions on the removed actor and its children (the default
} // remove-child flags include `REMOVE_CHILD_STOP_TRANSITIONS`).
if (box === "right") { // Detaching e.g. the "activities" indicator container while GNOME
// If the target panel box is the right panel box, insert the // Shell animates in a new workspace dot stops that animation,
// indicator container at index `-1`, which just adds it to the // leaving the dot invisible or incorrectly sized until the next
// end (correct order is ensured, since `validBoxOrder` is // workspace change.
// sorted correctly and we're looping over it in order). if (associatedIndicatorContainer.get_parent() !== panelBox) {
// This way unaccounted-for indicator containers will be at the const parent = associatedIndicatorContainer.get_parent();
// left, which is preferred, since the box is logically parent?.remove_child(associatedIndicatorContainer);
// right-to-left.
// The same applies for indicator containers, which are just
// temporarily unaccounted for (like for indicator containers of
// not yet ready app indicators), since them being at the right
// for a probably temporary stay causes all the indicator
// containers to shift.
panelBox.insert_child_at_index(associatedIndicatorContainer, -1); panelBox.insert_child_at_index(associatedIndicatorContainer, -1);
} else {
panelBox.insert_child_at_index(associatedIndicatorContainer, i);
} }
// Hide the indicator container... // Hide the indicator container...
@ -172,6 +166,24 @@ export default class TopBarOrganizerExtension extends Extension {
associatedIndicatorContainer.hide(); associatedIndicatorContainer.hide();
} }
} }
// Order the indicator containers by changing their indexes in place.
// `set_child_at_index()` is logically equivalent to removing and
// re-inserting an actor, but unlike `remove_child()` it does not change
// the actor's state or stop its transitions.
//
// For the right box, the first indicator container has to be placed at
// the beginning of the block of accounted-for indicator containers at
// the end of the box. This way unaccounted-for indicator containers
// (e.g. not yet ready app indicators) will be at the left, which is
// preferred, since the box is logically right-to-left. For the left and
// center box, the block starts at index 0.
const firstIndex = box === "right"
? panelBox.get_n_children() - indicatorContainers.length
: 0;
for (let i = 0; i < indicatorContainers.length; i++) {
panelBox.set_child_at_index(indicatorContainers[i], firstIndex + i);
}
// To handle the case, where the box order got set to a permutation // To handle the case, where the box order got set to a permutation
// of an outdated box order, it would be wise, if the caller updated the // of an outdated box order, it would be wise, if the caller updated the
// box order now to include the items present in the top bar. // box order now to include the items present in the top bar.