diff --git a/data/Makefile.am b/data/Makefile.am
index ca8d6dde0..eee6b2d51 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -18,9 +18,8 @@ dist_image_DATA = \
add-workspace.svg \
close.svg \
info.svg \
- remove-workspace.svg \
- view-more-activated.svg \
- view-more.svg
+ magnifier.svg \
+ remove-workspace.svg
schemadir = @GCONF_SCHEMA_FILE_DIR@
schema_DATA = gnome-shell.schemas
diff --git a/data/view-more.svg b/data/magnifier.svg
similarity index 76%
rename from data/view-more.svg
rename to data/magnifier.svg
index 31af4ee2e..836ee6998 100644
--- a/data/view-more.svg
+++ b/data/magnifier.svg
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/data/view-more-activated.svg b/data/view-more-activated.svg
deleted file mode 100644
index 787b1ad6f..000000000
--- a/data/view-more-activated.svg
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index a1e5f6f7a..7d28fbaff 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -565,9 +565,7 @@ WellGrid.prototype = {
_init: function() {
this.actor = new Shell.GenericContainer();
- this._separator = new Big.Box({ border_color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
- border_top: 1,
- height: 1 });
+ this._separator = new Big.Box({ height: 1 });
this.actor.add_actor(this._separator);
this._separatorIndex = 0;
this._cachedSeparatorY = 0;
diff --git a/js/ui/dash.js b/js/ui/dash.js
index c5d8030a6..59426d5e0 100644
--- a/js/ui/dash.js
+++ b/js/ui/dash.js
@@ -5,6 +5,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
+const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const Lang = imports.lang;
@@ -18,14 +19,35 @@ const Main = imports.ui.main;
const DEFAULT_PADDING = 4;
const DASH_SECTION_PADDING = 6;
-const DASH_SECTION_SPACING = 12;
+const DASH_SECTION_SPACING = 40;
const DASH_CORNER_RADIUS = 5;
-const DASH_SEARCH_BG_COLOR = new Clutter.Color();
-DASH_SEARCH_BG_COLOR.from_pixel(0xffffffff);
-const DASH_SECTION_COLOR = new Clutter.Color();
-DASH_SECTION_COLOR.from_pixel(0x846c3dff);
-const DASH_TEXT_COLOR = new Clutter.Color();
-DASH_TEXT_COLOR.from_pixel(0xffffffff);
+
+const BACKGROUND_COLOR = new Clutter.Color();
+BACKGROUND_COLOR.from_pixel(0x000000c0);
+
+const DASH_PADDING_SIDE = 14;
+
+const SEARCH_BORDER_BOTTOM_COLOR = new Clutter.Color();
+SEARCH_BORDER_BOTTOM_COLOR.from_pixel(0x191919ff);
+
+const SECTION_BORDER_COLOR = new Clutter.Color();
+SECTION_BORDER_COLOR.from_pixel(0x262626ff);
+const SECTION_BORDER = 1;
+const SECTION_INNER_BORDER_COLOR = new Clutter.Color();
+SECTION_INNER_BORDER_COLOR.from_pixel(0x000000ff);
+const SECTION_BACKGROUND_TOP_COLOR = new Clutter.Color();
+SECTION_BACKGROUND_TOP_COLOR.from_pixel(0x161616ff);
+const SECTION_BACKGROUND_BOTTOM_COLOR = new Clutter.Color();
+SECTION_BACKGROUND_BOTTOM_COLOR.from_pixel(0x000000ff);
+const SECTION_INNER_SPACING = 8;
+
+const BROWSE_ACTIVATED_BG = new Clutter.Color();
+BROWSE_ACTIVATED_BG.from_pixel(0x303030f0);
+
+const TEXT_COLOR = new Clutter.Color();
+TEXT_COLOR.from_pixel(0x5f5f5fff);
+const BRIGHT_TEXT_COLOR = new Clutter.Color();
+BRIGHT_TEXT_COLOR.from_pixel(0xffffffff);
const PANE_BORDER_COLOR = new Clutter.Color();
PANE_BORDER_COLOR.from_pixel(0x101d3cfa);
@@ -144,7 +166,7 @@ ResultArea.prototype = {
// Utility function shared between ResultPane and the DocDisplay in the main dash.
// Connects to the detail signal of the display, and on-demand creates a new
// pane.
-function createPaneForDetails(dash, display, detailsWidth) {
+function createPaneForDetails(dash, display) {
let detailPane = null;
display.connect('show-details', Lang.bind(this, function(display, index) {
if (detailPane == null) {
@@ -160,7 +182,7 @@ function createPaneForDetails(dash, display, detailsWidth) {
if (index >= 0) {
detailPane.destroyContent();
- let details = display.createDetailsForIndex(index, detailsWidth, -1);
+ let details = display.createDetailsForIndex(index, -1);
detailPane.content.append(details, Big.BoxPackFlags.EXPAND);
detailPane.open();
} else {
@@ -170,17 +192,16 @@ function createPaneForDetails(dash, display, detailsWidth) {
return null;
}
-function ResultPane(dash, detailsWidth) {
- this._init(dash, detailsWidth);
+function ResultPane(dash) {
+ this._init(dash);
}
ResultPane.prototype = {
__proto__: Pane.prototype,
- _init: function(dash, detailsWidth) {
+ _init: function(dash) {
Pane.prototype._init.call(this);
this._dash = dash;
- this._detailsWidth = detailsWidth;
},
// Create an instance of displayClass and pack it into this pane's
@@ -188,7 +209,7 @@ ResultPane.prototype = {
packResults: function(displayClass, enableNavigation) {
let resultArea = new ResultArea(displayClass, enableNavigation);
- createPaneForDetails(this._dash, resultArea.display, this._detailsWidth);
+ createPaneForDetails(this._dash, resultArea.display);
this.content.append(resultArea.actor, Big.BoxPackFlags.EXPAND);
this.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
@@ -206,31 +227,89 @@ SearchEntry.prototype = {
_init : function() {
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
y_align: Big.BoxAlignment.CENTER,
- background_color: DASH_SEARCH_BG_COLOR,
- corner_radius: 4,
- spacing: DEFAULT_PADDING,
- padding: DEFAULT_PADDING
- });
-
- let icon = new Gio.ThemedIcon({ name: 'gtk-find' });
- let searchIconTexture = Shell.TextureCache.get_default().load_gicon(icon, 16);
- this.actor.append(searchIconTexture, Big.BoxPackFlags.NONE);
-
+ border_bottom: SECTION_BORDER,
+ border_color: SEARCH_BORDER_BOTTOM_COLOR });
this.pane = null;
+ this._defaultText = "Find apps or documents";
+
+ let textProperties = { font_name: "Sans 12" };
+ let entryProperties = { editable: true,
+ activatable: true,
+ single_line_mode: true,
+ color: BRIGHT_TEXT_COLOR,
+ cursor_color: BRIGHT_TEXT_COLOR,
+ text: '' };
+ Lang.copyProperties(textProperties, entryProperties);
// We need to initialize the text for the entry to have the cursor displayed
// in it. See http://bugzilla.openedhand.com/show_bug.cgi?id=1365
- this.entry = new Clutter.Text({ font_name: "Sans 14px",
- editable: true,
- activatable: true,
- singleLineMode: true,
- text: ""
- });
+ this.entry = new Clutter.Text(entryProperties);
+ this.entry.connect('notify::text', Lang.bind(this, function () {
+ this._resetTextState();
+ }));
this.actor.append(this.entry, Big.BoxPackFlags.EXPAND);
+
+ // Mark as editable just to get a cursor
+ let defaultTextProperties = { ellipsize: Pango.EllipsizeMode.END,
+ text: "Find apps or documents",
+ editable: true,
+ color: TEXT_COLOR,
+ cursor_visible: false,
+ single_line_mode: true };
+ Lang.copyProperties(textProperties, defaultTextProperties);
+ this._defaultText = new Clutter.Text(defaultTextProperties);
+ this.actor.add_actor(this._defaultText);
+ this.entry.connect('notify::allocation', Lang.bind(this, function () {
+ this._repositionDefaultText();
+ }));
+
+ this._iconBox = new Big.Box({ x_align: Big.BoxAlignment.CENTER,
+ y_align: Big.BoxAlignment.CENTER });
+ this.actor.append(this._iconBox, Big.BoxPackFlags.END);
+
+ let global = Shell.Global.get();
+ let magnifierUri = "file://" + global.imagedir + "magnifier.svg";
+ this._magnifierIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
+ magnifierUri, 29, 18);
+ let closeUri = "file://" + global.imagedir + "close.svg";
+ this._closeIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
+ closeUri, 18, 18);
+ this._closeIcon.reactive = true;
+ this._closeIcon.connect('button-press-event', Lang.bind(this, function () {
+ this.entry.text = '';
+ }));
+ this._repositionDefaultText();
+ this._resetTextState();
},
setPane: function (pane) {
this._pane = pane;
+ },
+
+ reset: function () {
+ this.entry.text = '';
+ },
+
+ getText: function () {
+ return this.entry.text;
+ },
+
+ _resetTextState: function () {
+ let text = this.getText();
+ this._iconBox.remove_all();
+ if (text != '') {
+ this._defaultText.hide();
+ this._iconBox.append(this._closeIcon, Big.BoxPackFlags.NONE);
+ } else {
+ this._defaultText.show();
+ this._iconBox.append(this._magnifierIcon, Big.BoxPackFlags.NONE);
+ }
+ },
+
+ _repositionDefaultText: function () {
+ // Offset a little to show the cursor
+ this._defaultText.set_position(this.entry.x + 4, this.entry.y);
+ this._defaultText.set_size(this.entry.width, this.entry.height);
}
};
Signals.addSignalMethods(SearchEntry.prototype);
@@ -242,22 +321,21 @@ function MoreLink() {
MoreLink.prototype = {
_init : function () {
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
+ padding_right: DEFAULT_PADDING,
padding_left: DEFAULT_PADDING,
- padding_right: DEFAULT_PADDING });
- let global = Shell.Global.get();
- let inactiveUri = "file://" + global.imagedir + "view-more.svg";
- let activeUri = "file://" + global.imagedir + "view-more-activated.svg";
- this._inactiveIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
- inactiveUri, 29, 18);
- this._activeIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
- activeUri, 29, 18);
- this._iconBox = new Big.Box({ reactive: true });
- this._iconBox.append(this._inactiveIcon, Big.BoxPackFlags.NONE);
- this.actor.append(this._iconBox, Big.BoxPackFlags.END);
-
+ reactive: true,
+ x_align: Big.BoxAlignment.CENTER,
+ y_align: Big.BoxAlignment.CENTER,
+ border_left: SECTION_BORDER,
+ border_color: SECTION_BORDER_COLOR });
this.pane = null;
- this._iconBox.connect('button-press-event', Lang.bind(this, function (b, e) {
+ let text = new Clutter.Text({ font_name: "Sans 12px",
+ color: BRIGHT_TEXT_COLOR,
+ text: "Browse" });
+ this.actor.append(text, Big.BoxPackFlags.NONE);
+
+ this.actor.connect('button-press-event', Lang.bind(this, function (b, e) {
if (this.pane == null) {
// Ensure the pane is created; the activated handler will call setPane
this.emit('activated');
@@ -270,41 +348,66 @@ MoreLink.prototype = {
setPane: function (pane) {
this._pane = pane;
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
- this._iconBox.remove_all();
- this._iconBox.append(isOpen ? this._activeIcon : this._inactiveIcon,
- Big.BoxPackFlags.NONE);
}));
}
}
Signals.addSignalMethods(MoreLink.prototype);
-function SectionHeader(title) {
- this._init(title);
+function SectionHeader(title, suppressBrowse) {
+ this._init(title, suppressBrowse);
}
SectionHeader.prototype = {
- _init : function (title) {
- this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
- let text = new Clutter.Text({ color: DASH_SECTION_COLOR,
- font_name: "Sans Bold 10px",
+ _init : function (title, suppressBrowse) {
+ this.actor = new Big.Box({ border: SECTION_BORDER,
+ border_color: SECTION_BORDER_COLOR });
+ this._innerBox = new Big.Box({ border: SECTION_BORDER,
+ border_color: SECTION_INNER_BORDER_COLOR,
+ padding_left: DEFAULT_PADDING,
+ orientation: Big.BoxOrientation.HORIZONTAL });
+ this.actor.append(this._innerBox, Big.BoxPackFlags.EXPAND);
+ let backgroundGradient = Shell.create_vertical_gradient(SECTION_BACKGROUND_TOP_COLOR,
+ SECTION_BACKGROUND_BOTTOM_COLOR);
+ this._innerBox.add_actor(backgroundGradient);
+ this._innerBox.connect('notify::allocation', Lang.bind(this, function (actor) {
+ let [width, height] = actor.get_size();
+ backgroundGradient.set_size(width, height);
+ }));
+ let textBox = new Big.Box({ padding_top: DEFAULT_PADDING,
+ padding_bottom: DEFAULT_PADDING });
+ let text = new Clutter.Text({ color: TEXT_COLOR,
+ font_name: "Sans Bold 12px",
text: title });
- this.moreLink = new MoreLink();
- this.actor.append(text, Big.BoxPackFlags.EXPAND);
- this.actor.append(this.moreLink.actor, Big.BoxPackFlags.END);
+ textBox.append(text, Big.BoxPackFlags.NONE);
+ this._innerBox.append(textBox, Big.BoxPackFlags.EXPAND);
+ if (!suppressBrowse) {
+ this.moreLink = new MoreLink();
+ this._innerBox.append(this.moreLink.actor, Big.BoxPackFlags.END);
+ }
}
}
-function Dash(displayGridColumnWidth) {
- this._init(displayGridColumnWidth);
+function Section(titleString, suppressBrowse) {
+ this._init(titleString, suppressBrowse);
+}
+
+Section.prototype = {
+ _init: function(titleString, suppressBrowse) {
+ this.actor = new Big.Box({ spacing: SECTION_INNER_SPACING });
+ this.header = new SectionHeader(titleString, suppressBrowse);
+ this.actor.append(this.header.actor, Big.BoxPackFlags.NONE);
+ this.content = new Big.Box();
+ this.actor.append(this.content, Big.BoxPackFlags.EXPAND);
+ }
+}
+
+function Dash() {
+ this._init();
}
Dash.prototype = {
- _init : function(displayGridColumnWidth) {
- this._width = displayGridColumnWidth;
-
- this._detailsWidth = displayGridColumnWidth * 2;
-
+ _init : function() {
let global = Shell.Global.get();
// dash and the popup panes need to be reactive so that the clicks in unoccupied places on them
@@ -316,14 +419,21 @@ Dash.prototype = {
// of the Group actor ends up including the width of its hidden children, so we were getting a reactive object as
// wide as the details pane that was blocking the clicks to the workspaces underneath it even when the details pane
// was actually hidden.
- this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
- width: this._width,
- padding: DEFAULT_PADDING,
+ this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
+ background_color: BACKGROUND_COLOR,
+ corner_radius: DASH_CORNER_RADIUS,
+ padding_left: DASH_PADDING_SIDE,
+ padding_right: DASH_PADDING_SIDE,
reactive: true });
- this.dashContainer = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
- spacing: DASH_SECTION_SPACING });
- this.actor.append(this.dashContainer, Big.BoxPackFlags.EXPAND);
+ // Size for this one explicitly set from overlay.js
+ this.searchArea = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
+
+ this.sectionArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
+ spacing: DASH_SECTION_SPACING });
+
+ this.actor.append(this.searchArea, Big.BoxPackFlags.NONE);
+ this.actor.append(this.sectionArea, Big.BoxPackFlags.NONE);
// The currently active popup display
this._activePane = null;
@@ -333,24 +443,25 @@ Dash.prototype = {
this._searchPane = null;
this._searchActive = false;
this._searchEntry = new SearchEntry();
- this.dashContainer.append(this._searchEntry.actor, Big.BoxPackFlags.NONE);
+ this.searchArea.append(this._searchEntry.actor, Big.BoxPackFlags.EXPAND);
this._searchAreaApps = null;
this._searchAreaDocs = null;
this._searchQueued = false;
this._searchEntry.entry.connect('text-changed', Lang.bind(this, function (se, prop) {
- this._searchActive = this._searchEntry.text != '';
+ let text = this._searchEntry.getText();
+ this._searchActive = text != '';
if (this._searchQueued)
return;
if (this._searchPane == null) {
- this._searchPane = new ResultPane(this, this._detailsWidth);
- this._searchPane.content.append(new Clutter.Text({ color: DASH_SECTION_COLOR,
+ this._searchPane = new ResultPane(this);
+ this._searchPane.content.append(new Clutter.Text({ color: TEXT_COLOR,
font_name: 'Sans Bold 10px',
text: "APPLICATIONS" }),
Big.BoxPackFlags.NONE);
this._searchAreaApps = this._searchPane.packResults(AppDisplay.AppDisplay, false);
- this._searchPane.content.append(new Clutter.Text({ color: DASH_SECTION_COLOR,
+ this._searchPane.content.append(new Clutter.Text({ color: TEXT_COLOR,
font_name: 'Sans Bold 10px',
text: "RECENT DOCUMENTS" }),
Big.BoxPackFlags.NONE);
@@ -360,8 +471,9 @@ Dash.prototype = {
}
this._searchQueued = true;
Mainloop.timeout_add(250, Lang.bind(this, function() {
+ let text = this._searchEntry.getText();
// Strip leading and trailing whitespace
- let text = this._searchEntry.entry.text.replace(/^\s+/g, "").replace(/\s+$/g, "");
+ text = text.replace(/^\s+/g, "").replace(/\s+$/g, "");
this._searchQueued = false;
this._searchAreaApps.setSearch(text);
this._searchAreaDocs.setSearch(text);
@@ -380,12 +492,13 @@ Dash.prototype = {
return true;
}));
this._searchEntry.entry.connect('key-press-event', Lang.bind(this, function (se, e) {
+ let text = this._searchEntry.getText();
let symbol = Shell.get_event_key_symbol(e);
if (symbol == Clutter.Escape) {
// Escape will keep clearing things back to the desktop. First, if
// we have active text, we remove it.
- if (this._searchEntry.entry.text != '')
- this._searchEntry.entry.text = '';
+ if (text != '')
+ this._searchEntry.reset();
// Next, if we're in one of the "more" modes or showing the details pane, close them
else if (this._activePane != null)
this._activePane.close();
@@ -423,64 +536,49 @@ Dash.prototype = {
/***** Applications *****/
- let appsHeader = new SectionHeader("APPLICATIONS");
- this._appsSection = new Big.Box({ spacing: DEFAULT_PADDING });
- this._appsSection.append(appsHeader.actor, Big.BoxPackFlags.NONE);
-
- this._appsContent = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
- this._appsSection.append(this._appsContent, Big.BoxPackFlags.EXPAND);
- this._appWell = new AppDisplay.AppWell();
- this._appsContent.append(this._appWell.actor, Big.BoxPackFlags.EXPAND);
+ let appsSection = new Section("APPLICATIONS");
+ let appWell = new AppDisplay.AppWell();
+ appsSection.content.append(appWell.actor, Big.BoxPackFlags.EXPAND);
this._moreAppsPane = null;
- appsHeader.moreLink.connect('activated', Lang.bind(this, function (link) {
+ appsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
if (this._moreAppsPane == null) {
- this._moreAppsPane = new ResultPane(this, this._detailsWidth);
+ this._moreAppsPane = new ResultPane(this);
this._moreAppsPane.packResults(AppDisplay.AppDisplay, true);
this._addPane(this._moreAppsPane);
link.setPane(this._moreAppsPane);
}
}));
- this.dashContainer.append(this._appsSection, Big.BoxPackFlags.NONE);
+ this.sectionArea.append(appsSection.actor, Big.BoxPackFlags.NONE);
/***** Places *****/
- let placesSection = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
- spacing: DEFAULT_PADDING });
- let placesHeader = new SectionHeader("PLACES");
- placesSection.append(placesHeader.actor, Big.BoxPackFlags.NONE);
-
+ let placesSection = new Section("PLACES", true);
let placesDisplay = new Places.Places();
- placesSection.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND);
-
- this.dashContainer.append(placesSection, Big.BoxPackFlags.NONE);
+ placesSection.content.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND);
+ this.sectionArea.append(placesSection.actor, Big.BoxPackFlags.NONE);
/***** Documents *****/
- this._docsSection = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
- spacing: DEFAULT_PADDING });
+ let docsSection = new Section("RECENT DOCUMENTS");
+
+ let docDisplay = new DocDisplay.DocDisplay();
+ docDisplay.load();
+ docsSection.content.append(docDisplay.actor, Big.BoxPackFlags.EXPAND);
+ createPaneForDetails(this, docDisplay);
+
this._moreDocsPane = null;
-
- let docsHeader = new SectionHeader("RECENT DOCUMENTS");
- this._docsSection.append(docsHeader.actor, Big.BoxPackFlags.NONE);
-
- this._docDisplay = new DocDisplay.DocDisplay();
- this._docDisplay.load();
- this._docsSection.append(this._docDisplay.actor, Big.BoxPackFlags.EXPAND);
-
- createPaneForDetails(this, this._docDisplay, this._detailsWidth);
-
- docsHeader.moreLink.connect('activated', Lang.bind(this, function (link) {
+ docsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
if (this._moreDocsPane == null) {
- this._moreDocsPane = new ResultPane(this, this._detailsWidth);
+ this._moreDocsPane = new ResultPane(this);
this._moreDocsPane.packResults(DocDisplay.DocDisplay, true);
this._addPane(this._moreDocsPane);
link.setPane(this._moreDocsPane);
}
}));
- this.dashContainer.append(this._docsSection, Big.BoxPackFlags.EXPAND);
+ this.sectionArea.append(docsSection.actor, Big.BoxPackFlags.EXPAND);
},
show: function() {
@@ -489,9 +587,8 @@ Dash.prototype = {
},
hide: function() {
- this._firstSelectAfterOverviewShow = true;
- if (this._searchEntry.entry.text != '')
- this._searchEntry.entry.text = '';
+ this._firstSelectAfterOverlayShow = true;
+ this._searchEntry.reset();
if (this._activePane != null)
this._activePane.close();
},
diff --git a/js/ui/docDisplay.js b/js/ui/docDisplay.js
index d2d4fa305..8dd133966 100644
--- a/js/ui/docDisplay.js
+++ b/js/ui/docDisplay.js
@@ -68,13 +68,13 @@ DocDisplayItem.prototype = {
// Creates and returns a large preview icon, but only if this._docInfo is an image file
// and we were able to generate a pixbuf from it successfully.
- _createLargePreviewIcon : function(availableWidth, availableHeight) {
+ _createLargePreviewIcon : function() {
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
return null;
try {
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
- this._docInfo.uri, availableWidth, availableHeight);
+ this._docInfo.uri, -1, -1);
} catch (e) {
// An exception will be raised when the image format isn't know
/* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should
diff --git a/js/ui/genericDisplay.js b/js/ui/genericDisplay.js
index 3dbc4e92f..6f1347791 100644
--- a/js/ui/genericDisplay.js
+++ b/js/ui/genericDisplay.js
@@ -183,18 +183,14 @@ GenericDisplayItem.prototype = {
/*
* Returns an actor containing item details. In the future details can have more information than what
* the preview pop-up has and be item-type specific.
- *
- * availableWidth - width available for displaying details
*/
- createDetailsActor: function(availableWidth) {
+ createDetailsActor: function() {
let details = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
- spacing: PREVIEW_BOX_SPACING,
- width: availableWidth });
+ spacing: PREVIEW_BOX_SPACING });
let mainDetails = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
- spacing: PREVIEW_BOX_SPACING,
- width: availableWidth });
+ spacing: PREVIEW_BOX_SPACING });
// Inner box with name and description
let textDetails = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
@@ -216,7 +212,7 @@ GenericDisplayItem.prototype = {
mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND);
let previewIcon = this._createPreviewIcon();
- let largePreviewIcon = this._createLargePreviewIcon(availableWidth, -1);
+ let largePreviewIcon = this._createLargePreviewIcon();
if (previewIcon != null && largePreviewIcon == null) {
mainDetails.prepend(previewIcon, Big.BoxPackFlags.NONE);
@@ -303,7 +299,7 @@ GenericDisplayItem.prototype = {
//// Virtual protected methods ////
// Creates and returns a large preview icon, but only if we have a detailed image.
- _createLargePreviewIcon : function(availableWidth, availableHeight) {
+ _createLargePreviewIcon : function() {
return null;
},
@@ -465,9 +461,9 @@ GenericDisplay.prototype = {
return null;
},
- createDetailsForIndex: function(index, width, height) {
+ createDetailsForIndex: function(index) {
let item = this._findDisplayedByIndex(index);
- return item.createDetailsActor(width, height);
+ return item.createDetailsActor();
},
//// Protected methods ////
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 9d42ed159..94b4cbdc4 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -109,7 +109,7 @@ Overview.prototype = {
global.overlay_group.add_actor(this._group);
// TODO - recalculate everything when desktop size changes
- this._dash = new Dash.Dash(displayGridColumnWidth);
+ this._dash = new Dash.Dash();
this._group.add_actor(this._dash.actor);
// Container to hold popup pane chrome.
@@ -149,10 +149,34 @@ Overview.prototype = {
relayout: function () {
let global = Shell.Global.get();
- let contentHeight = global.screen_height - Panel.PANEL_HEIGHT;
+ let screenHeight = global.screen_height;
+ let screenWidth = global.screen_width;
- this._dash.actor.set_position(0, Panel.PANEL_HEIGHT);
- this._dash.actor.set_size(displayGridColumnWidth, contentHeight);
+ let contentHeight = screenHeight - Panel.PANEL_HEIGHT;
+
+ let workspaceColumnsUsed = wideScreen ? COLUMNS_FOR_WORKSPACES_WIDE_SCREEN : COLUMNS_FOR_WORKSPACES_REGULAR_SCREEN;
+ let workspaceRowsUsed = wideScreen ? ROWS_FOR_WORKSPACES_WIDE_SCREEN : ROWS_FOR_WORKSPACES_REGULAR_SCREEN;
+
+ this._workspacesWidth = displayGridColumnWidth * workspaceColumnsUsed
+ - WORKSPACE_GRID_PADDING * 2;
+ // We scale the vertical padding by (screenHeight / screenWidth)
+ // so that the workspace preserves its aspect ratio.
+ this._workspacesHeight = displayGridRowHeight * workspaceRowsUsed
+ - WORKSPACE_GRID_PADDING * (screenHeight / screenWidth) * 2;
+
+ this._workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
+ this._workspacesY = displayGridRowHeight + WORKSPACE_GRID_PADDING * (screenHeight / screenWidth);
+
+ let dashY = Panel.PANEL_HEIGHT;
+ this._dash.actor.set_position(0, dashY);
+ this._dash.actor.set_size(displayGridColumnWidth, screenHeight - dashY);
+ this._dash.searchArea.height = this._workspacesY - dashY;
+ this._dash.sectionArea.height = this._workspacesHeight;
+
+ // place the 'Add Workspace' button in the bottom row of the grid
+ this._addButtonSize = Math.floor(displayGridRowHeight * 3/5);
+ this._addButtonX = this._workspacesX + this._workspacesWidth - this._addButtonSize;
+ this._addButtonY = screenHeight - Math.floor(displayGridRowHeight * 4/5);
this._backOver.set_position(0, Panel.PANEL_HEIGHT);
this._backOver.set_size(global.screen_width, contentHeight);
@@ -165,10 +189,12 @@ Overview.prototype = {
this._transparentBackground.set_position(this._paneContainer.x, this._paneContainer.y);
this._transparentBackground.set_size(global.screen_width - this._paneContainer.x,
this._paneContainer.height);
+
+ if (this._activeDisplayPane != null)
+ this._activeDisplayPane.actor.width = displayGridColumnWidth * 2;
},
addPane: function (pane) {
- pane.actor.width = displayGridColumnWidth * 2;
this._paneContainer.append(pane.actor, Big.BoxPackFlags.NONE);
// When a pane is displayed, we raise the transparent background to the top
// and connect to button-release-event on it, then raise the pane above that.
@@ -177,6 +203,7 @@ Overview.prototype = {
let backgroundEventId = null;
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
if (isOpen) {
+ pane.actor.width = displayGridColumnWidth * 2;
this._activeDisplayPane = pane;
this._transparentBackground.raise_top();
this._paneContainer.raise_top();
@@ -251,28 +278,13 @@ Overview.prototype = {
this.animationInProgress = true;
let global = Shell.Global.get();
- let screenWidth = global.screen_width;
- let screenHeight = global.screen_height;
this._dash.show();
- let columnsUsed = wideScreen ? COLUMNS_FOR_WORKSPACES_WIDE_SCREEN : COLUMNS_FOR_WORKSPACES_REGULAR_SCREEN;
- let rowsUsed = wideScreen ? ROWS_FOR_WORKSPACES_WIDE_SCREEN : ROWS_FOR_WORKSPACES_REGULAR_SCREEN;
-
- let workspacesWidth = displayGridColumnWidth * columnsUsed - WORKSPACE_GRID_PADDING * 2;
- // We scale the vertical padding by (screenHeight / screenWidth) so that the workspace preserves its aspect ratio.
- let workspacesHeight = displayGridRowHeight * rowsUsed - WORKSPACE_GRID_PADDING * (screenHeight / screenWidth) * 2;
-
- let workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
- let workspacesY = displayGridRowHeight + WORKSPACE_GRID_PADDING * (screenHeight / screenWidth);
-
- // place the 'Add Workspace' button in the bottom row of the grid
- let addButtonSize = Math.floor(displayGridRowHeight * 3/5);
- let addButtonX = workspacesX + workspacesWidth - addButtonSize;
- let addButtonY = screenHeight - Math.floor(displayGridRowHeight * 4/5);
-
- this._workspaces = new Workspaces.Workspaces(workspacesWidth, workspacesHeight, workspacesX, workspacesY,
- addButtonSize, addButtonX, addButtonY);
+ /* TODO: make this stuff dynamic */
+ this._workspaces = new Workspaces.Workspaces(this._workspacesWidth, this._workspacesHeight,
+ this._workspacesX, this._workspacesY,
+ this._addButtonSize, this._addButtonX, this._addButtonY);
this._group.add_actor(this._workspaces.actor);
// The workspaces actor is as big as the screen, so we have to raise the dash above it
diff --git a/js/ui/panel.js b/js/ui/panel.js
index fa9d6d047..c919ada85 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -20,8 +20,11 @@ const DEFAULT_PADDING = 4;
const PANEL_ICON_SIZE = 24;
-const PANEL_BACKGROUND_COLOR = new Clutter.Color();
-PANEL_BACKGROUND_COLOR.from_pixel(0x000000ff);
+const BACKGROUND_TOP = new Clutter.Color();
+BACKGROUND_TOP.from_pixel(0x414141ff);
+const BACKGROUND_BOTTOM = new Clutter.Color();
+BACKGROUND_BOTTOM.from_pixel(0x000000ff);
+
const PANEL_FOREGROUND_COLOR = new Clutter.Color();
PANEL_FOREGROUND_COLOR.from_pixel(0xffffffff);
const SN_BACKGROUND_COLOR = new Clutter.Color();
@@ -83,8 +86,7 @@ AppPanelMenu.prototype = {
this.actor.append(labelBox, Big.BoxPackFlags.NONE);
this._startupBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
- y_align: Big.BoxAlignment.CENTER
- });
+ y_align: Big.BoxAlignment.CENTER });
this.actor.append(this._startupBox, Big.BoxPackFlags.NONE);
Main.overview.connect('hiding', Lang.bind(this, function () {
@@ -161,9 +163,17 @@ Panel.prototype = {
_init : function() {
let global = Shell.Global.get();
- this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
- background_color: PANEL_BACKGROUND_COLOR
+
+ this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL
});
+ let backgroundGradient = Shell.create_vertical_gradient(BACKGROUND_TOP,
+ BACKGROUND_BOTTOM);
+ this.actor.connect('notify::allocation', Lang.bind(this, function () {
+ let [width, height] = this.actor.get_size();
+ backgroundGradient.set_size(width, height);
+ }));
+ this.actor.add_actor(backgroundGradient);
+
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
y_align: Big.BoxAlignment.CENTER,
spacing: DEFAULT_PADDING,
diff --git a/js/ui/workspaces.js b/js/ui/workspaces.js
index e1c6aba52..0618518c2 100644
--- a/js/ui/workspaces.js
+++ b/js/ui/workspaces.js
@@ -398,7 +398,9 @@ Workspace.prototype = {
// Mark the workspace selected/not-selected
setSelected : function(selected) {
- if (selected) {
+ let global = Shell.Global.get();
+ // Don't draw a frame if we only have one workspace
+ if (selected && global.screen.n_workspaces > 1) {
if (this._frame)
return;
@@ -1112,6 +1114,11 @@ Workspaces.prototype = {
// FIXME: deal with windows on the lost workspaces
}
+
+ // Reset the selection state; if we went from > 1 workspace to 1,
+ // this has the side effect of removing the frame border
+ let activeIndex = global.screen.get_active_workspace_index();
+ this._workspaces[activeIndex].setSelected(true);
},
_activeWorkspaceChanged : function(wm, from, to, direction) {