From d51384fb86c6d351a16b0b032b592df613130c38 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 3 Nov 2009 18:36:44 -0500 Subject: [PATCH] switch to scrolling GenericDisplay, remove menus from apps Temporarily removed search-by-menu from apps as well, will readd later as a ShellApp feature. https://bugzilla.gnome.org/show_bug.cgi?id=600734 --- js/ui/appDisplay.js | 199 +++------------------------------------- js/ui/dash.js | 49 ++++------ js/ui/docDisplay.js | 10 +- js/ui/genericDisplay.js | 148 +++++++++--------------------- js/ui/placeDisplay.js | 8 +- 5 files changed, 86 insertions(+), 328 deletions(-) diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index db2b507e3..c88191016 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -166,15 +166,15 @@ Signals.addSignalMethods(MenuItem.prototype); * showPrefs - a boolean indicating if this AppDisplay should contain preference * applets, rather than applications */ -function AppDisplay(showPrefs) { - this._init(showPrefs); +function AppDisplay(showPrefs, flags) { + this._init(showPrefs, flags); } AppDisplay.prototype = { __proto__: GenericDisplay.GenericDisplay.prototype, - _init : function(showPrefs) { - GenericDisplay.GenericDisplay.prototype._init.call(this); + _init : function(showPrefs, flags) { + GenericDisplay.GenericDisplay.prototype._init.call(this, flags); this._showPrefs = showPrefs; @@ -190,156 +190,10 @@ AppDisplay.prototype = { this._appsStale = true; this._redisplay(GenericDisplay.RedisplayFlags.NONE); })); - - this._focusInMenus = true; - this._activeMenuIndex = -1; - this._activeMenu = null; - this._activeMenuApps = null; - this._menuDisplay = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, - spacing: MENU_SPACING - }); - - this.connect('expanded', Lang.bind(this, function (self) { - this._filterReset(); - })); - this._filterReset(); - }, - - moveRight: function() { - if (this._expanded && this._focusInMenu) { - this._focusInMenu = false; - this._activeMenu.setState(MENU_ENTERED); - this.selectFirstItem(); - } - }, - - moveLeft: function() { - if (this._expanded && !this._focusInMenu) { - this._activeMenu.setState(MENU_SELECTED); - this.unsetSelected(); - this._focusInMenu = true; - } - }, - - // Override genericDisplay.js - getNavigationArea: function() { - return this._menuDisplay; - }, - - selectUp: function() { - if (!(this._expanded && this._focusInMenu)) - return GenericDisplay.GenericDisplay.prototype.selectUp.call(this); - this._selectMenuIndex(this._activeMenuIndex - 1); - return true; - }, - - selectDown: function() { - if (!(this._expanded && this._focusInMenu)) - return GenericDisplay.GenericDisplay.prototype.selectDown.call(this); - this._selectMenuIndex(this._activeMenuIndex+1); - return true; - }, - - setSearch: function(text) { - let lowertext = text.toLowerCase(); - if (lowertext == this._search) - return; - - // We prepare menu matches up-front, so that we don't - // need to go over all menu items for each application - // and then get all applications for a matching menu - // to see if a particular application passed to - // _isInfoMatching() is a match. - let terms = lowertext.split(/\s+/); - this._menuSearchAppMatches = {}; - for (let i = 0; i < terms.length; i++) { - let term = terms[i]; - this._menuSearchAppMatches[term] = {}; - for (let j = 0; j < this._menus.length; j++) { - let menuItem = this._menus[j]; - // Match only on the beginning of the words in category names, - // because otherwise it introduces unnecessary noise in the results. - if (menuItem.name.toLowerCase().indexOf(term) == 0 || - menuItem.name.toLowerCase().indexOf(" " + term) > 0) { - let menuApps = this._appSystem.get_applications_for_menu(menuItem.id); - for (let k = 0; k < menuApps.length; k++) { - let menuApp = menuApps[k]; - this._menuSearchAppMatches[term][menuApp.get_id()] = true; - } - } - } - } - - GenericDisplay.GenericDisplay.prototype.setSearch.call(this, text); - }, - - // Protected overrides - - _filterActive: function() { - // We always have a filter now since a menu must be selected - return true; - }, - - _filterReset: function() { - GenericDisplay.GenericDisplay.prototype._filterReset.call(this); - this._selectMenuIndex(0); }, //// Private //// - _emitStateChange: function() { - this.emit('state-changed'); - }, - - _selectMenuIndex: function(index) { - if (index < 0 || index >= this._menus.length) - return; - this._menuDisplays[index].setState(MENU_SELECTED); - }, - - _getMostUsed: function() { - let context = ""; - let usage = Shell.AppUsage.get_default(); - return usage.get_most_used(context, 30); - }, - - _addMenuItem: function(name, id, index) { - let display = new MenuItem(name, id); - this._menuDisplays.push(display); - display.connect('state-changed', Lang.bind(this, function (display) { - let activated = display.getState() != MENU_UNSELECTED; - if (!activated && display == this._activeMenu) { - this._activeMenuIndex = -1; - this._activeMenu = null; - } else if (activated) { - if (display != this._activeMenu && this._activeMenu != null) - this._activeMenu.setState(MENU_UNSELECTED); - this._activeMenuIndex = index; - this._activeMenu = display; - if (id == null) { - this._activeMenuApps = this._getMostUsed(); - } else { - this._activeMenuApps = this._appSystem.get_applications_for_menu(id); - } - } - this._redisplay(GenericDisplay.RedisplayFlags.FULL); - })); - this._menuDisplay.append(display.actor, 0); - }, - - _redisplayMenus: function() { - this._menuDisplay.remove_all(); - this._addMenuItem(_("Frequent"), null, 'gtk-select-all'); - // Adding an empty box here results in double spacing between - // "Frequent" and the other items. - let separator_actor = new Big.Box(); - this._menuDisplay.append(separator_actor, 0); - for (let i = 0; i < this._menus.length; i++) { - let menu = this._menus[i]; - this._addMenuItem(menu.name, menu.id, i+1); - } - }, - _addApp: function(appInfo) { let appId = appInfo.get_id(); this._allItems[appId] = appInfo; @@ -363,33 +217,33 @@ AppDisplay.prototype = { } } else { // Loop over the toplevel menu items, load the set of desktop file ids - // associated with each one, skipping empty menus + // associated with each one. let allMenus = this._appSystem.get_menus(); - this._menus = []; for (let i = 0; i < allMenus.length; i++) { let menu = allMenus[i]; let menuApps = this._appSystem.get_applications_for_menu(menu.id); - let hasVisibleApps = menuApps.some(function (app) { return !app.get_is_nodisplay(); }); - if (!hasVisibleApps) { - continue; - } - this._menus.push(menu); + for (let j = 0; j < menuApps.length; j++) { let app = menuApps[j]; this._addApp(app); } } - this._redisplayMenus(); } this._appsStale = false; return false; }, - // Stub this out; the app display always has a category selected _setDefaultList : function() { - this._matchedItems = {}; + this._matchedItems = this._allItems; this._matchedItemKeys = []; + for (let itemId in this._matchedItems) { + let app = this._allItems[itemId]; + if (app.get_is_nodisplay()) + continue; + this._matchedItemKeys.push(itemId); + } + this._matchedItemKeys.sort(Lang.bind(this, this._compareItems)); }, // Compares items associated with the item ids based on the alphabetical order @@ -409,25 +263,7 @@ AppDisplay.prototype = { // Don't show nodisplay items here if (itemInfo.get_is_nodisplay()) return false; - // Search takes precedence; not typically useful to search within a - // menu - if (this._activeMenu == null || search != "") - return this._isInfoMatchingSearch(itemInfo, search); - else - return this._isInfoMatchingMenu(itemInfo); - }, - _isInfoMatchingMenu: function(itemInfo) { - let id = itemInfo.get_id(); - for (let i = 0; i < this._activeMenuApps.length; i++) { - let activeApp = this._activeMenuApps[i]; - if (activeApp.get_id() == id) - return true; - } - return false; - }, - - _isInfoMatchingSearch: function(itemInfo, search) { if (search == null || search == '') return true; @@ -455,13 +291,6 @@ AppDisplay.prototype = { return true; } - if (this._menuSearchAppMatches[search]) { - if (this._menuSearchAppMatches[search].hasOwnProperty(itemInfo.get_id())) - return true; - } else { - log("Missing an entry for search term " + search + " in this._menuSearchAppMatches"); - } - return false; }, diff --git a/js/ui/dash.js b/js/ui/dash.js index fe7a4dafb..06cfd9910 100644 --- a/js/ui/dash.js +++ b/js/ui/dash.js @@ -75,15 +75,15 @@ function _getIndexWrapped(index, increment, length) { return (index + increment + length) % length; } -function _createDisplay(displayType) { +function _createDisplay(displayType, flags) { if (displayType == APPS) - return new AppDisplay.AppDisplay(); + return new AppDisplay.AppDisplay(false, flags); else if (displayType == PREFS) - return new AppDisplay.AppDisplay(true); + return new AppDisplay.AppDisplay(true, flags); else if (displayType == DOCS) - return new DocDisplay.DocDisplay(); + return new DocDisplay.DocDisplay(flags); else if (displayType == PLACES) - return new PlaceDisplay.PlaceDisplay(); + return new PlaceDisplay.PlaceDisplay(flags); return null; } @@ -162,32 +162,20 @@ Pane.prototype = { } Signals.addSignalMethods(Pane.prototype); -function ResultArea(displayType, enableNavigation) { - this._init(displayType, enableNavigation); +function ResultArea(displayType, flags) { + this._init(displayType, flags); } ResultArea.prototype = { - _init : function(displayType, enableNavigation) { + _init : function(displayType, flags) { this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL }); this.resultsContainer = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, spacing: DEFAULT_PADDING }); this.actor.append(this.resultsContainer, Big.BoxPackFlags.EXPAND); - this.navContainer = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL }); - this.resultsContainer.append(this.navContainer, Big.BoxPackFlags.NONE); - - this.display = _createDisplay(displayType); - - this.navArea = this.display.getNavigationArea(); - if (enableNavigation && this.navArea) - this.navContainer.append(this.navArea, Big.BoxPackFlags.EXPAND); + this.display = _createDisplay(displayType, flags); this.resultsContainer.append(this.display.actor, Big.BoxPackFlags.EXPAND); - - this.controlBox = new Big.Box({ x_align: Big.BoxAlignment.CENTER }); - this.controlBox.append(this.display.displayControl, Big.BoxPackFlags.NONE); - this.actor.append(this.controlBox, Big.BoxPackFlags.NONE); - this.display.load(); } } @@ -235,8 +223,8 @@ ResultPane.prototype = { // Create a display of displayType and pack it into this pane's // content area. Return the display. - packResults: function(displayType, enableNavigation) { - let resultArea = new ResultArea(displayType, enableNavigation); + packResults: function(displayType) { + let resultArea = new ResultArea(displayType); createPaneForDetails(this._dash, resultArea.display); @@ -713,7 +701,7 @@ Dash.prototype = { this._appsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) { if (this._moreAppsPane == null) { this._moreAppsPane = new ResultPane(this); - this._moreAppsPane.packResults(APPS, true); + this._moreAppsPane.packResults(APPS); this._addPane(this._moreAppsPane); link.setPane(this._moreAppsPane); } @@ -741,7 +729,7 @@ Dash.prototype = { this._docsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) { if (this._moreDocsPane == null) { this._moreDocsPane = new ResultPane(this); - this._moreDocsPane.packResults(DOCS, true); + this._moreDocsPane.packResults(DOCS); this._addPane(this._moreDocsPane); link.setPane(this._moreDocsPane); } @@ -796,8 +784,7 @@ Dash.prototype = { this._showSingleSearchSection(section.type); })); this._searchResultsSection.content.append(section.header.actor, Big.BoxPackFlags.NONE); - section.resultArea = new ResultArea(section.type, false); - section.resultArea.controlBox.hide(); + section.resultArea = new ResultArea(section.type, GenericDisplay.GenericDisplayFlags.DISABLE_VSCROLLING); this._searchResultsSection.content.append(section.resultArea.actor, Big.BoxPackFlags.EXPAND); createPaneForDetails(this, section.resultArea.display); } @@ -847,6 +834,11 @@ Dash.prototype = { } } + // Here work around a bug that I never quite tracked down + // the root cause of; it appeared that the search results + // section was getting a 0 height allocation. + this._searchResultsSection.content.queue_relayout(); + return false; }, @@ -914,7 +906,6 @@ Dash.prototype = { if (section.type == type) { // This will be the only section shown. section.resultArea.display.selectFirstItem(); - section.resultArea.controlBox.show(); let itemCount = section.resultArea.display.getMatchedItemsCount(); let itemCountText = itemCount + ""; section.header.actor.hide(); @@ -938,8 +929,6 @@ Dash.prototype = { let section = this._searchSections[i]; if (section.type == this._searchResultsSingleShownSection) { // This will no longer be the only section shown. - section.resultArea.display.displayPage(0); - section.resultArea.controlBox.hide(); let itemCount = section.resultArea.display.getMatchedItemsCount(); if (itemCount != 0) { section.header.actor.show(); diff --git a/js/ui/docDisplay.js b/js/ui/docDisplay.js index 9596b0b43..011ba7724 100644 --- a/js/ui/docDisplay.js +++ b/js/ui/docDisplay.js @@ -111,19 +111,19 @@ DocDisplayItem.prototype = { /* This class represents a display containing a collection of document items. * The documents are sorted by how recently they were last visited. */ -function DocDisplay() { - this._init(); +function DocDisplay(flags) { + this._init(flags); } DocDisplay.prototype = { __proto__: GenericDisplay.GenericDisplay.prototype, - _init : function() { - GenericDisplay.GenericDisplay.prototype._init.call(this); + _init : function(flags) { + GenericDisplay.GenericDisplay.prototype._init.call(this, flags); // We keep a single timeout callback for updating last visited times // for all the items in the display. This avoids creating individual // callbacks for each item in the display. So proper time updates - // for individual items and item details depend on the item being + // for individual items and item details depend on the item being // associated with one of the displays. this._updateTimeoutTargetTime = -1; this._updateTimeoutId = 0; diff --git a/js/ui/genericDisplay.js b/js/ui/genericDisplay.js index e58c2c632..c154f74f0 100644 --- a/js/ui/genericDisplay.js +++ b/js/ui/genericDisplay.js @@ -11,6 +11,7 @@ const Meta = imports.gi.Meta; const Pango = imports.gi.Pango; const Signals = imports.signals; const Shell = imports.gi.Shell; +const St = imports.gi.St; const Button = imports.ui.button; const DND = imports.ui.dnd; @@ -18,7 +19,6 @@ const Link = imports.ui.link; const Main = imports.ui.main; const RedisplayFlags = { NONE: 0, - RESET_CONTROLS: 1 << 0, FULL: 1 << 1, SUBSEARCH: 1 << 2, IMMEDIATE: 1 << 3 }; @@ -320,31 +320,36 @@ GenericDisplayItem.prototype = { Signals.addSignalMethods(GenericDisplayItem.prototype); +const GenericDisplayFlags = { + DISABLE_VSCROLLING: 1 << 0 +} + /* This is a virtual class that represents a display containing a collection of items * that can be filtered with a search string. */ -function GenericDisplay() { - this._init(); +function GenericDisplay(flags) { + this._init(flags); } GenericDisplay.prototype = { - _init : function() { + _init : function(flags) { + let disableVScrolling = (flags & GenericDisplayFlags.DISABLE_VSCROLLING) != 0; this._search = ''; this._expanded = false; - this._maxItemsPerPage = null; - this._list = new Shell.OverflowList({ spacing: 6.0, - item_height: ITEM_DISPLAY_HEIGHT }); - - this._list.connect('notify::n-pages', Lang.bind(this, function () { - this._updateDisplayControl(true); - })); - this._list.connect('notify::page', Lang.bind(this, function () { - this._updateDisplayControl(false); - })); + if (disableVScrolling) { + this.actor = this._list = new Shell.OverflowList({ spacing: 6, + item_height: ITEM_DISPLAY_HEIGHT }); + } else { + this.actor = new St.ScrollView({ x_fill: true, y_fill: true }); + this.actor.get_hscroll_bar().hide(); + this._list = new St.BoxLayout({ style_class: "generic-display-container", + vertical: true }); + this.actor.add_actor(this._list); + } this._pendingRedisplay = RedisplayFlags.NONE; - this._list.connect('notify::mapped', Lang.bind(this, this._onMappedNotify)); + this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedNotify)); // map where Object represents the item info this._allItems = {}; @@ -356,13 +361,6 @@ GenericDisplay.prototype = { this._displayedItems = {}; this._openDetailIndex = -1; this._selectedIndex = -1; - // These two are public - .actor is the normal "actor subclass" property, - // but we also expose a .displayControl actor which is separate. - // See also getNavigationArea. - this.actor = this._list; - this.displayControl = new Big.Box({ background_color: ITEM_DISPLAY_BACKGROUND_COLOR, - spacing: 12, - orientation: Big.BoxOrientation.HORIZONTAL}); }, //// Public methods //// @@ -373,7 +371,7 @@ GenericDisplay.prototype = { if (lowertext == this._search) { return; } - let flags = RedisplayFlags.RESET_CONTROLS | RedisplayFlags.IMMEDIATE; + let flags = RedisplayFlags.IMMEDIATE; if (this._search != '') { // Because we combine search terms with OR, we have to be sure that no new term // was introduced before deciding that the new search results will be a subset of @@ -401,7 +399,7 @@ GenericDisplay.prototype = { // to the bottom one. Returns true if the selection actually moved up, false if it wrapped // around to the bottom. selectUp: function() { - let count = this._list.displayedCount; + let count = this._getVisibleCount(); let selectedUp = true; let prev = this._selectedIndex - 1; if (this._selectedIndex <= 0) { @@ -416,7 +414,7 @@ GenericDisplay.prototype = { // to the top one. Returns true if the selection actually moved down, false if it wrapped // around to the top. selectDown: function() { - let count = this._list.displayedCount; + let count = this._getVisibleCount(); let selectedDown = true; let next = this._selectedIndex + 1; if (this._selectedIndex == count - 1) { @@ -435,7 +433,7 @@ GenericDisplay.prototype = { // Selects the last item among the displayed items. selectLastItem: function() { - let count = this._list.displayedCount; + let count = this._getVisibleCount(); if (this.hasItems()) this._selectIndex(count - 1); }, @@ -472,6 +470,8 @@ GenericDisplay.prototype = { resetState: function() { this._filterReset(); this._openDetailIndex = -1; + if (!(this.actor instanceof Shell.OverflowList)) + this.actor.get_vscroll_bar().get_adjustment().value = 0; }, // Returns an actor which acts as a sidebar; this is used for @@ -485,15 +485,6 @@ GenericDisplay.prototype = { return item.createDetailsActor(); }, - // Displays the page specified by the pageNumber argument. - displayPage: function(pageNumber) { - // Cleanup from the previous selection, but don't unset this._selectedIndex - if (this.hasSelected()) { - this._findDisplayedByIndex(this._selectedIndex).markSelected(false); - } - this._list.page = pageNumber; - }, - //// Protected methods //// _recreateDisplayItems: function() { @@ -519,14 +510,14 @@ GenericDisplay.prototype = { Lang.bind(this, function() { // update the selection - this._selectIndex(this._list.get_actor_index(displayItem.actor)); + this._selectIndex(this._list.get_children().indexOf(displayItem.actor)); this.activateSelected(); })); displayItem.connect('show-details', Lang.bind(this, function() { - let index = this._list.get_actor_index(displayItem.actor); + let index = this._list.get_children().indexOf(displayItem.actor); /* Close the details pane if already open */ if (index == this._openDetailIndex) { this._openDetailIndex = -1; @@ -541,9 +532,10 @@ GenericDisplay.prototype = { // Removes an item identifed by the itemId from the displayed items. _removeDisplayItem: function(itemId) { - let count = this._list.displayedCount; + let children = this._list.get_children(); + let count = children.length; let displayItem = this._displayedItems[itemId]; - let displayItemIndex = this._list.get_actor_index(displayItem.actor); + let displayItemIndex = children.indexOf(displayItem.actor); if (this.hasSelected() && count == 1) { this.unsetSelected(); @@ -638,28 +630,22 @@ GenericDisplay.prototype = { /* * Updates the displayed items, applying the search string if one exists. * @flags: Flags controlling redisplay behavior as follows: - * RESET_CONTROLS - indicates if the page selection should be reset when displaying the matching results. - * We reset the page selection when the change in results was initiated by the user by - * entering a different search criteria or by viewing the results list in a different - * size mode, but we keep the page selection the same if the results got updated on - * their own while the user was browsing through the result pages. * SUBSEARCH - Indicates that the current _search is a superstring of the previous * one, which implies we only need to re-search through previous results. - * FULL - Indicates that we need recreate all displayed items; implies RESET_CONTROLS as well + * FULL - Indicates that we need recreate all displayed items. * IMMEDIATE - Do the full redisplay even if we're not mapped. This is useful * if you want to get the number of matched items and show/hide a section based on * that number. */ _redisplay: function(flags) { - let immediate = (flags & RedisplayFlags.IMMEDIATE) > 0; - if (!immediate && !this._list.mapped) { + let immediate = (flags & RedisplayFlags.IMMEDIATE) != 0; + if (!immediate && !this.actor.mapped) { this._pendingRedisplay |= flags; return; } - let isSubSearch = (flags & RedisplayFlags.SUBSEARCH) > 0; - let fullReload = (flags & RedisplayFlags.FULL) > 0; - let resetPage = (flags & RedisplayFlags.RESET_CONTROLS) > 0 || fullReload; + let isSubSearch = (flags & RedisplayFlags.SUBSEARCH) != 0; + let fullReload = (flags & RedisplayFlags.FULL) != 0; let hadSelected = this.hasSelected(); this.unsetSelected(); @@ -681,9 +667,6 @@ GenericDisplay.prototype = { this._redisplayReordering(); } - if (resetPage) - this._list.page = 0; - if (hadSelected) { this._selectedIndex = -1; this.selectFirstItem(); @@ -783,59 +766,10 @@ GenericDisplay.prototype = { return matchScores; }, - /* - * Updates the display control to reflect the matched items set and the page selected. - * - * resetDisplayControl - indicates if the display control should be re-created because - * the results or the space allocated for them changed. If it's false, - * the existing display control is used and only the page links are - * updated to reflect the current page selection. - */ - _updateDisplayControl: function(resetDisplayControl) { - if (resetDisplayControl) { - this.displayControl.remove_all(); - let nPages = this._list.n_pages; - // Don't show the page indicator if there is only one page. - if (nPages == 1) - return; - let pageNumber = this._list.page; - for (let i = 0; i < nPages; i++) { - let pageControl = new Link.Link({ color: (i == pageNumber) ? DISPLAY_CONTROL_SELECTED_COLOR : ITEM_DISPLAY_DESCRIPTION_COLOR, - font_name: "Sans Bold 16px", - text: (i+1) + "", - reactive: (i == pageNumber) ? false : true}); - this.displayControl.append(pageControl.actor, Big.BoxPackFlags.NONE); - - // we use pageNumberLocalScope to get the page number right in the callback function - let pageNumberLocalScope = i; - pageControl.connect('clicked', - Lang.bind(this, - function(o, event) { - this.displayPage(pageNumberLocalScope); - })); - } - } else { - let pageControlActors = this.displayControl.get_children(); - for (let i = 0; i < pageControlActors.length; i++) { - let pageControlActor = pageControlActors[i]; - if (i == this._list.page) { - pageControlActor.color = DISPLAY_CONTROL_SELECTED_COLOR; - pageControlActor.reactive = false; - } else { - pageControlActor.color = ITEM_DISPLAY_DESCRIPTION_COLOR; - pageControlActor.reactive = true; - } - } - } - if (this.hasSelected()) { - this.selectFirstItem(); - } - }, - // Returns a display item based on its index in the ordering of the // display children. _findDisplayedByIndex: function(index) { - let actor = this._list.get_displayed_actor(index); + let actor = this._list.get_children()[index]; return this._findDisplayedByActor(actor); }, @@ -869,8 +803,14 @@ GenericDisplay.prototype = { this.emit('selected'); }, + _getVisibleCount: function() { + if (this.actor instanceof Shell.OverflowList) + return this._list.displayed_count; + return this._list.get_n_children(); + }, + _onMappedNotify: function () { - let mapped = this._list.mapped; + let mapped = this.actor.mapped; if (mapped && this._pendingRedisplay > RedisplayFlags.NONE) this._redisplay(this._pendingRedisplay); diff --git a/js/ui/placeDisplay.js b/js/ui/placeDisplay.js index acee53e55..af92c666c 100644 --- a/js/ui/placeDisplay.js +++ b/js/ui/placeDisplay.js @@ -470,15 +470,15 @@ PlaceDisplayItem.prototype = { }; -function PlaceDisplay() { - this._init(); +function PlaceDisplay(flags) { + this._init(flags); } PlaceDisplay.prototype = { __proto__: GenericDisplay.GenericDisplay.prototype, - _init: function() { - GenericDisplay.GenericDisplay.prototype._init.call(this); + _init: function(flags) { + GenericDisplay.GenericDisplay.prototype._init.call(this, flags); this._stale = true; Main.placesManager.connect('places-updated', Lang.bind(this, function (e) { this._stale = true;