dash: Reimplement the dash based on AppWell code
The new dash implementation is a single-column vertical sidebar, whose items are scaled dynamically to fit the available height. If the height is still exceeded after scaling down to a minimum item size, excess items are cut off. The now unused old dash implementation is renamed to OldDash, as its code will be used as a base for the new view selector element. https://bugzilla.gnome.org/show_bug.cgi?id=634948
This commit is contained in:
163
js/ui/dash.js
163
js/ui/dash.js
@ -4,11 +4,13 @@ const Clutter = imports.gi.Clutter;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const DND = imports.ui.dnd;
|
||||
const DocDisplay = imports.ui.docDisplay;
|
||||
const PlaceDisplay = imports.ui.placeDisplay;
|
||||
@ -16,6 +18,7 @@ const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const Search = imports.ui.search;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Workspace = imports.ui.workspace;
|
||||
|
||||
// 25 search results (per result type) should be enough for everyone
|
||||
const MAX_RENDERED_SEARCH_RESULTS = 25;
|
||||
@ -689,11 +692,11 @@ Section.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function Dash() {
|
||||
function OldDash() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Dash.prototype = {
|
||||
OldDash.prototype = {
|
||||
_init : function() {
|
||||
// dash and the popup panes need to be reactive so that the clicks in unoccupied places on them
|
||||
// are not passed to the transparent background underneath them. This background is used for the workspaces area when
|
||||
@ -911,3 +914,159 @@ Dash.prototype = {
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Dash.prototype);
|
||||
|
||||
|
||||
function Dash() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Dash.prototype = {
|
||||
_init : function() {
|
||||
this._menus = [];
|
||||
this._menuDisplays = [];
|
||||
this._maxHeight = -1;
|
||||
|
||||
this._favorites = [];
|
||||
|
||||
this._box = new St.BoxLayout({ name: 'dash',
|
||||
vertical: true,
|
||||
clip_to_allocation: true });
|
||||
this._box._delegate = this;
|
||||
|
||||
this.actor = new St.Bin({ y_align: St.Align.START, child: this._box });
|
||||
this.actor.connect('notify::height', Lang.bind(this,
|
||||
function() {
|
||||
if (this._maxHeight != this.actor.height)
|
||||
this._queueRedisplay();
|
||||
this._maxHeight = this.actor.height;
|
||||
}));
|
||||
|
||||
this._workId = Main.initializeDeferredWork(this._box, Lang.bind(this, this._redisplay));
|
||||
|
||||
this._tracker = Shell.WindowTracker.get_default();
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
|
||||
this._appSystem.connect('installed-changed', Lang.bind(this, this._queueRedisplay));
|
||||
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
|
||||
this._tracker.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
||||
},
|
||||
|
||||
_appIdListToHash: function(apps) {
|
||||
let ids = {};
|
||||
for (let i = 0; i < apps.length; i++)
|
||||
ids[apps[i].get_id()] = apps[i];
|
||||
return ids;
|
||||
},
|
||||
|
||||
_queueRedisplay: function () {
|
||||
Main.queueDeferredWork(this._workId);
|
||||
},
|
||||
|
||||
_redisplay: function () {
|
||||
this._box.hide();
|
||||
this._box.remove_all();
|
||||
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
/* hardcode here pending some design about how exactly desktop contexts behave */
|
||||
let contextId = '';
|
||||
|
||||
let running = this._tracker.get_running_apps(contextId);
|
||||
|
||||
for (let id in favorites) {
|
||||
let app = favorites[id];
|
||||
let display = new AppDisplay.AppWellIcon(app);
|
||||
this._box.add(display.actor);
|
||||
}
|
||||
|
||||
for (let i = 0; i < running.length; i++) {
|
||||
let app = running[i];
|
||||
if (app.get_id() in favorites)
|
||||
continue;
|
||||
let display = new AppDisplay.AppWellIcon(app);
|
||||
this._box.add(display.actor);
|
||||
}
|
||||
|
||||
let children = this._box.get_children();
|
||||
if (children.length == 0) {
|
||||
this._box.add_style_pseudo_class('empty');
|
||||
} else {
|
||||
this._box.remove_style_pseudo_class('empty');
|
||||
|
||||
if (this._maxHeight > -1) {
|
||||
let iconSizes = [ 48, 32, 24, 22, 16 ];
|
||||
|
||||
for (let i = 0; i < iconSizes.length; i++) {
|
||||
let minHeight, natHeight;
|
||||
|
||||
this._iconSize = iconSizes[i];
|
||||
for (let j = 0; j < children.length; j++)
|
||||
children[j]._delegate.icon.setIconSize(this._iconSize);
|
||||
|
||||
[minHeight, natHeight] = this.actor.get_preferred_height(-1);
|
||||
|
||||
if (natHeight <= this._maxHeight)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this._box.show();
|
||||
},
|
||||
|
||||
handleDragOver : function(source, actor, x, y, time) {
|
||||
let app = null;
|
||||
if (source instanceof AppDisplay.AppWellIcon)
|
||||
app = this._appSystem.get_app(source.getId());
|
||||
else if (source instanceof Workspace.WindowClone)
|
||||
app = this._tracker.get_window_app(source.metaWindow);
|
||||
|
||||
// Don't allow favoriting of transient apps
|
||||
if (app == null || app.is_transient())
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
||||
let id = app.get_id();
|
||||
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
let srcIsFavorite = (id in favorites);
|
||||
|
||||
if (srcIsFavorite)
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
||||
return DND.DragMotionResult.COPY_DROP;
|
||||
},
|
||||
|
||||
// Draggable target interface
|
||||
acceptDrop : function(source, actor, x, y, time) {
|
||||
let app = null;
|
||||
if (source instanceof AppDisplay.AppWellIcon) {
|
||||
app = this._appSystem.get_app(source.getId());
|
||||
} else if (source instanceof Workspace.WindowClone) {
|
||||
app = this._tracker.get_window_app(source.metaWindow);
|
||||
}
|
||||
|
||||
// Don't allow favoriting of transient apps
|
||||
if (app == null || app.is_transient()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let id = app.get_id();
|
||||
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
let srcIsFavorite = (id in favorites);
|
||||
|
||||
if (srcIsFavorite) {
|
||||
return false;
|
||||
} else {
|
||||
Mainloop.idle_add(Lang.bind(this, function () {
|
||||
AppFavorites.getAppFavorites().addFavorite(id);
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(Dash.prototype);
|
||||
|
Reference in New Issue
Block a user