[IJPL-43620] [platform] Custom Ordering for Status Bar Items#3447
[IJPL-43620] [platform] Custom Ordering for Status Bar Items#3447jakub-bochenski wants to merge 2 commits intoJetBrains:masterfrom
Conversation
At first I tried implementing user ordering using LoadingOrder: - currently the order of widgets in status bar is defined by plugins, using anchors like after LineSeparator - we want to allow the user to override this order - naive approach fails because, you might have two widgets A and B, typically B is after A but the user rearranges them, it will cause an exception if another widget has anchor like after A, before B - trying to override all the anchors and "linearize" them (sequential after anchors as per desired visual order), only helps assuming no new widgets are added, - even considering all currently available widgets (active and inactive) this will still fail if a new plugin that contributes status bar widgets is installed later - since widgets can be added and removed, there is a need for an algorithm to reconcile the order desired by the user and the default order defined by the plugins - there is no obvious, simple approach; this is a partial-order merge problem, this would require extending the DFSTBuilder.java class to support weighted edges So I implemented a different approach. User moves are recorded separately and applied after the LoadingOrder sorting is applied (`WidgetSorter`) I didn't find any tests covering the status bar. I've added a unit test to verify that the widgets are sorted correctly. I've also fixed `com.intellij.openapi.wm.impl.status.IdeStatusBarImplKt#wrap` method to set WIDGET_IT. Missing WIDGET_IT was preventing DnD from working.
aydarin
left a comment
There was a problem hiding this comment.
I like the idea of storing user's customisations and applying them on top of the configured by xmls order.
If I get it correct, approach of storing moves by sourceWidgetID-> targetWidgetID won't handle reorder correctly if a widget with targetWidgetID will be removed.
What do you think about storing the state of customized order like: sourceWidgetID-> targetIndex?
We should store only changed indexes, and during reorder do a "bubble sort" by comparing targetIndex(lower indexes goes to left) without touching non-customised widgets.
For example:
Original: A-B-C-D
After drag D->A: D-A-B-C
Stored user reordering: D->0, A->1, B->2, C->3
Restore after the new widget is added:
Original: A-B-E-C-D
After reordering from the user state: D-A-B-E-C
Restore after one of them is removed:
Original: B-E-C-D
After reordering from the user state: D-B-E-C
What do you think?
| val order: LoadingOrder | ||
| } | ||
| } No newline at end of file | ||
| } |
There was a problem hiding this comment.
Is it? It will compile w/o it. but text files should end with new line by POSIX standards.
| return null | ||
| } | ||
|
|
||
| class WidgetSorter( |
There was a problem hiding this comment.
Suggestion to hide it from public API:
@TestOnly
class WidgetSorter(
| data class StatusBarState(@JvmField val widgets: Map<String, Boolean> = emptyMap()) | ||
| data class StatusBarState( | ||
| @JvmField val widgets: Map<String, Boolean> = emptyMap(), | ||
| @JvmField val userMoves: Map<String, String> = emptyMap(), |
There was a problem hiding this comment.
AFAIU, the order is important for user moves.
I guess they should be stored in the ordered data structure like list of pairs.
There was a problem hiding this comment.
I guess this does not apply if we store indexes instead
There was a problem hiding this comment.
Hi!
I'm not sure I understand the comment. Could you elaborate?
There was a problem hiding this comment.
I mean if we apply you suggestion from #3447 (review) the stored data is different anyway
There was a problem hiding this comment.
If after discussion we decide to go that way, then yes.
It's still a proposal, not a requirement.
Yes, the order would reset for sourceWidget.
I'm not sure what would the index be during sort then if it's not stored? |
Sorry, my example wasn't fully showing the idea. If we take longer example, then it's visible, we store only changed indexes without indexes for X, E and F. Original: X-A-B-C-D-E-F |
At first I tried implementing user ordering using LoadingOrder:
So I implemented a different approach.
User moves are recorded separately and applied after the LoadingOrder sorting is applied (
WidgetSorter)I didn't find any tests covering the status bar.
I've added a unit test to verify that the widgets are sorted correctly.
I've also fixed
com.intellij.openapi.wm.impl.status.IdeStatusBarImplKt#wrapmethod to set WIDGET_IT.Missing WIDGET_IT was preventing DnD from working.