Skip to content

Commit 9025021

Browse files
authored
gwl: Add overflow support through slide/scroll list (#13352)
* gwl: Add initial overflow support through sliding * gwl: Scroll to focused app when a new one is added or when changing workspaces To find the new app position in the container instead of using actor.x we are summing the size of each preceding appGroup until the current app to focus because actor.x would report 0 some times. * gwl: Avoid trying to remove slide timer multiple times This was triggering GLib Critical error in the logs. * gwl: Properly integrate with the scroll-behavior settings * gwl: Avoid trying to remove the scroll to focused app deboucer timer after being removed already * gwl: Listen to the scrollBox allocation signal to update the scroll buttons visibility This avoids issues with improper representation of the current allocation after the buttons are hidden. * gwl: Make sure to scroll to the focused app group on workspace switched * gwl: Refactor the scroll logic to its own class * gwl: Improve scroll to item implementation * gwl: Extract app group scroll box to its own module * gwl: Disable actions if panel edit mode is enabled and update classes on orientation changed * gwl: Debounce calls to updateScrollVisibility to avoid it being called excessively * gwl: Define style in proper cinnamon theme file instead of in-code * gwl: Update scroll button theme * gwl: Implementation using the native St.ScrollView * gwl: Update scroll police depending on the orientation and make sure to debounce setting scrollActive state as inactive to avoid triggering the menu during the scroll animation * gwl: Fix handleDragOver positioning for the scrollview based implementation * Update scrollbox vfade/hfade theme defaults * gwl: Adjust min_size setting for lateral panels * gwl: Only set appGroup focus if app actually has focus This avoids an issue where during workspace switching some times a minimized window would visually have the focused window style when it shouldn't. * gwl: Improve the scroll to last focused app This is useful when switching to a new workspace or the applet is reloaded so it guarantees user will at least be aware of opened windows that could otherwise be hidden if the scroll state is mantained. * gwl: Remove important attr from the scrollbox style * gwl: Improve scroll to last focused If there's no opened windows just keep the current scroll state. * gwl: Improve scroll handling to work better with previous scroll options I've also decided to change the scroll key name, this with the goal of guaranteeing that the scroll app window list will be set as default for all users, those that want other options, or none, can switch back. * gwl: Remove unused import * gwl: Bring back slider buttons * gwl: Fix scroll handling and workspace scrollbox destroy process * gwl: Improve edge slide area and style handling gwl: Update name from box to container for clarity * gwl: Add option to enable/disable slide to focused app button * gwl: Use xsi-pan icons instead of the arrow icons Looks better and is consistent with what is used in the alt-tab window switcher for example when it reaches the limits of the screen. * gwl: Handle possible undefined or null this.state cases * gwl: Add click to slide option * gwl: Update scroll box buttons classes * gwl: Break to handle lastFocused app instead of handling inside the loop * gwl: Remove edge scroll zone in favor of the side buttons Considering we are already using the side scroll buttons which gives a clear over area for sliding the app list, having a edge scroll zone there makes it redudant and potentially confusing for the user. * gwl: Implement proper styling for the slide buttons
1 parent 1c50d51 commit 9025021

6 files changed

Lines changed: 568 additions & 41 deletions

File tree

data/theme/cinnamon-sass/widgets/_windowlist.scss

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,58 @@
107107
&-notifications-badge-label {
108108
font-size: 12px;
109109
}
110+
111+
&-scrollbox {
112+
&-scrollview {
113+
&.vfade {
114+
-st-vfade-offset: 68px;
115+
-st-hfade-offset: 0;
116+
}
117+
&.hfade {
118+
-st-hfade-offset: 68px;
119+
-st-vfade-offset: 0;
120+
}
121+
}
122+
123+
&-button {
124+
transition-duration: 100ms;
125+
126+
&-icon {
127+
icon-size: $scalable_icon_size;
128+
color: inherit;
129+
}
130+
131+
&.vertical { }
132+
133+
&-start {
134+
margin-right: 1px;
135+
136+
&.vertical {
137+
margin-right: 0;
138+
margin-bottom: 1px;
139+
}
140+
}
141+
142+
&-end {
143+
margin-left: 1px;
144+
145+
&.vertical {
146+
margin-left: 0;
147+
margin-top: 1px;
148+
}
149+
}
150+
151+
&:hover {
152+
background-color: $lighter_bg_color;
153+
color: $fg_color;
154+
}
155+
156+
&:active {
157+
background-color: $lightest_bg_color;
158+
color: $fg_color;
159+
}
160+
}
161+
}
110162
}
111163

112164
// classic window list

files/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/appGroup.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,6 @@ var AppGroup = class AppGroup {
375375
getPreferredWidth(actor, forHeight, alloc) {
376376
const [iconMinSize, iconNaturalSize] = this.iconBox.get_preferred_width(forHeight);
377377
const [labelMinSize, labelNaturalSize] = this.label.get_preferred_width(forHeight);
378-
// The label text starts in the center of the icon, so we should allocate the space
379-
// needed for the icon plus the space needed for(label - icon/2)
380-
alloc.min_size = 1 * global.ui_scale;
381-
382378
const {appId} = this.groupState;
383379

384380
const allocateForLabel = this.labelVisiblePref ||
@@ -393,16 +389,18 @@ var AppGroup = class AppGroup {
393389
} else {
394390
alloc.natural_size = iconNaturalSize + 6 * global.ui_scale;
395391
}
392+
alloc.min_size = alloc.natural_size;
396393
} else {
397394
alloc.natural_size = this.state.trigger('getPanelHeight');
395+
alloc.min_size = 1 * global.ui_scale;
398396
}
399397
}
400398

401399
getPreferredHeight(actor, forWidth, alloc) {
402400
let [iconMinSize, iconNaturalSize] = this.iconBox.get_preferred_height(forWidth);
403401
let [labelMinSize, labelNaturalSize] = this.label.get_preferred_height(forWidth);
404-
alloc.min_size = Math.min(iconMinSize, labelMinSize);
405402
alloc.natural_size = Math.max(iconNaturalSize, labelNaturalSize);
403+
alloc.min_size = alloc.natural_size;
406404
}
407405

408406
allocate(actor, box, flags) {
@@ -555,7 +553,7 @@ var AppGroup = class AppGroup {
555553
}
556554

557555
onEnter() {
558-
if (this.state.panelEditMode) return false;
556+
if (this.state.panelEditMode || this.state.scrollActive) return false;
559557

560558
this.actor.add_style_pseudo_class('hover');
561559

@@ -642,7 +640,7 @@ var AppGroup = class AppGroup {
642640
const {appId, metaWindows, lastFocused} = this.groupState;
643641

644642
if (hasFocus === undefined) {
645-
hasFocus = this.workspaceState.lastFocusedApp === appId;
643+
hasFocus = this.workspaceState.lastFocusedApp === appId && getFocusState(lastFocused);
646644
}
647645

648646
// If any of the windows associated with our app have focus,

files/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class PinnedFavs {
110110
const currentWorkspace = this.params.state.trigger('getCurrentWorkspace');
111111
const newFavorites = [];
112112
let refActorFound = false;
113-
currentWorkspace.actor.get_children().forEach( (actor, i) => {
113+
currentWorkspace.container.get_children().forEach( (actor, i) => {
114114
const appGroup = currentWorkspace.appGroups.find( appGroup => appGroup.actor === actor );
115115
if (!appGroup) return;
116116
const {app, appId, isFavoriteApp} = appGroup.groupState;
@@ -254,6 +254,7 @@ class GroupedWindowListApplet extends Applet.Applet {
254254
removeFavorite: (id) => this.pinnedFavorites.removeFavorite(id),
255255
getFavorites: () => this.pinnedFavorites._favorites,
256256
cycleWindows: (e, source) => this.handleScroll(e, source),
257+
handleScroll: (e) => this.handleScroll(e),
257258
openAbout: () => this.openAbout(),
258259
configureApplet: () => this.configureApplet(),
259260
removeApplet: (event) => this.confirmRemoveApplet(event)
@@ -300,7 +301,7 @@ class GroupedWindowListApplet extends Applet.Applet {
300301
bindSettings() {
301302
const settingsProps = [
302303
{key: 'group-apps', value: 'groupApps', cb: this.refreshAllWorkspaces},
303-
{key: 'scroll-behavior', value: 'scrollBehavior', cb: null},
304+
{key: 'list-scroll-behavior', value: 'scrollBehavior', cb: null},
304305
{key: 'left-click-action', value: 'leftClickAction', cb: null},
305306
{key: 'middle-click-action', value: 'middleClickAction', cb: null},
306307
{key: 'show-all-workspaces', value: 'showAllWorkspaces', cb: this.refreshAllWorkspaces},
@@ -314,6 +315,7 @@ class GroupedWindowListApplet extends Applet.Applet {
314315
{key: 'enable-window-count-badges', value: 'enableWindowCountBadges', cb: this.onEnableWindowCountBadgeChange},
315316
{key: 'enable-notification-badges', value: 'enableNotificationBadges', cb: this.onEnableNotificationsChange},
316317
{key: 'enable-app-button-dragging', value: 'enableDragging', cb: this.draggableSettingChanged},
318+
{key: 'enable-click-to-slide', value: 'enableClickToSlide', cb: null},
317319
{key: 'thumbnail-scroll-behavior', value: 'thumbnailScrollBehavior', cb: null},
318320
{key: 'show-thumbnails', value: 'showThumbs', cb: this.updateVerticalThumbnailState},
319321
{key: 'animate-thumbnails', value: 'animateThumbs', cb: null},
@@ -794,14 +796,26 @@ class GroupedWindowListApplet extends Applet.Applet {
794796
&& St.Widget.get_default_direction () === St.TextDirection.RTL;
795797

796798
const axis = this.state.isHorizontal ? [x, 'x2'] : [y, 'y2'];
799+
800+
let adjustmentValue = 0;
801+
if (currentWorkspace.scrollBox) {
802+
const adjustment = this.state.isHorizontal ?
803+
currentWorkspace.scrollBox.scrollView.get_hscroll_bar().get_adjustment() :
804+
currentWorkspace.scrollBox.scrollView.get_vscroll_bar().get_adjustment();
805+
adjustmentValue = adjustment.get_value();
806+
}
807+
808+
// Add scroll position to current coordinate
809+
axis[0] += adjustmentValue;
810+
797811
if(rtl_horizontal)
798812
axis[0] = this.actor.width - axis[0];
799813

800814
// save data on drag start
801815
if(this.state.dragging.posList === null){
802816
this.state.dragging.isForeign = !(source instanceof AppGroup);
803817
this.state.dragging.posList = [];
804-
currentWorkspace.actor.get_children().forEach( child => {
818+
currentWorkspace.container.get_children().forEach( child => {
805819
let childPos;
806820
if(rtl_horizontal)
807821
childPos = this.actor.width - child.get_allocation_box()['x1'];
@@ -815,7 +829,7 @@ class GroupedWindowListApplet extends Applet.Applet {
815829
let pos = 0;
816830
while(pos < this.state.dragging.posList.length && axis[0] > this.state.dragging.posList[pos])
817831
pos++;
818-
832+
819833
let favLength = 0;
820834
for (const appGroup of currentWorkspace.appGroups) {
821835
if(appGroup.groupState.isFavoriteApp)
@@ -835,21 +849,21 @@ class GroupedWindowListApplet extends Applet.Applet {
835849

836850
if(this.state.dragging.isForeign) {
837851
if (this.state.dragging.dragPlaceholder)
838-
currentWorkspace.actor.set_child_at_index(this.state.dragging.dragPlaceholder, pos);
852+
currentWorkspace.container.set_child_at_index(this.state.dragging.dragPlaceholder, pos);
839853
else {
840854
const iconSize = this.getPanelIconSize() * global.ui_scale;
841855
this.state.dragging.dragPlaceholder = new DND.GenericDragPlaceholderItem();
842856
this.state.dragging.dragPlaceholder.width = iconSize;
843857
this.state.dragging.dragPlaceholder.height = iconSize;
844-
currentWorkspace.actor.insert_child_at_index(
858+
currentWorkspace.container.insert_child_at_index(
845859
this.state.dragging.dragPlaceholder,
846860
this.state.dragging.pos
847861
);
848862
this.state.dragging.dragPlaceholder.animateIn();
849863
}
850864
}
851865
else
852-
currentWorkspace.actor.set_child_at_index(source.actor, pos);
866+
currentWorkspace.container.set_child_at_index(source.actor, pos);
853867
}
854868

855869
if(this.state.dragging.isForeign)

0 commit comments

Comments
 (0)