Skip to content

Commit 5465c97

Browse files
committed
menu applet: use a single context menu item
instead of creating one per application button. This reduces the number of actors in the applicationsBox from 250 to 140 at startup on my system.
1 parent b07b0e6 commit 5465c97

File tree

1 file changed

+54
-66
lines changed
  • files/usr/share/cinnamon/applets/menu@cinnamon.org

1 file changed

+54
-66
lines changed

files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js

Lines changed: 54 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,8 @@ class GenericApplicationButton extends SimpleMenuItem {
287287
let desc = app.get_description() || "";
288288
super(applet, true, true, app.get_name(), desc.split("\n")[0], styleClass);
289289
this.app = app;
290-
290+
this.menu = null;
291291
this.withMenu = withMenu;
292-
if (this.withMenu){
293-
this.menu = new PopupMenu.PopupSubMenu(this.actor);
294-
this.menu.actor.set_style_class_name('menu-context-menu');
295-
this._signals.connect(this.menu, 'open-state-changed', Lang.bind(this, this._subMenuOpenStateChanged));
296-
}
297292
}
298293

299294
highlight() {
@@ -327,39 +322,56 @@ class GenericApplicationButton extends SimpleMenuItem {
327322
}
328323

329324
activateContextMenus() {
330-
if (this.withMenu && !this.menu.isOpen)
331-
this.applet.closeContextMenus(this.app, true);
332-
this.toggleMenu();
333-
}
325+
if (!this.withMenu)
326+
return;
327+
328+
let menu = this.applet.contextMenu;
334329

335-
closeMenu() {
336-
if (this.withMenu) this.menu.close();
330+
if (menu != null && menu.sourceActor._delegate != this)
331+
this.applet.closeContextMenu(this, true);
332+
333+
this.toggleMenu();
337334
}
338335

339336
toggleMenu() {
340-
if (!this.withMenu) return;
337+
if (!this.withMenu)
338+
return;
339+
340+
if (this.applet.contextMenu == null) {
341+
this.applet.createContextMenu(this.actor);
342+
}
343+
344+
let menu = this.applet.contextMenu;
345+
this.menu = menu;
341346

342347
if (!this.menu.isOpen){
343348
Util.each(this.menu.box.get_children(), c => { c.destroy() });
344349

350+
menu.sourceActor = this.actor;
351+
this.actor.get_parent().set_child_above_sibling(menu.actor, this.actor);
352+
345353
let menuItem;
346354
menuItem = new ApplicationContextMenuItem(this, _("Add to panel"), "add_to_panel", "list-add");
347355
this.menu.addMenuItem(menuItem);
356+
348357
if (USER_DESKTOP_PATH){
349358
menuItem = new ApplicationContextMenuItem(this, _("Add to desktop"), "add_to_desktop", "computer");
350359
this.menu.addMenuItem(menuItem);
351360
}
361+
352362
if (AppFavorites.getAppFavorites().isFavorite(this.app.get_id())){
353363
menuItem = new ApplicationContextMenuItem(this, _("Remove from favorites"), "remove_from_favorites", "starred");
354364
this.menu.addMenuItem(menuItem);
355-
}else{
365+
} else {
356366
menuItem = new ApplicationContextMenuItem(this, _("Add to favorites"), "add_to_favorites", "non-starred");
357367
this.menu.addMenuItem(menuItem);
358368
}
369+
359370
if (this.applet._canUninstallApps) {
360371
menuItem = new ApplicationContextMenuItem(this, _("Uninstall"), "uninstall", "edit-delete");
361372
this.menu.addMenuItem(menuItem);
362373
}
374+
363375
if (this.applet._isBumblebeeInstalled) {
364376
menuItem = new ApplicationContextMenuItem(this, _("Run with NVIDIA GPU"), "run_with_nvidia_gpu", "cpu");
365377
this.menu.addMenuItem(menuItem);
@@ -379,7 +391,7 @@ class GenericApplicationButton extends SimpleMenuItem {
379391
}
380392

381393
get _contextIsOpen() {
382-
return this.menu.isOpen;
394+
return this.menu != null && this.menu.isOpen;
383395
}
384396

385397
destroy() {
@@ -640,41 +652,31 @@ class RecentButton extends SimpleMenuItem {
640652
}
641653

642654
activateContextMenus() {
643-
let menu = this.applet.recentContextMenu;
655+
let menu = this.applet.contextMenu;
644656

645657
if (menu != null && menu.sourceActor._delegate != this)
646-
this.applet.closeContextMenus(this, true);
658+
this.applet.closeContextMenu(this, true);
647659

648660
this.toggleMenu();
649661
}
650662

651-
closeMenu() {
652-
this.menu = null;
653-
this.menu.close();
654-
}
655-
656663
hasLocalPath(file) {
657664
return file.is_native() || file.get_path() != null;
658665
}
659666

660667
toggleMenu() {
661-
if (this.applet.recentContextMenu == null) {
662-
this.applet.createRecentContextMenu(this.actor);
668+
if (this.applet.contextMenu == null) {
669+
this.applet.createContextMenu(this.actor);
663670
}
664671

665-
let menu = this.applet.recentContextMenu;
672+
let menu = this.applet.contextMenu;
666673
this.menu = menu;
667674

668675
if (!menu.isOpen) {
669-
let parent = menu.actor.get_parent();
670-
if (parent != null) {
671-
parent.remove_child(menu.actor);
672-
}
676+
Util.each(this.menu.box.get_children(), c => { c.destroy() });
673677

674678
menu.sourceActor = this.actor;
675-
this.actor.get_parent().insert_child_above(menu.actor, this.actor);
676-
677-
Util.each(menu.box.get_children(), c => { c.destroy() });
679+
this.actor.get_parent().set_child_above_sibling(menu.actor, this.actor);
678680

679681
let menuItem;
680682

@@ -734,7 +736,7 @@ class RecentButton extends SimpleMenuItem {
734736
menu.addMenuItem(menuItem);
735737
}
736738
}
737-
this.applet.recentContextMenu.toggle();
739+
this.menu.toggle();
738740
}
739741

740742
get _contextIsOpen() {
@@ -1063,8 +1065,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
10631065
this.settings.bind("search-filesystem", "searchFilesystem");
10641066
this.refreshing = false; // used as a flag to know if we're currently refreshing (so we don't do it more than once concurrently)
10651067

1066-
this.recentContextMenu = null;
1067-
this.appsContextMenu = null;
1068+
this.contextMenu = null;
10681069

10691070
this.lastSelectedCategory = null;
10701071

@@ -1247,7 +1248,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
12471248
this.selectedAppDescription.set_text("");
12481249
this._previousTreeSelectedActor = null;
12491250
this._previousSelectedActor = null;
1250-
this.closeContextMenus(null, false);
1251+
this.closeContextMenu(null, false);
12511252

12521253
this._clearAllSelections(true);
12531254
this._scrollToButton(this.favBoxIter.getFirstVisible()._delegate, this.favoritesScrollBox);
@@ -1331,26 +1332,23 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
13311332
}
13321333
}
13331334

1334-
_recentMenuOpenStateChanged(recentContextMenu) {
1335-
if (recentContextMenu.isOpen) {
1336-
this._activeContextMenuParent = recentContextMenu.sourceActor._delegate;
1337-
this._scrollToButton(recentContextMenu);
1335+
_contextMenuOpenStateChanged(menu) {
1336+
if (menu.isOpen) {
1337+
this._activeContextMenuParent = menu.sourceActor._delegate;
1338+
this._scrollToButton(menu);
13381339
} else {
13391340
this._activeContextMenuItem = null;
13401341
this._activeContextMenuParent = null;
1341-
for (let item in this._recentButtons) {
1342-
if (this._recentButtons[item].menu) {
1343-
this._recentButtons[item].menu = null;
1344-
}
1345-
}
1342+
menu.sourceActor._delegate.menu = null;
13461343
}
13471344
}
13481345

1349-
createRecentContextMenu(actor) {
1346+
createContextMenu(actor) {
13501347
let menu = new PopupMenu.PopupSubMenu(actor);
13511348
menu.actor.set_style_class_name('menu-context-menu');
1352-
menu.connect('open-state-changed', Lang.bind(this, this._recentMenuOpenStateChanged));
1353-
this.recentContextMenu = menu;
1349+
menu.connect('open-state-changed', Lang.bind(this, this._contextMenuOpenStateChanged));
1350+
this.contextMenu = menu;
1351+
this.applicationsBox.add_actor(menu.actor);
13541352
}
13551353

13561354
_navigateContextMenu(button, symbol, ctrlKey) {
@@ -1916,7 +1914,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
19161914
return;
19171915
button.isHovered = true;
19181916
this._clearPrevCatSelection(button.actor);
1919-
this.closeContextMenus(null, false);
1917+
this.closeContextMenu(null, false);
19201918
this._select_category(button.categoryId);
19211919
this.makeVectorBox(button.actor);
19221920
} else {
@@ -2369,7 +2367,6 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
23692367

23702368
for (let i = 0; i < this._applicationsButtons.length; i++) {
23712369
this.applicationsBox.add_actor(this._applicationsButtons[i].actor);
2372-
this.applicationsBox.add_actor(this._applicationsButtons[i].menu.actor);
23732370
}
23742371

23752372
this._appsWereRefreshed = true;
@@ -2719,30 +2716,21 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
27192716
this._displayButtons(name);
27202717
}
27212718

2722-
this.closeContextMenus(null, false);
2719+
this.closeContextMenu(null, false);
27232720
}
27242721

2725-
closeContextMenus(excluded, animate) {
2726-
for (let app in this._applicationsButtons){
2727-
if (this._applicationsButtons[app] != excluded && this._applicationsButtons[app].menu.isOpen){
2728-
if (animate)
2729-
this._applicationsButtons[app].toggleMenu();
2730-
else
2731-
this._applicationsButtons[app].closeMenu();
2732-
}
2733-
}
2734-
2735-
if (!this.recentContextMenu) {
2722+
closeContextMenu(excluded, animate) {
2723+
if (!this.contextMenu)
27362724
return;
2737-
}
27382725

2739-
let item = this.recentContextMenu.sourceActor._delegate;
2726+
let menu = this.contextMenu;
2727+
let item = menu.sourceActor._delegate;
27402728

27412729
if ((item != excluded || excluded == null) && item.menu && item.menu.isOpen) {
27422730
if (animate)
2743-
this.recentContextMenu.toggle();
2731+
menu.toggle();
27442732
else
2745-
this.recentContextMenu.close();
2733+
menu.close();
27462734

27472735
this._activeContextMenuParent = null;
27482736
this._activeContextMenuItem = null;

0 commit comments

Comments
 (0)