Bug 591246 - Move towards shell-black02 mockup

Remove the last use of passing width into Dash by having the
Pane with the previews scaling dynamically and relying on
Clutter scaling.

If we only have one workspace, don't display a selection frame
for it.

Rework Dash into a searchArea and sectionArea, which get
explicitly sized by overlay.js.  We use the workspaces size
to choose the size of those dash areas.

Switch dash colors/boxes etc. to ones from shell-black02.

Add a gradient to the panel.

Add a magnifier.svg for use in search.
This commit is contained in:
Colin Walters 2009-08-09 19:48:54 -04:00
parent 25a5da074c
commit f00500d3d5
10 changed files with 301 additions and 246 deletions

View File

@ -18,9 +18,8 @@ dist_image_DATA = \
add-workspace.svg \ add-workspace.svg \
close.svg \ close.svg \
info.svg \ info.svg \
remove-workspace.svg \ magnifier.svg \
view-more-activated.svg \ remove-workspace.svg
view-more.svg
schemadir = @GCONF_SCHEMA_FILE_DIR@ schemadir = @GCONF_SCHEMA_FILE_DIR@
schema_DATA = gnome-shell.schemas schema_DATA = gnome-shell.schemas

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) --> <!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg <svg
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#" xmlns:cc="http://creativecommons.org/ns#"
@ -18,12 +19,12 @@
enable-background="new 0 0 29 18" enable-background="new 0 0 29 18"
xml:space="preserve" xml:space="preserve"
sodipodi:version="0.32" sodipodi:version="0.32"
inkscape:version="0.46" inkscape:version="0.46+devel"
sodipodi:docname="search_1.svg" sodipodi:docname="magnifier.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
id="metadata16"><rdf:RDF><cc:Work id="metadata16"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs14"><inkscape:perspective id="defs14"><inkscape:perspective
sodipodi:type="inkscape:persp3d" sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 9 : 1" inkscape:vp_x="0 : 9 : 1"
@ -34,40 +35,41 @@
inkscape:window-height="728" inkscape:window-height="728"
inkscape:window-width="1103" inkscape:window-width="1103"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:pageopacity="0.0" inkscape:pageopacity="0"
guidetolerance="10.0" guidetolerance="10.0"
gridtolerance="10.0" gridtolerance="10.0"
objecttolerance="10.0" objecttolerance="10.0"
borderopacity="1.0" borderopacity="1.0"
bordercolor="#666666" bordercolor="#666666"
pagecolor="#ffffff" pagecolor="#000000"
id="base" id="base"
showgrid="false" showgrid="false"
inkscape:zoom="19.275862" inkscape:zoom="27.260185"
inkscape:cx="14.5" inkscape:cx="14.5"
inkscape:cy="9" inkscape:cy="9"
inkscape:window-x="40" inkscape:window-x="142"
inkscape:window-y="40" inkscape:window-y="25"
inkscape:current-layer="Foreground"><inkscape:grid inkscape:current-layer="Foreground"><inkscape:grid
type="xygrid" type="xygrid"
id="grid2391" /></sodipodi:namedview> id="grid2391"
<path empspacing="5"
d="M0,3c0-1.657,1.343-3,3-3h17c0.515,0,1.027,0.195,1.42,0.588l6.992,6.992c0.784,0.784,0.784,2.056,0,2.84l-6.992,6.992 C21.028,17.804,20.514,18,20,18H3c-1.657,0-3-1.343-3-3V3z" visible="true"
id="path3" enabled="true"
style="fill:#151e2f;fill-opacity:1" /> snapvisiblegridlinesonly="true" /></sodipodi:namedview>
<g <g
id="g5" id="g5"
style="fill:#4669a9;fill-opacity:1"> style="fill:#ffffff;fill-opacity:1">
<path <path
fill="#FFFFFF" fill="#FFFFFF"
d="M6.246,13.98c-0.319-0.319-0.319-0.837,0-1.157l3.717-3.717c0.319-0.319,0.837-0.319,1.157,0l0.786,0.787 c0.32,0.319,0.32,0.837,0,1.157l-3.717,3.717c-0.32,0.319-0.838,0.319-1.157,0L6.246,13.98L6.246,13.98z" d="M6.246,13.98c-0.319-0.319-0.319-0.837,0-1.157l3.717-3.717c0.319-0.319,0.837-0.319,1.157,0l0.786,0.787 c0.32,0.319,0.32,0.837,0,1.157l-3.717,3.717c-0.32,0.319-0.838,0.319-1.157,0L6.246,13.98L6.246,13.98z"
id="path7" id="path7"
style="fill:#4669a9;fill-opacity:1" /> style="fill:#ffffff;fill-opacity:1" />
<path <path
fill="#FFFFFF" fill="#FFFFFF"
d="M9.076,11.937" d="M9.076,11.937"
id="path9" id="path9"
style="fill:#4669a9;fill-opacity:1" /> style="fill:#ffffff;fill-opacity:1" />
</g> </g>
<path <path
fill-rule="evenodd" fill-rule="evenodd"
@ -75,5 +77,5 @@
fill="#FFFFFF" fill="#FFFFFF"
d="M11.25,7.5c0-1.243,1.007-2.25,2.25-2.25s2.25,1.007,2.25,2.25 s-1.007,2.25-2.25,2.25S11.25,8.743,11.25,7.5z M9,7.5C9,5.015,11.015,3,13.5,3S18,5.015,18,7.5S15.985,12,13.5,12S9,9.985,9,7.5z" d="M11.25,7.5c0-1.243,1.007-2.25,2.25-2.25s2.25,1.007,2.25,2.25 s-1.007,2.25-2.25,2.25S11.25,8.743,11.25,7.5z M9,7.5C9,5.015,11.015,3,13.5,3S18,5.015,18,7.5S15.985,12,13.5,12S9,9.985,9,7.5z"
id="path11" id="path11"
style="fill:#4669a9;fill-opacity:1" /> style="fill:#ffffff;fill-opacity:1" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,66 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Foreground"
x="0px"
y="0px"
width="29px"
height="18px"
viewBox="0 0 29 18"
enable-background="new 0 0 29 18"
xml:space="preserve"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="search_2.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
id="metadata16"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs14"><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 9 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="29 : 9 : 1"
inkscape:persp3d-origin="14.5 : 6 : 1"
id="perspective18" />
</defs><sodipodi:namedview
inkscape:window-height="728"
inkscape:window-width="1103"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
showgrid="false"
inkscape:zoom="19.275862"
inkscape:cx="14.5"
inkscape:cy="9"
inkscape:window-x="40"
inkscape:window-y="40"
inkscape:current-layer="Foreground"><inkscape:grid
type="xygrid"
id="grid2391" /></sodipodi:namedview>
<path
style="fill:#4669a9;fill-opacity:1"
id="path9"
d="" />
<path
id="path3"
style="fill:#3d5a93;fill-opacity:1"
d="M 0,3 C 0,1.343 1.343,0 3,0 L 20,0 C 20.515,0 21.027,0.195 21.42,0.588 L 28.412,7.58 C 29.196,8.364 29.196,9.636 28.412,10.42 L 21.42,17.412 C 21.028,17.804 20.514,18 20,18 L 3,18 C 1.343,18 0,16.657 0,15 L 0,3 zM 13.5,3 C 11.015,3 9,5.015 9,7.5 C 9,8.2423219 9.1815696,8.9452421 9.5,9.5625 L 6.25,12.8125 C 5.931,13.1325 5.9310002,13.64975 6.25,13.96875 L 7.03125,14.78125 C 7.35025,15.10025 7.8674999,15.10025 8.1875,14.78125 L 11.46875,11.5 C 12.080227,11.810879 12.767137,12 13.5,12 C 15.985,12 18,9.985 18,7.5 C 18,5.015 15.985,3 13.5,3 z M 11.25,7.5 C 11.25,6.257 12.257,5.25 13.5,5.25 C 14.743,5.25 15.75,6.257 15.75,7.5 C 15.75,8.743 14.743,9.75 13.5,9.75 C 12.257,9.75 11.25,8.743 11.25,7.5 z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -565,9 +565,7 @@ WellGrid.prototype = {
_init: function() { _init: function() {
this.actor = new Shell.GenericContainer(); this.actor = new Shell.GenericContainer();
this._separator = new Big.Box({ border_color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR, this._separator = new Big.Box({ height: 1 });
border_top: 1,
height: 1 });
this.actor.add_actor(this._separator); this.actor.add_actor(this._separator);
this._separatorIndex = 0; this._separatorIndex = 0;
this._cachedSeparatorY = 0; this._cachedSeparatorY = 0;

View File

@ -5,6 +5,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk; const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop; const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Signals = imports.signals; const Signals = imports.signals;
const Lang = imports.lang; const Lang = imports.lang;
@ -18,14 +19,35 @@ const Main = imports.ui.main;
const DEFAULT_PADDING = 4; const DEFAULT_PADDING = 4;
const DASH_SECTION_PADDING = 6; const DASH_SECTION_PADDING = 6;
const DASH_SECTION_SPACING = 12; const DASH_SECTION_SPACING = 40;
const DASH_CORNER_RADIUS = 5; const DASH_CORNER_RADIUS = 5;
const DASH_SEARCH_BG_COLOR = new Clutter.Color();
DASH_SEARCH_BG_COLOR.from_pixel(0xffffffff); const BACKGROUND_COLOR = new Clutter.Color();
const DASH_SECTION_COLOR = new Clutter.Color(); BACKGROUND_COLOR.from_pixel(0x000000c0);
DASH_SECTION_COLOR.from_pixel(0x846c3dff);
const DASH_TEXT_COLOR = new Clutter.Color(); const DASH_PADDING_SIDE = 14;
DASH_TEXT_COLOR.from_pixel(0xffffffff);
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(); const PANE_BORDER_COLOR = new Clutter.Color();
PANE_BORDER_COLOR.from_pixel(0x101d3cfa); PANE_BORDER_COLOR.from_pixel(0x101d3cfa);
@ -144,7 +166,7 @@ ResultArea.prototype = {
// Utility function shared between ResultPane and the DocDisplay in the main dash. // 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 // Connects to the detail signal of the display, and on-demand creates a new
// pane. // pane.
function createPaneForDetails(dash, display, detailsWidth) { function createPaneForDetails(dash, display) {
let detailPane = null; let detailPane = null;
display.connect('show-details', Lang.bind(this, function(display, index) { display.connect('show-details', Lang.bind(this, function(display, index) {
if (detailPane == null) { if (detailPane == null) {
@ -160,7 +182,7 @@ function createPaneForDetails(dash, display, detailsWidth) {
if (index >= 0) { if (index >= 0) {
detailPane.destroyContent(); detailPane.destroyContent();
let details = display.createDetailsForIndex(index, detailsWidth, -1); let details = display.createDetailsForIndex(index, -1);
detailPane.content.append(details, Big.BoxPackFlags.EXPAND); detailPane.content.append(details, Big.BoxPackFlags.EXPAND);
detailPane.open(); detailPane.open();
} else { } else {
@ -170,17 +192,16 @@ function createPaneForDetails(dash, display, detailsWidth) {
return null; return null;
} }
function ResultPane(dash, detailsWidth) { function ResultPane(dash) {
this._init(dash, detailsWidth); this._init(dash);
} }
ResultPane.prototype = { ResultPane.prototype = {
__proto__: Pane.prototype, __proto__: Pane.prototype,
_init: function(dash, detailsWidth) { _init: function(dash) {
Pane.prototype._init.call(this); Pane.prototype._init.call(this);
this._dash = dash; this._dash = dash;
this._detailsWidth = detailsWidth;
}, },
// Create an instance of displayClass and pack it into this pane's // Create an instance of displayClass and pack it into this pane's
@ -188,7 +209,7 @@ ResultPane.prototype = {
packResults: function(displayClass, enableNavigation) { packResults: function(displayClass, enableNavigation) {
let resultArea = new ResultArea(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.content.append(resultArea.actor, Big.BoxPackFlags.EXPAND);
this.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) { this.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
@ -206,31 +227,89 @@ SearchEntry.prototype = {
_init : function() { _init : function() {
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
y_align: Big.BoxAlignment.CENTER, y_align: Big.BoxAlignment.CENTER,
background_color: DASH_SEARCH_BG_COLOR, border_bottom: SECTION_BORDER,
corner_radius: 4, border_color: SEARCH_BORDER_BOTTOM_COLOR });
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);
this.pane = null; 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 // 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 // in it. See http://bugzilla.openedhand.com/show_bug.cgi?id=1365
this.entry = new Clutter.Text({ font_name: "Sans 14px", this.entry = new Clutter.Text(entryProperties);
editable: true, this.entry.connect('notify::text', Lang.bind(this, function () {
activatable: true, this._resetTextState();
singleLineMode: true, }));
text: ""
});
this.actor.append(this.entry, Big.BoxPackFlags.EXPAND); 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) { setPane: function (pane) {
this._pane = 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); Signals.addSignalMethods(SearchEntry.prototype);
@ -242,22 +321,21 @@ function MoreLink() {
MoreLink.prototype = { MoreLink.prototype = {
_init : function () { _init : function () {
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
padding_right: DEFAULT_PADDING,
padding_left: DEFAULT_PADDING, padding_left: DEFAULT_PADDING,
padding_right: DEFAULT_PADDING }); reactive: true,
let global = Shell.Global.get(); x_align: Big.BoxAlignment.CENTER,
let inactiveUri = "file://" + global.imagedir + "view-more.svg"; y_align: Big.BoxAlignment.CENTER,
let activeUri = "file://" + global.imagedir + "view-more-activated.svg"; border_left: SECTION_BORDER,
this._inactiveIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER, border_color: SECTION_BORDER_COLOR });
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);
this.pane = null; 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) { if (this.pane == null) {
// Ensure the pane is created; the activated handler will call setPane // Ensure the pane is created; the activated handler will call setPane
this.emit('activated'); this.emit('activated');
@ -270,41 +348,66 @@ MoreLink.prototype = {
setPane: function (pane) { setPane: function (pane) {
this._pane = pane; this._pane = pane;
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) { 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); Signals.addSignalMethods(MoreLink.prototype);
function SectionHeader(title) { function SectionHeader(title, suppressBrowse) {
this._init(title); this._init(title, suppressBrowse);
} }
SectionHeader.prototype = { SectionHeader.prototype = {
_init : function (title) { _init : function (title, suppressBrowse) {
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL }); this.actor = new Big.Box({ border: SECTION_BORDER,
let text = new Clutter.Text({ color: DASH_SECTION_COLOR, border_color: SECTION_BORDER_COLOR });
font_name: "Sans Bold 10px", 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 }); text: title });
textBox.append(text, Big.BoxPackFlags.NONE);
this._innerBox.append(textBox, Big.BoxPackFlags.EXPAND);
if (!suppressBrowse) {
this.moreLink = new MoreLink(); this.moreLink = new MoreLink();
this.actor.append(text, Big.BoxPackFlags.EXPAND); this._innerBox.append(this.moreLink.actor, Big.BoxPackFlags.END);
this.actor.append(this.moreLink.actor, Big.BoxPackFlags.END); }
} }
} }
function Dash(displayGridColumnWidth) { function Section(titleString, suppressBrowse) {
this._init(displayGridColumnWidth); 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 = { Dash.prototype = {
_init : function(displayGridColumnWidth) { _init : function() {
this._width = displayGridColumnWidth;
this._detailsWidth = displayGridColumnWidth * 2;
let global = Shell.Global.get(); let global = Shell.Global.get();
// dash and the popup panes need to be reactive so that the clicks in unoccupied places on them // 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 // 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 // wide as the details pane that was blocking the clicks to the workspaces underneath it even when the details pane
// was actually hidden. // was actually hidden.
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
width: this._width, background_color: BACKGROUND_COLOR,
padding: DEFAULT_PADDING, corner_radius: DASH_CORNER_RADIUS,
padding_left: DASH_PADDING_SIDE,
padding_right: DASH_PADDING_SIDE,
reactive: true }); reactive: true });
this.dashContainer = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, // 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 }); spacing: DASH_SECTION_SPACING });
this.actor.append(this.dashContainer, Big.BoxPackFlags.EXPAND);
this.actor.append(this.searchArea, Big.BoxPackFlags.NONE);
this.actor.append(this.sectionArea, Big.BoxPackFlags.NONE);
// The currently active popup display // The currently active popup display
this._activePane = null; this._activePane = null;
@ -333,24 +443,25 @@ Dash.prototype = {
this._searchPane = null; this._searchPane = null;
this._searchActive = false; this._searchActive = false;
this._searchEntry = new SearchEntry(); 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._searchAreaApps = null;
this._searchAreaDocs = null; this._searchAreaDocs = null;
this._searchQueued = false; this._searchQueued = false;
this._searchEntry.entry.connect('text-changed', Lang.bind(this, function (se, prop) { 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) if (this._searchQueued)
return; return;
if (this._searchPane == null) { if (this._searchPane == null) {
this._searchPane = new ResultPane(this, this._detailsWidth); this._searchPane = new ResultPane(this);
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', font_name: 'Sans Bold 10px',
text: "APPLICATIONS" }), text: "APPLICATIONS" }),
Big.BoxPackFlags.NONE); Big.BoxPackFlags.NONE);
this._searchAreaApps = this._searchPane.packResults(AppDisplay.AppDisplay, false); 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', font_name: 'Sans Bold 10px',
text: "RECENT DOCUMENTS" }), text: "RECENT DOCUMENTS" }),
Big.BoxPackFlags.NONE); Big.BoxPackFlags.NONE);
@ -360,8 +471,9 @@ Dash.prototype = {
} }
this._searchQueued = true; this._searchQueued = true;
Mainloop.timeout_add(250, Lang.bind(this, function() { Mainloop.timeout_add(250, Lang.bind(this, function() {
let text = this._searchEntry.getText();
// Strip leading and trailing whitespace // 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._searchQueued = false;
this._searchAreaApps.setSearch(text); this._searchAreaApps.setSearch(text);
this._searchAreaDocs.setSearch(text); this._searchAreaDocs.setSearch(text);
@ -380,12 +492,13 @@ Dash.prototype = {
return true; return true;
})); }));
this._searchEntry.entry.connect('key-press-event', Lang.bind(this, function (se, e) { 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); let symbol = Shell.get_event_key_symbol(e);
if (symbol == Clutter.Escape) { if (symbol == Clutter.Escape) {
// Escape will keep clearing things back to the desktop. First, if // Escape will keep clearing things back to the desktop. First, if
// we have active text, we remove it. // we have active text, we remove it.
if (this._searchEntry.entry.text != '') if (text != '')
this._searchEntry.entry.text = ''; this._searchEntry.reset();
// Next, if we're in one of the "more" modes or showing the details pane, close them // Next, if we're in one of the "more" modes or showing the details pane, close them
else if (this._activePane != null) else if (this._activePane != null)
this._activePane.close(); this._activePane.close();
@ -423,64 +536,49 @@ Dash.prototype = {
/***** Applications *****/ /***** Applications *****/
let appsHeader = new SectionHeader("APPLICATIONS"); let appsSection = new Section("APPLICATIONS");
this._appsSection = new Big.Box({ spacing: DEFAULT_PADDING }); let appWell = new AppDisplay.AppWell();
this._appsSection.append(appsHeader.actor, Big.BoxPackFlags.NONE); appsSection.content.append(appWell.actor, Big.BoxPackFlags.EXPAND);
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);
this._moreAppsPane = null; 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) { if (this._moreAppsPane == null) {
this._moreAppsPane = new ResultPane(this, this._detailsWidth); this._moreAppsPane = new ResultPane(this);
this._moreAppsPane.packResults(AppDisplay.AppDisplay, true); this._moreAppsPane.packResults(AppDisplay.AppDisplay, true);
this._addPane(this._moreAppsPane); this._addPane(this._moreAppsPane);
link.setPane(this._moreAppsPane); link.setPane(this._moreAppsPane);
} }
})); }));
this.dashContainer.append(this._appsSection, Big.BoxPackFlags.NONE); this.sectionArea.append(appsSection.actor, Big.BoxPackFlags.NONE);
/***** Places *****/ /***** Places *****/
let placesSection = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, let placesSection = new Section("PLACES", true);
spacing: DEFAULT_PADDING });
let placesHeader = new SectionHeader("PLACES");
placesSection.append(placesHeader.actor, Big.BoxPackFlags.NONE);
let placesDisplay = new Places.Places(); let placesDisplay = new Places.Places();
placesSection.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND); placesSection.content.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND);
this.sectionArea.append(placesSection.actor, Big.BoxPackFlags.NONE);
this.dashContainer.append(placesSection, Big.BoxPackFlags.NONE);
/***** Documents *****/ /***** Documents *****/
this._docsSection = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, let docsSection = new Section("RECENT DOCUMENTS");
spacing: DEFAULT_PADDING });
let docDisplay = new DocDisplay.DocDisplay();
docDisplay.load();
docsSection.content.append(docDisplay.actor, Big.BoxPackFlags.EXPAND);
createPaneForDetails(this, docDisplay);
this._moreDocsPane = null; this._moreDocsPane = null;
docsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
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) {
if (this._moreDocsPane == null) { if (this._moreDocsPane == null) {
this._moreDocsPane = new ResultPane(this, this._detailsWidth); this._moreDocsPane = new ResultPane(this);
this._moreDocsPane.packResults(DocDisplay.DocDisplay, true); this._moreDocsPane.packResults(DocDisplay.DocDisplay, true);
this._addPane(this._moreDocsPane); this._addPane(this._moreDocsPane);
link.setPane(this._moreDocsPane); link.setPane(this._moreDocsPane);
} }
})); }));
this.dashContainer.append(this._docsSection, Big.BoxPackFlags.EXPAND); this.sectionArea.append(docsSection.actor, Big.BoxPackFlags.EXPAND);
}, },
show: function() { show: function() {
@ -489,9 +587,8 @@ Dash.prototype = {
}, },
hide: function() { hide: function() {
this._firstSelectAfterOverviewShow = true; this._firstSelectAfterOverlayShow = true;
if (this._searchEntry.entry.text != '') this._searchEntry.reset();
this._searchEntry.entry.text = '';
if (this._activePane != null) if (this._activePane != null)
this._activePane.close(); this._activePane.close();
}, },

View File

@ -68,13 +68,13 @@ DocDisplayItem.prototype = {
// Creates and returns a large preview icon, but only if this._docInfo is an image file // 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. // 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) if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
return null; return null;
try { try {
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE, return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
this._docInfo.uri, availableWidth, availableHeight); this._docInfo.uri, -1, -1);
} catch (e) { } catch (e) {
// An exception will be raised when the image format isn't know // An exception will be raised when the image format isn't know
/* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should /* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should

View File

@ -183,18 +183,14 @@ GenericDisplayItem.prototype = {
/* /*
* Returns an actor containing item details. In the future details can have more information than what * 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. * 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, let details = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: PREVIEW_BOX_SPACING, spacing: PREVIEW_BOX_SPACING });
width: availableWidth });
let mainDetails = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, let mainDetails = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
spacing: PREVIEW_BOX_SPACING, spacing: PREVIEW_BOX_SPACING });
width: availableWidth });
// Inner box with name and description // Inner box with name and description
let textDetails = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, let textDetails = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
@ -216,7 +212,7 @@ GenericDisplayItem.prototype = {
mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND); mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND);
let previewIcon = this._createPreviewIcon(); let previewIcon = this._createPreviewIcon();
let largePreviewIcon = this._createLargePreviewIcon(availableWidth, -1); let largePreviewIcon = this._createLargePreviewIcon();
if (previewIcon != null && largePreviewIcon == null) { if (previewIcon != null && largePreviewIcon == null) {
mainDetails.prepend(previewIcon, Big.BoxPackFlags.NONE); mainDetails.prepend(previewIcon, Big.BoxPackFlags.NONE);
@ -303,7 +299,7 @@ GenericDisplayItem.prototype = {
//// Virtual protected methods //// //// Virtual protected methods ////
// Creates and returns a large preview icon, but only if we have a detailed image. // Creates and returns a large preview icon, but only if we have a detailed image.
_createLargePreviewIcon : function(availableWidth, availableHeight) { _createLargePreviewIcon : function() {
return null; return null;
}, },
@ -465,9 +461,9 @@ GenericDisplay.prototype = {
return null; return null;
}, },
createDetailsForIndex: function(index, width, height) { createDetailsForIndex: function(index) {
let item = this._findDisplayedByIndex(index); let item = this._findDisplayedByIndex(index);
return item.createDetailsActor(width, height); return item.createDetailsActor();
}, },
//// Protected methods //// //// Protected methods ////

View File

@ -109,7 +109,7 @@ Overview.prototype = {
global.overlay_group.add_actor(this._group); global.overlay_group.add_actor(this._group);
// TODO - recalculate everything when desktop size changes // 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); this._group.add_actor(this._dash.actor);
// Container to hold popup pane chrome. // Container to hold popup pane chrome.
@ -149,10 +149,34 @@ Overview.prototype = {
relayout: function () { relayout: function () {
let global = Shell.Global.get(); 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); let contentHeight = screenHeight - Panel.PANEL_HEIGHT;
this._dash.actor.set_size(displayGridColumnWidth, contentHeight);
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_position(0, Panel.PANEL_HEIGHT);
this._backOver.set_size(global.screen_width, contentHeight); 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_position(this._paneContainer.x, this._paneContainer.y);
this._transparentBackground.set_size(global.screen_width - this._paneContainer.x, this._transparentBackground.set_size(global.screen_width - this._paneContainer.x,
this._paneContainer.height); this._paneContainer.height);
if (this._activeDisplayPane != null)
this._activeDisplayPane.actor.width = displayGridColumnWidth * 2;
}, },
addPane: function (pane) { addPane: function (pane) {
pane.actor.width = displayGridColumnWidth * 2;
this._paneContainer.append(pane.actor, Big.BoxPackFlags.NONE); this._paneContainer.append(pane.actor, Big.BoxPackFlags.NONE);
// When a pane is displayed, we raise the transparent background to the top // 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. // and connect to button-release-event on it, then raise the pane above that.
@ -177,6 +203,7 @@ Overview.prototype = {
let backgroundEventId = null; let backgroundEventId = null;
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) { pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
if (isOpen) { if (isOpen) {
pane.actor.width = displayGridColumnWidth * 2;
this._activeDisplayPane = pane; this._activeDisplayPane = pane;
this._transparentBackground.raise_top(); this._transparentBackground.raise_top();
this._paneContainer.raise_top(); this._paneContainer.raise_top();
@ -251,28 +278,13 @@ Overview.prototype = {
this.animationInProgress = true; this.animationInProgress = true;
let global = Shell.Global.get(); let global = Shell.Global.get();
let screenWidth = global.screen_width;
let screenHeight = global.screen_height;
this._dash.show(); this._dash.show();
let columnsUsed = wideScreen ? COLUMNS_FOR_WORKSPACES_WIDE_SCREEN : COLUMNS_FOR_WORKSPACES_REGULAR_SCREEN; /* TODO: make this stuff dynamic */
let rowsUsed = wideScreen ? ROWS_FOR_WORKSPACES_WIDE_SCREEN : ROWS_FOR_WORKSPACES_REGULAR_SCREEN; this._workspaces = new Workspaces.Workspaces(this._workspacesWidth, this._workspacesHeight,
this._workspacesX, this._workspacesY,
let workspacesWidth = displayGridColumnWidth * columnsUsed - WORKSPACE_GRID_PADDING * 2; this._addButtonSize, this._addButtonX, this._addButtonY);
// 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);
this._group.add_actor(this._workspaces.actor); 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 // The workspaces actor is as big as the screen, so we have to raise the dash above it

View File

@ -20,8 +20,11 @@ const DEFAULT_PADDING = 4;
const PANEL_ICON_SIZE = 24; const PANEL_ICON_SIZE = 24;
const PANEL_BACKGROUND_COLOR = new Clutter.Color(); const BACKGROUND_TOP = new Clutter.Color();
PANEL_BACKGROUND_COLOR.from_pixel(0x000000ff); BACKGROUND_TOP.from_pixel(0x414141ff);
const BACKGROUND_BOTTOM = new Clutter.Color();
BACKGROUND_BOTTOM.from_pixel(0x000000ff);
const PANEL_FOREGROUND_COLOR = new Clutter.Color(); const PANEL_FOREGROUND_COLOR = new Clutter.Color();
PANEL_FOREGROUND_COLOR.from_pixel(0xffffffff); PANEL_FOREGROUND_COLOR.from_pixel(0xffffffff);
const SN_BACKGROUND_COLOR = new Clutter.Color(); const SN_BACKGROUND_COLOR = new Clutter.Color();
@ -83,8 +86,7 @@ AppPanelMenu.prototype = {
this.actor.append(labelBox, Big.BoxPackFlags.NONE); this.actor.append(labelBox, Big.BoxPackFlags.NONE);
this._startupBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, 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); this.actor.append(this._startupBox, Big.BoxPackFlags.NONE);
Main.overview.connect('hiding', Lang.bind(this, function () { Main.overview.connect('hiding', Lang.bind(this, function () {
@ -161,9 +163,17 @@ Panel.prototype = {
_init : function() { _init : function() {
let global = Shell.Global.get(); 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, this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
y_align: Big.BoxAlignment.CENTER, y_align: Big.BoxAlignment.CENTER,
spacing: DEFAULT_PADDING, spacing: DEFAULT_PADDING,

View File

@ -398,7 +398,9 @@ Workspace.prototype = {
// Mark the workspace selected/not-selected // Mark the workspace selected/not-selected
setSelected : function(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) if (this._frame)
return; return;
@ -1112,6 +1114,11 @@ Workspaces.prototype = {
// FIXME: deal with windows on the lost workspaces // 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) { _activeWorkspaceChanged : function(wm, from, to, direction) {