Refactor _removeLastZone to avoid recreating entire editor

Simplified the _removeLastZone() function to be more efficient:

Before:
- Removed last zone from array
- Destroyed and recreated entire editor interface (_cancelEditor + startEditor)
- Recreated all remaining zones from scratch
- Caused visual flicker and was inefficient
- Could leave dangling event listeners

After:
- Remove last zone from zones array
- Remove and destroy only the last zone actor
- No need to update zone numbers (removing last zone doesn't affect other numbers)
- No editor recreation needed

Benefits:
- No visual flicker
- Much more efficient (O(1) instead of O(n))
- Cleaner code (15 lines vs 50+ lines)
- No risk of dangling event listeners from recreation
- Better user experience

Fixes TODO item #2.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-15 21:34:36 -07:00
parent ec19b234bb
commit ee2f4792ac
2 changed files with 12 additions and 45 deletions

12
TODO.md
View File

@@ -11,13 +11,13 @@
- [x] Save layouts when created in graphical editor - [x] Save layouts when created in graphical editor
- [x] Load layouts on extension initialization - [x] Load layouts on extension initialization
### 2. Remove Last Zone Implementation (extension.js:236-274) ### 2. Remove Last Zone Implementation ✅ COMPLETED
**Priority: Medium** **Priority: Medium**
- [ ] `_removeLastZone()` destroys and recreates entire editor interface - [x] `_removeLastZone()` destroys and recreates entire editor interface
- [ ] Causes visual flicker - [x] Causes visual flicker
- [ ] Inefficient approach - [x] Inefficient approach
- [ ] Could leave dangling event listeners - [x] Could leave dangling event listeners
- [ ] Refactor to only remove the last zone widget without recreating everything - [x] Refactor to only remove the last zone widget without recreating everything
## Functionality Improvements ## Functionality Improvements

View File

@@ -548,53 +548,20 @@ ZoneEditor.prototype = {
_removeLastZone: function() { _removeLastZone: function() {
if (this.zones.length > 0) { if (this.zones.length > 0) {
// Remove the last zone from data
this.zones.pop(); this.zones.pop();
// Also remove the last zone actor // Remove and destroy the last zone actor
if (this.zoneActors.length > 0) { if (this.zoneActors.length > 0) {
let removedActor = this.zoneActors.pop(); let removedActor = this.zoneActors.pop();
this.editorOverlay.remove_child(removedActor); this.editorOverlay.remove_child(removedActor);
removedActor.destroy(); removedActor.destroy();
} }
// Redraw editor // Update zone numbers on remaining zones
this._cancelEditor(); // Since we removed the last zone, we only need to update if there are still zones
this.startEditor(); // The numbering is 1-indexed, so zone 0 displays "1", zone 1 displays "2", etc.
// No need to update numbers since we removed the last one - other numbers stay the same
// Re-add existing zones
let monitor = Main.layoutManager.primaryMonitor;
this.zoneActors = []; // Reset actors array
this.zones.forEach((zone, index) => {
let zoneActor = new St.Widget({
style_class: 'gridsnap-editor-zone',
x: zone.x * monitor.width,
y: zone.y * monitor.height,
width: zone.width * monitor.width,
height: zone.height * monitor.height
});
zoneActor.set_style(
'border: 3px solid rgba(100, 255, 100, 0.9);' +
'background-color: rgba(100, 255, 100, 0.3);' +
'border-radius: 4px;'
);
let label = new St.Label({
text: String(index + 1),
x: 10,
y: 10
});
label.set_style(
'color: white;' +
'font-size: 24px;' +
'font-weight: bold;' +
'text-shadow: 2px 2px 4px rgba(0,0,0,0.8);'
);
zoneActor.add_child(label);
this.editorOverlay.add_child(zoneActor);
// Track zone actors for moving
this.zoneActors.push(zoneActor);
});
} }
}, },