Compare commits

..

22 Commits

Author SHA1 Message Date
72a43a6001 Bump version to 3.15.1
Update NEWS.
2014-10-30 11:13:39 +00:00
5180ab262c appDisplay: Use EXTERNAL scroll policy
Now that we support the new policy type, we can just use it instead
of hiding the scrollbar.

https://bugzilla.gnome.org/show_bug.cgi?id=739379
2014-10-30 00:37:55 +01:00
5fca85cd28 scroll-view: Support GTK_POLICY_EXTERNAL
GTK+ added a new PolicyType which currently triggers compiler warnings
about unhandled values in switch statements. We also have a use case for
it already, so add support for the new policy type.

https://bugzilla.gnome.org/show_bug.cgi?id=739379
2014-10-30 00:37:55 +01:00
fb5b368ca7 Calendar: Inline _ellipsizeEventTime into caller
This patch inlines the function _ellipsizeEventTime into its only caller
_addEvent. This also removes the need for the global const
EventEllipses and is thus removed by this commit as well.

https://bugzilla.gnome.org/show_bug.cgi?id=727302
2014-10-27 19:31:05 -05:00
62b6419332 Calendar: sort multi-day events by ending day/time
With commit dc6a60dde, the calendar displays the ending day and time of
a continuing multi-day event on its ending day. This results in the list
not appearing to be sorted. This patch sorts the list according to the
displayed day/time.

With the two appointments
Thursday 0800-1000 Foo, and Wednesday 0900-Friday 1200 Bar and today
being Monday, the rest of the week list currently displays:
F ...1200 Bar
T    0800 Foo
With this patch, the displaying order is switched because Friday comes
after Thursday.

https://bugzilla.gnome.org/show_bug.cgi?id=727302
2014-10-27 15:31:32 -05:00
65c136f4ed Calendar: Show multi-day event continuation
Currently, multi-day events are shown as individual appointments on each
day.  This patch ellipsizes multi-day events to indicate continuation on
the prior or following day (or other time-period.)

The time label spot is now replaced by a box layout that contains the
prefix ellipsis label, the time label and the postfix ellipsis label.
In order to keep the alignment, ellipses are merely invisible (zero
opacity) when hidden.

The ellipses are styled using the events-day-time-ellipses class which,
by default, take the color of the event text.

When RTL is used, the box contents are adjusted accordingly (clutter
does that for us).

An event spanning three days now displays "...All Day..." in the
calendar on the second day.

https://bugzilla.gnome.org/show_bug.cgi?id=727302
2014-10-27 15:31:32 -05:00
34606c0a8c messageTray: Summarize notifications when messages queue up
It is really annoying for the user to acknowledge multiple notifications
when they queue up. So, to prevent a notification flood that has to be
handled by the user one-by-one, a summarized-notification feature is
added which leaves a single summarized-notification for the user,
replacing multiple notifications if the number exceeds 1, which they may
or may not acknowledge. When this summarized-notification is acknowledged,
the message-tray is opened where they can view the notifications that were
summarized. This helps the user concentrate on his primary task
simultaneously informing them about the new notifications.

https://bugzilla.gnome.org/show_bug.cgi?id=702460
2014-10-27 18:20:51 +01:00
260657c0b8 BackgroundCache: plug an Animation object leak
We need to return early in case the animation file is the same,
otherwise we'll create a new Animation object and leak the previous
one.

https://bugzilla.gnome.org/show_bug.cgi?id=739252
2014-10-27 17:50:41 +01:00
f5cc579272 Update Uzbek@cyrillic translation 2014-10-19 13:41:47 -04:00
b4ce0e7208 Update Uzbek@cyrillic translation 2014-10-18 19:45:55 -04:00
eb3fc7815e Use LC_TIME locale for strftime format string translations
We commonly mark strftime format strings for translation to account
for date/time representations without an existing strftime shortcut
("Yesterday %H%p"). As those translations are looked up according to
the locale defined by LC_MESSAGES, while the conversion characters
themselves are resolved according to LC_TIME, the result can be
rather odd when mixing locales ("Den 27. January"). The correct
solution would be to install translations for format strings in
the LC_TIME catalogue and look them up with dcgettext(), but we
don't have the infrastructure to do that easily. Work around this
by adding a helper method that looks up a string in LC_MESSAGES
using the locale defined by LC_TIME and use that to translate
format strings, which has the same result.

https://bugzilla.gnome.org/show_bug.cgi?id=738640
2014-10-16 23:41:51 +02:00
2f5a226bc2 Fix handling of SystemBackground
Since the background rework, SystemBackground is no longer a transparent
actor that you have to stack on top of a solid background, it is an
opaque actor. Fix the color of the background actor, and remove places
where we were setting the background color underneath the system background
and expecting blending - in particular, we can always set no_clear_hint
on the stage.

https://bugzilla.gnome.org/show_bug.cgi?id=738652
2014-10-16 17:16:06 -04:00
01eb79a3cc layout: Reset the OSK to the primary monitor when monitors change
When monitors change, the previous index might not mean the same
physical monitor anymore, in fact, it might become invalid. In the
latter case, we'll actually get a JS error when accessing
this.keyboardMonitor in _updateKeyboardBox() . To avoid this, let's
just always reset the OSK to the primary monitor.

https://bugzilla.gnome.org/show_bug.cgi?id=738536
2014-10-16 16:42:36 +02:00
7ea364ae8b Add Uzbek@cyrillic translation 2014-10-16 09:49:20 -04:00
48a6e6f309 main: Allow loading file-based stylesheets again
The gnome-classic mode ships a stylesheet on disk, so make sure to load
that if if we can't find any file in the resource itself.
2014-10-14 22:25:30 -07:00
0f63ad0fc1 gdm: Don't throw an error if there's no logo file 2014-10-14 20:00:25 -07:00
49c4ba5656 theme: make a GResource
Now that we have all the infrastructure ready, port the theme to a
GResource.

https://bugzilla.gnome.org/show_bug.cgi?id=736936
2014-10-14 18:54:18 -07:00
642bf2b778 theme: convert stylesheet loading to GFile
In preparation to making it a GResource.

https://bugzilla.gnome.org/show_bug.cgi?id=736936
2014-10-14 18:54:00 -07:00
328bb1c21b st: always use GFile internally
We're moving the theme infrastructure towards GResource, so as a first
step move all the loading to use GFiles instead of URIs or paths.

https://bugzilla.gnome.org/show_bug.cgi?id=736936
2014-10-14 18:53:39 -07:00
38add2e78b background: port to new GFile MetaBackground API
https://bugzilla.gnome.org/show_bug.cgi?id=736936
2014-10-14 18:51:29 -07:00
2dc41c944e texture-cache: remove unused base64 code path
This was introduced in b0c6cf3f to support image data for web search
providers, which do not exist anymore. Just remove it.

https://bugzilla.gnome.org/show_bug.cgi?id=736936
2014-10-14 18:50:48 -07:00
ea552ea157 keyboardManager: Adopt to changes in meta_display_freeze_keyboard 2014-10-14 14:47:23 -07:00
60 changed files with 1599 additions and 6036 deletions

1
.gitignore vendored
View File

@ -23,6 +23,7 @@ data/gnome-shell-wayland.desktop
data/gnome-shell-wayland.desktop.in
data/gnome-shell-extension-prefs.desktop
data/gnome-shell-extension-prefs.desktop.in
data/gnome-shell-theme.gresource
data/gschemas.compiled
data/perf-background.xml
data/org.gnome.shell.gschema.xml

55
NEWS
View File

@ -1,52 +1,19 @@
3.14.4
3.15.1
======
* Fix erroneous week numbers in calendar [Florian; #736722]
* Make slider scrolling smoother [Adel; #742648]
* Fix current day highlight on day change [Sebastian; #742492]
* Do not wake up the screen for disabled notifications [Florian; #744114]
* gdm: Fix user list accessibility [Florian; #729603]
* Work around background corruption with NVIDIA driver [Rui; #739178]
* Misc. bug fixes [Florian, Rui, Michele; #744575, #743993, #745245, #745570,
#737502]
* Use GResources for theme loading [Cosimo; #736936]
* Reset the OSK to primary on monitor changes [Rui; #738536]
* Use LC_TIME locale for format string translations [Florian; #738640]
* Summarize queued up notifications [Devyani; #702460]
* Improve handling of multi-day events [Andreas; #727302]
* Support EXTERNAL scroll policy type [Florian; #739379]
* Misc. bugfixes [Owen, Rui; #738652, #739252]
Contributors:
Michele, Adel Gadllah, Sebastian Keller, Rui Matos, Florian Müllner
Andreas Brauchli, Cosimo Cecchi, Devyani Kota, Rui Matos, Florian Müllner,
Jasper St. Pierre, Owen W. Taylor
Translations:
Matej Urbančič [sl], Samir Ribic [bs]
3.14.3
======
* Properly remove network connections from list [Ryan; #740227]
* Fix handling of cancel button on login screen [Ray; #740141]
* Fix build when using dash as default shell [Alexander; #739241]
* Make event list in calendar scrollable [Stalin; #705115]
* Fix calendar-server crash on DBus timeout [Giovanni; #735308]
* Fix gestures triggering erroneously [Florian; #740237]
Contributors:
Giovanni Campagna, Ryan Lortie, Florian Müllner, Stalin Pereira, Ray Strode,
Alexander Tsoy
3.14.2
======
* Do not hard-depend on latest NetworkManager [Florian; #738485]
* Fix check for isToday in calendar [Darcy; #738725]
* Fix workspace changes from app picker [Yuki; #737534]
* Misc. bug fixes [Yuki; #739497]
Contributors:
Darcy, Florian Müllner, Yuki
3.14.1.5
========
* Fix handing of SystemBackground [Owen; #738652]
* Summarize queued up notifications [Devyani; #702460]
* Plug an animation object leak [Rui; #739252]
* Improve handling of multi-day events [Andreas; #727302]
Contributors:
Andreas Brauchli, Devyani Kota, Rui Matos, Owen W. Taylor
Bahodir Mansurov [uz@cyrillic]
3.14.1
======

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.14.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.15.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -76,7 +76,7 @@ AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.15.90
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.14.4
MUTTER_MIN_VERSION=3.15.1
GTK_MIN_VERSION=3.13.2
GIO_MIN_VERSION=2.37.0
LIBECAL_MIN_VERSION=3.5.3
@ -232,9 +232,7 @@ esac
AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS"
AC_SUBST(AM_CFLAGS)
if test -z "${BROWSER_PLUGIN_DIR}"; then
BROWSER_PLUGIN_DIR="\${libdir}/mozilla/plugins"
fi
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
AC_CONFIG_FILES([

View File

@ -35,44 +35,11 @@ introspection_DATA = \
org.gnome.ShellSearchProvider.xml \
org.gnome.ShellSearchProvider2.xml
themedir = $(pkgdatadir)/theme
dist_theme_DATA = \
theme/calendar-arrow-left.svg \
theme/calendar-arrow-right.svg \
theme/calendar-today.svg \
theme/checkbox-focused.svg \
theme/checkbox-off-focused.svg \
theme/checkbox-off.svg \
theme/checkbox.svg \
theme/close-window.svg \
theme/close.svg \
theme/corner-ripple-ltr.png \
theme/corner-ripple-rtl.png \
theme/dash-placeholder.svg \
theme/filter-selected-ltr.svg \
theme/filter-selected-rtl.svg \
theme/gnome-shell.css \
theme/logged-in-indicator.svg \
theme/message-tray-background.png \
theme/more-results.svg \
theme/noise-texture.png \
theme/page-indicator-active.svg \
theme/page-indicator-inactive.svg \
theme/page-indicator-checked.svg \
theme/page-indicator-hover.svg \
theme/panel-button-border.svg \
theme/panel-button-highlight-narrow.svg \
theme/panel-button-highlight-wide.svg \
theme/process-working.svg \
theme/running-indicator.svg \
theme/source-button-border.svg \
theme/summary-counter.svg \
theme/toggle-off-us.svg \
theme/toggle-off-intl.svg \
theme/toggle-on-us.svg \
theme/toggle-on-intl.svg \
theme/ws-switch-arrow-up.png \
theme/ws-switch-arrow-down.png
resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/theme --generate-dependencies $(srcdir)/gnome-shell-theme.gresource.xml)
gnome-shell-theme.gresource: gnome-shell-theme.gresource.xml $(resource_files)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir)/theme $<
resourcedir = $(pkgdatadir)
resource_DATA = gnome-shell-theme.gresource
backgrounddir = $(pkgdatadir)
background_DATA = perf-background.xml
@ -116,7 +83,9 @@ EXTRA_DIST = \
perf-background.xml.in \
org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service.in \
org.gnome.shell.gschema.xml.in.in
org.gnome.shell.gschema.xml.in.in \
gnome-shell-theme.gresource.xml \
$(resource_files)
CLEANFILES += \
gnome-shell.desktop.in \
@ -128,4 +97,5 @@ CLEANFILES += \
perf-background.xml \
gschemas.compiled \
org.gnome.shell.gschema.valid \
org.gnome.shell.gschema.xml.in
org.gnome.shell.gschema.xml.in \
gnome-shell-theme.gresource

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell/theme">
<file>calendar-arrow-left.svg</file>
<file>calendar-arrow-right.svg</file>
<file>calendar-today.svg</file>
<file>checkbox-focused.svg</file>
<file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file>
<file>checkbox.svg</file>
<file>close-window.svg</file>
<file>close.svg</file>
<file>corner-ripple-ltr.png</file>
<file>corner-ripple-rtl.png</file>
<file>dash-placeholder.svg</file>
<file>filter-selected-ltr.svg</file>
<file>filter-selected-rtl.svg</file>
<file>gnome-shell.css</file>
<file>logged-in-indicator.svg</file>
<file>message-tray-background.png</file>
<file>more-results.svg</file>
<file>noise-texture.png</file>
<file>page-indicator-active.svg</file>
<file>page-indicator-inactive.svg</file>
<file>page-indicator-checked.svg</file>
<file>page-indicator-hover.svg</file>
<file>panel-button-border.svg</file>
<file>panel-button-highlight-narrow.svg</file>
<file>panel-button-highlight-wide.svg</file>
<file>process-working.svg</file>
<file>running-indicator.svg</file>
<file>source-button-border.svg</file>
<file>summary-counter.svg</file>
<file>toggle-off-us.svg</file>
<file>toggle-off-intl.svg</file>
<file>toggle-on-us.svg</file>
<file>toggle-on-intl.svg</file>
<file>ws-switch-arrow-up.png</file>
<file>ws-switch-arrow-down.png</file>
</gresource>
</gresources>

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
@ -126,7 +127,7 @@ const AuthPrompt = new Lang.Class({
this._initButtons();
let spinnerIcon = global.datadir + '/theme/process-working.svg';
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
@ -193,15 +194,17 @@ const AuthPrompt = new Lang.Class({
},
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
if (this._preemptiveAnswer) {
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer);
this._preemptiveAnswer = null;
return;
}
if (this._queryingService)
this.clear();
this._queryingService = serviceName;
if (this._preemptiveAnswer) {
this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer);
this._preemptiveAnswer = null;
return;
}
this.setPasswordChar(passwordChar);
this.setQuestion(question);
@ -258,7 +261,6 @@ const AuthPrompt = new Lang.Class({
_onVerificationComplete: function() {
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
},
_onReset: function() {
@ -430,7 +432,6 @@ const AuthPrompt = new Lang.Class({
reset: function() {
let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = true;
if (oldStatus == AuthPromptStatus.VERIFYING)
this._userVerifier.cancel();
@ -499,9 +500,6 @@ const AuthPrompt = new Lang.Class({
},
cancel: function() {
if (this.verificationStatus == AuthPromptStatus.NOT_VERIFYING || this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
return;
}
this.reset();
this.emit('cancelled');
}

View File

@ -22,7 +22,6 @@ const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
@ -71,9 +70,6 @@ const UserListItem = new Lang.Class({
this._userWidget = new UserWidget.UserWidget(this.user);
layout.add(this._userWidget.actor);
this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE);
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0 });
layout.add(this._timedLoginIndicator);
@ -541,24 +537,24 @@ const LoginDialog = new Lang.Class({
}
},
_updateLogoTexture: function(cache, uri) {
if (this._logoFileUri != uri)
_updateLogoTexture: function(cache, file) {
if (this._logoFile && !this._logoFile.equal(file))
return;
this._logoBin.destroy_all_children();
if (this._logoFileUri) {
if (this._logoFile) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri,
-1, _LOGO_ICON_HEIGHT,
scaleFactor));
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
-1, _LOGO_ICON_HEIGHT,
scaleFactor));
}
},
_updateLogo: function() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
this._updateLogoTexture(this._textureCache, this._logoFileUri);
this._logoFile = path ? Gio.file_new_for_path(path) : null;
this._updateLogoTexture(this._textureCache, this._logoFile);
},
_onPrompted: function() {
@ -647,8 +643,6 @@ const LoginDialog = new Lang.Class({
realmManager.release();
}));
this._updateCancelButton();
this._authPrompt.updateSensitivity(true);
this._showPrompt();
},

View File

@ -35,7 +35,7 @@ function releaseKeyboard() {
}
function holdKeyboard() {
global.freeze_keyboard(global.get_current_time());
global.display.freeze_keyboard(global.get_current_time());
}
const KeyboardManager = new Lang.Class({

View File

@ -12,7 +12,7 @@ const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const Animation = new Lang.Class({
Name: 'Animation',
_init: function(filename, width, height, speed) {
_init: function(file, width, height, speed) {
this.actor = new St.Bin();
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._speed = speed;
@ -23,7 +23,7 @@ const Animation = new Lang.Class({
this._frame = 0;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height, scaleFactor,
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations);
},
@ -82,7 +82,7 @@ const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init: function(filename, size) {
this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
_init: function(file, size) {
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
});

View File

@ -379,9 +379,7 @@ const AllView = new Lang.Class({
this.actor.add_actor(this._scrollView);
this._scrollView.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
// we are only using ScrollView for the fade effect, hide scrollbars
this._scrollView.vscroll.hide();
Gtk.PolicyType.EXTERNAL);
this._adjustment = this._scrollView.vscroll.adjustment;
this._pageIndicators = new PageIndicators();
@ -1564,11 +1562,10 @@ const AppIcon = new Lang.Class({
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._menuTimeoutId = 0;
this._stateChangedId = this.app.connect('notify::state', Lang.bind(this,
function () {
this._updateRunningStyle();
}));
this._updateRunningStyle();
this._stateChangedId = this.app.connect('notify::state',
Lang.bind(this,
this._onStateChanged));
this._onStateChanged();
},
_onDestroy: function() {
@ -1589,7 +1586,7 @@ const AppIcon = new Lang.Class({
}
},
_updateRunningStyle: function() {
_onStateChanged: function() {
if (this.app.state != Shell.AppState.STOPPED)
this.actor.add_style_class_name('running');
else
@ -1658,10 +1655,7 @@ const AppIcon = new Lang.Class({
if (!isPoppedUp)
this._onMenuPoppedDown();
}));
let id = Main.overview.connect('hiding', Lang.bind(this, function () { this._menu.close(); }));
this.actor.connect('destroy', function() {
Main.overview.disconnect(id);
});
Main.overview.connect('hiding', Lang.bind(this, function () { this._menu.close(); }));
this._menuManager.addMenu(this._menu);
}

View File

@ -127,6 +127,16 @@ const ANIMATION_MIN_WAKEUP_INTERVAL = 1.0;
let _backgroundCache = null;
function _fileEqual0(file1, file2) {
if (file1 == file2)
return true;
if (!file1 || !file2)
return false;
return file1.equal(file2);
}
const BackgroundCache = new Lang.Class({
Name: 'BackgroundCache',
@ -136,25 +146,25 @@ const BackgroundCache = new Lang.Class({
this._backgroundSources = {};
},
monitorFile: function(filename) {
if (this._fileMonitors[filename])
monitorFile: function(file) {
let key = file.hash();
if (this._fileMonitors[key])
return;
let file = Gio.File.new_for_path(filename);
let monitor = file.monitor(Gio.FileMonitorFlags.NONE, null);
monitor.connect('changed',
Lang.bind(this, function() {
this.emit('file-changed', filename);
this.emit('file-changed', file);
}));
this._fileMonitors[filename] = monitor;
this._fileMonitors[key] = monitor;
},
getAnimation: function(params) {
params = Params.parse(params, { filename: null,
params = Params.parse(params, { file: null,
onLoaded: null });
if (this._animationFilename == params.filename) {
if (_fileEqual0(this._animationFile, params.file)) {
if (params.onLoaded) {
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
params.onLoaded(this._animation);
@ -165,10 +175,10 @@ const BackgroundCache = new Lang.Class({
return;
}
let animation = new Animation({ filename: params.filename });
let animation = new Animation({ file: params.file });
animation.load(Lang.bind(this, function() {
this._animationFilename = params.filename;
this._animationFile = params.file;
this._animation = animation;
if (params.onLoaded) {
@ -221,14 +231,14 @@ const Background = new Lang.Class({
params = Params.parse(params, { monitorIndex: 0,
layoutManager: Main.layoutManager,
settings: null,
filename: null,
file: null,
style: null });
this.background = new Meta.Background({ meta_screen: global.screen });
this.background._delegate = this;
this._settings = params.settings;
this._filename = params.filename;
this._file = params.file;
this._style = params.style;
this._monitorIndex = params.monitorIndex;
this._layoutManager = params.layoutManager;
@ -295,20 +305,21 @@ const Background = new Lang.Class({
this.background.set_gradient(shadingType, color, secondColor);
},
_watchFile: function(filename) {
if (this._fileWatches[filename])
_watchFile: function(file) {
let key = file.hash();
if (this._fileWatches[key])
return;
this._cache.monitorFile(filename);
this._cache.monitorFile(file);
let signalId = this._cache.connect('file-changed',
Lang.bind(this, function(cache, changedFile) {
if (changedFile == filename) {
if (changedFile.equal(file)) {
let imageCache = Meta.BackgroundImageCache.get_default();
imageCache.purge(changedFile);
this.emit('changed');
}
}));
this._fileWatches[filename] = signalId;
this._fileWatches[key] = signalId;
},
_removeAnimationTimeout: function() {
@ -331,9 +342,9 @@ const Background = new Lang.Class({
this._animation.transitionProgress,
this._style);
} else if (files.length > 0) {
this.background.set_filename(files[0], this._style);
this.background.set_file(files[0], this._style);
} else {
this.background.set_filename(null, this._style);
this.background.set_file(null, this._style);
}
this._queueUpdateAnimation();
});
@ -390,28 +401,28 @@ const Background = new Lang.Class({
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
},
_loadAnimation: function(filename) {
this._cache.getAnimation({ filename: filename,
onLoaded: Lang.bind(this, function(animation) {
this._animation = animation;
_loadAnimation: function(file) {
this._cache.getAnimation({ file: file,
onLoaded: Lang.bind(this, function(animation) {
this._animation = animation;
if (!this._animation || this._cancellable.is_cancelled()) {
this._setLoaded();
return;
}
if (!this._animation || this._cancellable.is_cancelled()) {
this._setLoaded();
return;
}
this._updateAnimation();
this._watchFile(filename);
})
});
this._updateAnimation();
this._watchFile(file);
})
});
},
_loadImage: function(filename) {
this.background.set_filename(filename, this._style);
this._watchFile(filename);
_loadImage: function(file) {
this.background.set_file(file, this._style);
this._watchFile(file);
let cache = Meta.BackgroundImageCache.get_default();
let image = cache.load(filename);
let image = cache.load(file);
if (image.is_loaded())
this._setLoaded();
else {
@ -423,11 +434,11 @@ const Background = new Lang.Class({
}
},
_loadFile: function(filename) {
if (filename.endsWith('.xml'))
this._loadAnimation(filename);
_loadFile: function(file) {
if (file.get_basename().endsWith('.xml'))
this._loadAnimation(file);
else
this._loadImage(filename);
this._loadImage(file);
},
_load: function () {
@ -435,12 +446,12 @@ const Background = new Lang.Class({
this._loadPattern();
if (!this._filename) {
if (!this._file) {
this._setLoaded();
return;
}
this._loadFile(this._filename);
this._loadFile(this._file);
},
});
Signals.addSignalMethods(Background.prototype);
@ -451,12 +462,12 @@ const SystemBackground = new Lang.Class({
Name: 'SystemBackground',
_init: function() {
let filename = global.datadir + '/theme/noise-texture.png';
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
_systemBackground = new Meta.Background({ meta_screen: global.screen });
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
_systemBackground.set_filename(filename, GDesktopEnums.BackgroundStyle.WALLPAPER);
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
}
this.actor = new Meta.BackgroundActor({ meta_screen: global.screen,
@ -464,7 +475,7 @@ const SystemBackground = new Lang.Class({
background: _systemBackground });
let cache = Meta.BackgroundImageCache.get_default();
let image = cache.load(filename);
let image = cache.load(file);
if (image.is_loaded()) {
image = null;
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
@ -513,20 +524,17 @@ const BackgroundSource = new Lang.Class({
},
getBackground: function(monitorIndex) {
let filename = null;
let file = null;
let style;
if (this._overrideImage != null) {
filename = this._overrideImage;
file = Gio.File.new_for_path(this._overrideImage);
style = GDesktopEnums.BackgroundStyle.ZOOM; // Hardcode
} else {
style = this._settings.get_enum(BACKGROUND_STYLE_KEY);
if (style != GDesktopEnums.BackgroundStyle.NONE) {
let uri = this._settings.get_string(PICTURE_URI_KEY);
if (GLib.uri_parse_scheme(uri) != null)
filename = Gio.File.new_for_uri(uri).get_path();
else
filename = uri;
file = Gio.File.new_for_commandline_arg(uri);
}
}
@ -534,7 +542,7 @@ const BackgroundSource = new Lang.Class({
// they can have variants that depend on the aspect ratio and
// size of the monitor; for other backgrounds we can use the
// same background object for all monitors.
if (filename == null || !filename.endsWith('.xml'))
if (file == null || !file.get_basename().endsWith('.xml'))
monitorIndex = 0;
if (!(monitorIndex in this._backgrounds)) {
@ -542,7 +550,7 @@ const BackgroundSource = new Lang.Class({
monitorIndex: monitorIndex,
layoutManager: this._layoutManager,
settings: this._settings,
filename: filename,
file: file,
style: style
});
@ -575,9 +583,9 @@ const Animation = new Lang.Class({
Name: 'Animation',
_init: function(params) {
params = Params.parse(params, { filename: null });
params = Params.parse(params, { file: null });
this.filename = params.filename;
this.file = params.file;
this.keyFrameFiles = [];
this.transitionProgress = 0.0;
this.transitionDuration = 0.0;
@ -585,9 +593,7 @@ const Animation = new Lang.Class({
},
load: function(callback) {
let file = Gio.File.new_for_path(this.filename);
this._show = new GnomeDesktop.BGSlideShow({ filename: this.filename });
this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
this._show.load_async(null,
Lang.bind(this,
@ -607,16 +613,16 @@ const Animation = new Lang.Class({
if (this._show.get_num_slides() < 1)
return;
let [progress, duration, isFixed, file1, file2] = this._show.get_current_slide(monitor.width, monitor.height);
let [progress, duration, isFixed, filename1, filename2] = this._show.get_current_slide(monitor.width, monitor.height);
this.transitionDuration = duration;
this.transitionProgress = progress;
if (file1)
this.keyFrameFiles.push(file1);
if (filename1)
this.keyFrameFiles.push(Gio.File.new_for_path(filename1));
if (file2)
this.keyFrameFiles.push(file2);
if (filename2)
this.keyFrameFiles.push(Gio.File.new_for_path(filename2));
},
});
Signals.addSignalMethods(Animation.prototype);

View File

@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const St = imports.gi.St;
@ -18,6 +17,7 @@ const ELLIPSIS_CHAR = '\u2026';
// alias to prevent xgettext from picking up strings translated in GTK+
const gtk30_ = Gettext_gtk30.gettext;
const NC_ = function(context, str) { return str; };
// in org.gnome.desktop.interface
const CLOCK_FORMAT_KEY = 'clock-format';
@ -90,6 +90,23 @@ function _formatEventTime(event, clockFormat, periodBegin, periodEnd) {
return ret;
}
function _getCalendarWeekForDate(date) {
// Based on the algorithms found here:
// http://en.wikipedia.org/wiki/Talk:ISO_week_date
let midnightDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
// Need to get Monday to be 1 ... Sunday to be 7
let dayOfWeek = 1 + ((midnightDate.getDay() + 6) % 7);
let nearestThursday = new Date(midnightDate.getFullYear(), midnightDate.getMonth(),
midnightDate.getDate() + (4 - dayOfWeek));
let jan1st = new Date(nearestThursday.getFullYear(), 0, 1);
let diffDate = nearestThursday - jan1st;
let dayNumber = Math.floor(Math.abs(diffDate) / MSECS_IN_DAY);
let weekNumber = Math.floor(dayNumber / 7) + 1;
return weekNumber;
}
function _getCalendarDayAbbreviation(dayNumber) {
let abbreviations = [
/* Translators: Calendar grid abbreviation for Sunday.
@ -235,24 +252,11 @@ const DBusEventSource = new Lang.Class({
this._initialized = false;
this._dbusProxy = new CalendarServer();
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(object, result) {
let loaded = false;
try {
this._dbusProxy.init_finish(result);
loaded = true;
} catch(e) {
if (e.matches(Gio.DBusError, Gio.DBusError.TIMED_OUT)) {
// Ignore timeouts and install signals as normal, because with high
// probability the service will appear later on, and we will get a
// NameOwnerChanged which will finish loading
//
// (But still _initialized to false, because the proxy does not know
// about the HasCalendars property and would cause an exception trying
// to read it)
} else {
log('Error loading calendars: ' + e.message);
return;
}
log('Error loading calendars: ' + e.message);
return;
}
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
@ -268,11 +272,9 @@ const DBusEventSource = new Lang.Class({
this.emit('notify::has-calendars');
}));
this._initialized = loaded;
if (loaded) {
this.emit('notify::has-calendars');
this._onNameAppeared();
}
this._initialized = true;
this.emit('notify::has-calendars');
this._onNameAppeared();
}));
},
@ -294,7 +296,6 @@ const DBusEventSource = new Lang.Class({
},
_onNameAppeared: function(owner) {
this._initialized = true;
this._resetCache();
this._loadEvents(true);
},
@ -603,7 +604,6 @@ const Calendar = new Lang.Class({
beginDate.setHours(12);
this._calendarBegin = new Date(beginDate);
this._markedAsToday = now;
let year = beginDate.getYear();
@ -671,7 +671,7 @@ const Calendar = new Lang.Class({
this._buttons.push(button);
if (this._useWeekdate && iter.getDay() == 4) {
let label = new St.Label({ text: iter.toLocaleFormat('%V'),
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
style_class: 'calendar-day-base calendar-week-number'});
layout.attach(label, rtl ? 7 : 0, row, 1, 1);
}
@ -695,7 +695,7 @@ const Calendar = new Lang.Class({
else
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormat);
if (!this._calendarBegin || !_sameMonth(this._selectedDate, this._calendarBegin) || !_sameDay(now, this._markedAsToday))
if (!this._calendarBegin || !_sameMonth(this._selectedDate, this._calendarBegin))
this._rebuildCalendar();
this._buttons.forEach(Lang.bind(this, function(button) {
@ -732,8 +732,6 @@ const EventsList = new Lang.Class({
},
_addEvent: function(event, index, includeDayName, periodBegin, periodEnd) {
let eventBox = new St.BoxLayout();
eventBox.set_vertical(false);
let dayString;
if (includeDayName) {
if (event.date >= periodBegin)
@ -754,7 +752,7 @@ const EventsList = new Lang.Class({
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
let layout = this.actor.layout_manager;
eventBox.add_actor(dayLabel);
layout.attach(dayLabel, rtl ? 2 : 0, index, 1, 1);
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
let timeString = _formatEventTime(event, clockFormat, periodBegin, periodEnd);
let timeLabel = new St.Label({ style_class: 'events-day-time',
@ -774,12 +772,11 @@ const EventsList = new Lang.Class({
if (event.allDay || event.end <= periodEnd)
postEllipsisLabel.opacity = 0;
let timeLabelBoxLayout = new St.BoxLayout({ x_align: Clutter.ActorAlign.START });
let timeLabelBoxLayout = new St.BoxLayout();
timeLabelBoxLayout.add(preEllipsisLabel);
timeLabelBoxLayout.add(timeLabel);
timeLabelBoxLayout.add(postEllipsisLabel);
timeLabelBoxLayout.set_size(50, 1);
eventBox.add_actor(timeLabelBoxLayout);
layout.attach(timeLabelBoxLayout, 1, index, 1, 1);
let titleLabel = new St.Label({ style_class: 'events-day-task',
text: event.summary,
@ -787,8 +784,7 @@ const EventsList = new Lang.Class({
titleLabel.clutter_text.line_wrap = true;
titleLabel.clutter_text.ellipsize = false;
eventBox.add_actor(titleLabel);
this._eventListBox.add_actor(eventBox);
layout.attach(titleLabel, rtl ? 0 : 2, index, 1, 1);
},
_addPeriod: function(header, index, periodBegin, periodEnd, includeDayName, showNothingScheduled) {
@ -798,7 +794,8 @@ const EventsList = new Lang.Class({
return index;
let label = new St.Label({ style_class: 'events-day-header', text: header });
this._eventListBox.add_actor(label);
let layout = this.actor.layout_manager;
layout.attach(label, 0, index, 3, 1);
index++;
for (let n = 0; n < events.length; n++) {
@ -817,21 +814,27 @@ const EventsList = new Lang.Class({
},
_showOtherDay: function(day) {
this.actor.destroy_all_children();
let dayBegin = _getBeginningOfDay(day);
let dayEnd = _getEndOfDay(day);
let dayString;
let dayFormat;
let now = new Date();
if (_sameYear(day, now))
/* Translators: Shown on calendar heading when selected day occurs on current year */
dayString = day.toLocaleFormat(C_("calendar heading", "%A, %B %d"));
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
"%A, %B %d"));
else
/* Translators: Shown on calendar heading when selected day occurs on different year */
dayString = day.toLocaleFormat(C_("calendar heading", "%A, %B %d, %Y"));
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
"%A, %B %d, %Y"));
let dayString = day.toLocaleFormat(dayFormat);
this._addPeriod(dayString, 0, dayBegin, dayEnd, false, true);
},
_showToday: function() {
this.actor.destroy_all_children();
let index = 0;
let now = new Date();
@ -876,24 +879,6 @@ const EventsList = new Lang.Class({
if (this._eventSource.isLoading)
return;
this.actor.destroy_all_children();
let layout = this.actor.layout_manager;
this._eventListContainer = new St.BoxLayout({ x_expand: true, y_expand: true });
this._eventListContainer.set_vertical(true);
this._eventListBox = new St.BoxLayout();
this._eventListBox.set_vertical(true);
let eventScrollView = new St.ScrollView({style_class: 'vfade',
hscrollbar_policy: Gtk.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC});
eventScrollView.add_actor(this._eventListBox);
this._eventListContainer.add_actor(eventScrollView);
layout.attach(this._eventListContainer, 0, 0, 1, 1);
let today = new Date();
if (_sameDay (this._date, today)) {
this._showToday();

View File

@ -604,15 +604,9 @@ const NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
_init: function() {
try {
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NMClient.SecretAgentCapabilities.VPN_HINTS
});
} catch(e) {
// Support older versions without NetworkAgent:capabilities
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent'
});
}
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NMClient.SecretAgentCapabilities.VPN_HINTS
});
this._dialogs = { };
this._vpnRequests = { };

View File

@ -36,6 +36,8 @@ const NotificationDirection = {
RECEIVED: 'chat-received'
};
const N_ = function(s) { return s; };
function makeMessageFromTpMessage(tpMessage, direction) {
let [text, flags] = tpMessage.to_text();
@ -950,70 +952,70 @@ const ChatNotification = new Lang.Class({
// Show only the time if date is on today
if(daysAgo < 1){
/* Translators: Time in 24h format */
format = _("%H\u2236%M");
format = N_("%H\u2236%M");
}
// Show the word "Yesterday" and time if date is on yesterday
else if(daysAgo <2){
/* Translators: this is the word "Yesterday" followed by a
time string in 24h format. i.e. "Yesterday, 14:30" */
// xgettext:no-c-format
format = _("Yesterday, %H\u2236%M");
format = N_("Yesterday, %H\u2236%M");
}
// Show a week day and time if date is in the last week
else if (daysAgo < 7) {
/* Translators: this is the week day name followed by a time
string in 24h format. i.e. "Monday, 14:30" */
// xgettext:no-c-format
format = _("%A, %H\u2236%M");
format = N_("%A, %H\u2236%M");
} else if (date.getYear() == now.getYear()) {
/* Translators: this is the month name and day number
followed by a time string in 24h format.
i.e. "May 25, 14:30" */
// xgettext:no-c-format
format = _("%B %d, %H\u2236%M");
format = N_("%B %d, %H\u2236%M");
} else {
/* Translators: this is the month name, day number, year
number followed by a time string in 24h format.
i.e. "May 25 2012, 14:30" */
// xgettext:no-c-format
format = _("%B %d %Y, %H\u2236%M");
format = N_("%B %d %Y, %H\u2236%M");
}
} else {
// Show only the time if date is on today
if(daysAgo < 1){
/* Translators: Time in 24h format */
format = _("%l\u2236%M %p");
format = N_("%l\u2236%M %p");
}
// Show the word "Yesterday" and time if date is on yesterday
else if(daysAgo <2){
/* Translators: this is the word "Yesterday" followed by a
time string in 12h format. i.e. "Yesterday, 2:30 pm" */
// xgettext:no-c-format
format = _("Yesterday, %l\u2236%M %p");
format = N_("Yesterday, %l\u2236%M %p");
}
// Show a week day and time if date is in the last week
else if (daysAgo < 7) {
/* Translators: this is the week day name followed by a time
string in 12h format. i.e. "Monday, 2:30 pm" */
// xgettext:no-c-format
format = _("%A, %l\u2236%M %p");
format = N_("%A, %l\u2236%M %p");
} else if (date.getYear() == now.getYear()) {
/* Translators: this is the month name and day number
followed by a time string in 12h format.
i.e. "May 25, 2:30 pm" */
// xgettext:no-c-format
format = _("%B %d, %l\u2236%M %p");
format = N_("%B %d, %l\u2236%M %p");
} else {
/* Translators: this is the month name, day number, year
number followed by a time string in 12h format.
i.e. "May 25 2012, 2:30 pm"*/
// xgettext:no-c-format
format = _("%B %d %Y, %l\u2236%M %p");
format = N_("%B %d %Y, %l\u2236%M %p");
}
}
return date.toLocaleFormat(format);
return date.toLocaleFormat(Shell.util_translate_time_string(format));
},
appendTimestamp: function() {
@ -1264,9 +1266,8 @@ const SubscriptionRequestNotification = new Lang.Class({
let file = contact.get_avatar_file();
if (file) {
let uri = file.get_uri();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size, scaleFactor);
iconBox.child = textureCache.load_file_async(file, iconBox._size, iconBox._size, scaleFactor);
}
else {
iconBox.child = new St.Icon({ icon_name: 'avatar-default',

View File

@ -513,13 +513,10 @@ const Dash = new Lang.Class({
this._syncLabel(item, appIcon);
}));
let id = Main.overview.connect('hiding', Lang.bind(this, function() {
Main.overview.connect('hiding', Lang.bind(this, function() {
this._labelShowing = false;
item.hideLabel();
}));
item.child.connect('destroy', function() {
Main.overview.disconnect(id);
});
if (appIcon) {
appIcon.connect('sync-tooltip', Lang.bind(this, function() {

View File

@ -59,7 +59,7 @@ const DateMenuButton = new Lang.Class({
// Fill up the first column
vbox = new St.BoxLayout({vertical: true, x_expand: true, y_expand: true });
vbox = new St.BoxLayout({vertical: true});
hbox.add(vbox);
// Date
@ -96,11 +96,11 @@ const DateMenuButton = new Lang.Class({
this._openCalendarItem = new PopupMenu.PopupMenuItem(_("Open Calendar"));
this._openCalendarItem.connect('activate', Lang.bind(this, this._onOpenCalendarActivate));
vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: false, y_fill: false});
vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
this._openClocksItem = new PopupMenu.PopupMenuItem(_("Open Clocks"));
this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate));
vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: false, y_fill: false});
vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._appInstalledChanged));
@ -129,7 +129,7 @@ const DateMenuButton = new Lang.Class({
/* Translators: This is the date format to use when the calendar popup is
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
*/
let dateFormat = _("%A %B %e, %Y");
let dateFormat = Shell.util_translate_time_string ("%A %B %e, %Y");
this._date.set_label(now.toLocaleFormat(dateFormat));
}
}));
@ -147,7 +147,7 @@ const DateMenuButton = new Lang.Class({
let now = new Date();
return now.getYear() == date.getYear() &&
now.getMonth() == date.getMonth() &&
now.getDate() == date.getDate();
now.getDay() == date.getDay();
},
_appInstalledChanged: function() {

View File

@ -6,8 +6,6 @@ const Meta = imports.gi.Meta;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Main = imports.ui.main;
const EDGE_THRESHOLD = 20;
const DRAG_DISTANCE = 80;
@ -15,10 +13,9 @@ const EdgeDragAction = new Lang.Class({
Name: 'EdgeDragAction',
Extends: Clutter.GestureAction,
_init : function(side, allowedModes) {
_init : function(side) {
this.parent();
this._side = side;
this._allowedModes = allowedModes;
this.set_n_touch_points(1);
global.display.connect('grab-op-begin', Lang.bind(this, function() {
@ -37,9 +34,6 @@ const EdgeDragAction = new Lang.Class({
if (this.get_n_current_points() == 0)
return false;
if (!(this._allowedModes & Main.keybindingMode))
return false;
let [x, y] = this.get_press_coords(0);
let monitorRect = this._getMonitorRect(x, y);

View File

@ -74,7 +74,7 @@ function disableExtension(uuid) {
if (extension.stylesheet) {
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.unload_stylesheet(extension.stylesheet.get_path());
theme.unload_stylesheet(extension.stylesheet);
}
try {
@ -118,7 +118,7 @@ function enableExtension(uuid) {
let stylesheetFile = extension.dir.get_child(stylesheetNames[i]);
if (stylesheetFile.query_exists(null)) {
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.load_stylesheet(stylesheetFile.get_path());
theme.load_stylesheet(stylesheetFile);
extension.stylesheet = stylesheetFile;
break;
}

View File

@ -11,7 +11,6 @@ const St = imports.gi.St;
const Background = imports.ui.background;
const BackgroundMenu = imports.ui.backgroundMenu;
const LoginManager = imports.misc.loginManager;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
@ -249,18 +248,6 @@ const LayoutManager = new Lang.Class({
global.screen.connect('in-fullscreen-changed',
Lang.bind(this, this._updateFullscreen));
this._monitorsChanged();
// NVIDIA drivers don't preserve FBO contents across
// suspend/resume, see
// https://bugzilla.gnome.org/show_bug.cgi?id=739178
if (Shell.util_need_background_refresh()) {
LoginManager.getLoginManager().connect('prepare-for-sleep',
function(lm, suspending) {
if (suspending)
return;
Meta.Background.refresh_all();
});
}
},
// This is called by Main after everything else is constructed
@ -435,10 +422,7 @@ const LayoutManager = new Lang.Class({
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
this.panelBox.set_size(this.primaryMonitor.width, -1);
if (this.keyboardIndex < 0)
this.keyboardIndex = this.primaryIndex;
else
this._updateKeyboardBox();
this.keyboardIndex = this.primaryIndex;
this.trayBox.set_position(this.bottomMonitor.x,
this.bottomMonitor.y + this.bottomMonitor.height);

View File

@ -129,6 +129,9 @@ function _initializeUI() {
Shell.WindowTracker.get_default();
Shell.AppUsage.get_default();
let resource = Gio.Resource.load(global.datadir + '/gnome-shell-theme.gresource');
resource._register();
_loadDefaultStylesheet();
// Setup the stage hierarchy early
@ -222,12 +225,26 @@ function _initializeUI() {
});
}
function _getDefaultStylesheet() {
let stylesheet;
stylesheet = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/' + sessionMode.stylesheetName);
if (stylesheet.query_exists(null))
return stylesheet;
stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + sessionMode.stylesheetName);
if (stylesheet.query_exists(null))
return stylesheet;
return null;
}
function _loadDefaultStylesheet() {
if (!sessionMode.isPrimary)
return;
let stylesheet = global.datadir + '/theme/' + sessionMode.stylesheetName;
if (_defaultCssStylesheet == stylesheet)
let stylesheet = _getDefaultStylesheet();
if (_defaultCssStylesheet && _defaultCssStylesheet.equal(stylesheet))
return;
_defaultCssStylesheet = stylesheet;
@ -254,7 +271,7 @@ function getThemeStylesheet() {
* Set the theme CSS file that the shell will load
*/
function setThemeStylesheet(cssStylesheet) {
_cssStylesheet = cssStylesheet;
_cssStylesheet = Gio.File.new_for_path(cssStylesheet);
}
/**

View File

@ -1951,9 +1951,7 @@ const MessageTray = new Lang.Class({
this._messageTrayMenuButton.actor.connect('key-press-event',
Lang.bind(this, this._onTrayButtonKeyPress));
let gesture = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM,
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
let gesture = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM);
gesture.connect('activated', Lang.bind(this, this.toggle));
global.stage.add_action(gesture);
},

View File

@ -194,7 +194,7 @@ const ModalDialog = new Lang.Class({
},
placeSpinner: function(layoutInfo) {
let spinnerIcon = global.datadir + '/theme/process-working.svg';
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show();

View File

@ -273,7 +273,7 @@ const AppMenuButton = new Lang.Class({
_onStyleChanged: function(actor) {
let node = actor.get_theme_node();
let [success, icon] = node.lookup_url('spinner-image', false);
if (!success || this._spinnerIcon == icon)
if (!success || (this._spinnerIcon && this._spinnerIcon.equal(icon)))
return;
this._spinnerIcon = icon;
this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE);

View File

@ -85,7 +85,8 @@ const Clock = new Lang.Class({
let date = new Date();
/* Translators: This is a time format for a date in
long format */
this._date.text = date.toLocaleFormat(_("%A, %B %d"));
let dateFormat = Shell.util_translate_time_string("%A, %B %d");
this._date.text = date.toLocaleFormat(dateFormat);
},
destroy: function() {
@ -301,8 +302,7 @@ const NotificationsBox = new Lang.Class({
});
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
this.emit('wake-up-screen');
}
},

View File

@ -411,7 +411,6 @@ const SearchResults = new Lang.Class({
this._searchSettings = new Gio.Settings({ schema_id: SEARCH_PROVIDERS_SCHEMA });
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::enabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));

View File

@ -197,7 +197,7 @@ const Slider = new Lang.Class({
let [dx, dy] = event.get_scroll_delta();
// Even though the slider is horizontal, use dy to match
// the UP/DOWN above.
delta = -dy * SLIDER_SCROLL_STEP;
delta = -dy / 10;
}
this._value = Math.min(Math.max(0, this._value + delta), 1);

View File

@ -876,7 +876,8 @@ const NMWirelessDialog = new Lang.Class({
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this._noNetworksSpinner = new Animation.AnimatedIcon(global.datadir + '/theme/process-working.svg', 24, 24);
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._noNetworksSpinner = new Animation.AnimatedIcon(file, 24, 24);
this._noNetworksBox.add_actor(this._noNetworksSpinner.actor);
this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label',
text: _("No Networks") }));
@ -1866,7 +1867,7 @@ const NMApplet = new Lang.Class({
_connectionRemoved: function(connection) {
let pos = this._connections.indexOf(connection);
if (pos != -1)
this._connections.splice(pos, 1);
this._connections.splice(connection, 1);
let section = connection._section;

View File

@ -285,7 +285,7 @@ const Indicator = new Lang.Class({
let disabled = Main.sessionMode.isLocked ||
(Main.sessionMode.isGreeter &&
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._suspendAction.visible = this._haveSuspend && !disabled;
this._suspendAction.visible = this._haveShutdown && !disabled;
this._updateActionsVisibility();
},

View File

@ -6,7 +6,6 @@ const Clutter = imports.gi.Clutter;
const AccountsService = imports.gi.AccountsService;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const St = imports.gi.St;
@ -118,7 +117,6 @@ const UserWidgetLabel = new Lang.Class({
this._currentLabel = this._realNameLabel;
else
this._currentLabel = this._userNameLabel;
this.label_actor = this._currentLabel;
let childBox = new Clutter.ActorBox();
childBox.x1 = 0;
@ -160,9 +158,6 @@ const UserWidget = new Lang.Class({
this._label = new UserWidgetLabel(user);
this.actor.add_child(this._label);
this._label.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE);
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUser));
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUser));
this._updateUser();

View File

@ -65,8 +65,7 @@ const ShowOverviewAction = new Lang.Class({
},
vfunc_gesture_prepare : function(action, actor) {
return Main.keybindingMode == Shell.KeyBindingMode.NORMAL &&
this.get_n_current_points() == this.get_n_touch_points();
return this.get_n_current_points() == this.get_n_touch_points();
},
_getBoundingRect : function(motion) {
@ -194,10 +193,8 @@ const ViewSelector = new Lang.Class({
// the windows to animate, but now we no longer want to
// show it given that we are now on the apps page or
// search page.
if (this._activePage != this._workspacesPage) {
if (this._activePage != this._workspacesPage)
this._workspacesPage.opacity = 0;
this._workspacesPage.hide();
}
}));
Main.wm.addKeybinding('toggle-application-view',
@ -214,13 +211,9 @@ const ViewSelector = new Lang.Class({
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(Main.overview, Main.overview.toggle));
let side;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
side = St.Side.RIGHT;
else
side = St.Side.LEFT;
let gesture = new EdgeDragAction.EdgeDragAction(side,
Shell.KeyBindingMode.NORMAL);
let gesture;
gesture = new EdgeDragAction.EdgeDragAction(St.Side.LEFT);
gesture.connect('activated', Lang.bind(this, function() {
if (Main.overview.visible)
Main.overview.hide();

View File

@ -478,9 +478,7 @@ const WorkspaceSwitchAction = new Lang.Class({
},
vfunc_gesture_prepare : function(action, actor) {
let allowedModes = Shell.KeyBindingMode.NORMAL | Shell.KeyBindingMode.OVERVIEW;
return this.get_n_current_points() == this.get_n_touch_points() &&
(allowedModes & Main.keybindingMode);
return this.get_n_current_points() == this.get_n_touch_points();
},
vfunc_gesture_end : function(action, actor) {
@ -528,7 +526,7 @@ const AppSwitchAction = new Lang.Class({
},
vfunc_gesture_prepare : function(action, actor) {
if (Main.keybindingMode != Shell.KeyBindingMode.NORMAL) {
if (Main.overview.visible) {
this.cancel();
return false;
}

View File

@ -156,6 +156,7 @@ const WindowClone = new Lang.Class({
this.actor.add_action(clickAction);
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
this.actor.connect('enter-event', Lang.bind(this, this._onEnter));
this._draggable = DND.makeDraggable(this.actor,
{ restoreOnSuccess: true,
@ -352,6 +353,10 @@ const WindowClone = new Lang.Class({
return false;
},
_onEnter: function() {
this.actor.grab_key_focus();
},
_onClicked: function(action, actor) {
this._activate();
},

View File

@ -538,7 +538,6 @@ const WorkspacesDisplay = new Lang.Class({
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].destroy();
this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = [];
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {

View File

@ -7,7 +7,6 @@ be
bg
bn
bn_IN
bs
ca
ca@valencia
cs
@ -31,7 +30,6 @@ hi
hu
ia
id
is
it
ja
kk
@ -50,7 +48,6 @@ nb
ne
nl
nn
oc
or
pa
pl
@ -71,6 +68,7 @@ th
tr
ug
uk
uz@cyrillic
vi
zh_CN
zh_HK

View File

@ -1,4 +1,2 @@
data/org.gnome.shell.evolution.calendar.gschema.xml.in
src/calendar-server/evolution-calendar.desktop.in
# Meh, autofools :-(
sub/src/calendar-server/evolution-calendar.desktop.in

1804
po/bs.po

File diff suppressed because it is too large Load Diff

2487
po/oc.po

File diff suppressed because it is too large Load Diff

652
po/pt.po

File diff suppressed because it is too large Load Diff

166
po/sl.po
View File

@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2014-12-19 16:26+0000\n"
"PO-Revision-Date: 2014-12-25 19:18+0100\n"
"POT-Creation-Date: 2014-09-13 16:14+0000\n"
"PO-Revision-Date: 2014-09-13 21:02+0100\n"
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
"Language: Slovenian\n"
@ -125,11 +125,11 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "App Picker View"
msgstr "Pogled izbirnika programov"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10
msgid "Index of the currently selected view in the application picker."
msgstr "Kazalo trenutno izbranega pogleda v izbirniku programa."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog"
@ -224,8 +224,6 @@ msgstr "Tipkovna bližnjica za prikaz dejavnega obvestila."
msgid ""
"Keybinding that pauses and resumes all running tweens, for debugging purposes"
msgstr ""
"Tipkovna bližnjica, ki omogoča ustavljanje in ponovni zagon vseh zagnanih "
"programov za razhroščevanje."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
msgid "Which keyboard to use"
@ -244,9 +242,6 @@ msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
msgstr ""
"Izbrana možnost določa, da bodo v trenutnem pogledu prikazana le okna, ki so "
"v izbrani delovni površini v preklopniku. V nasprotnem primeru so prikazana "
"vsa okna."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "The application icon mode."
@ -267,8 +262,6 @@ msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
msgstr ""
"Izbrana možnost določa, da bodo v trenutnem pogledu prikazana le okna v "
"preklopniku. V nasprotnem primeru so prikazana vsa okna."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
msgid "Attach modal dialog to the parent window"
@ -300,7 +293,7 @@ msgstr ""
#: ../data/org.gnome.Shell.PortalHelper.desktop.in.h:1
msgid "Captive Portal"
msgstr "Združen pogled"
msgstr ""
#: ../js/extensionPrefs/main.js:123
#, javascript-format
@ -311,54 +304,54 @@ msgstr "Prišlo je do napake med nalaganjem pogovornega okna z možnosti za %s:"
msgid "GNOME Shell Extensions"
msgstr "Razširitve lupine Gnome"
#: ../js/gdm/authPrompt.js:146 ../js/ui/components/networkAgent.js:143
#: ../js/gdm/authPrompt.js:147 ../js/ui/components/networkAgent.js:143
#: ../js/ui/components/polkitAgent.js:166 ../js/ui/endSessionDialog.js:452
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/network.js:915
msgid "Cancel"
msgstr "Prekliči"
#: ../js/gdm/authPrompt.js:168 ../js/gdm/authPrompt.js:216
#: ../js/gdm/authPrompt.js:169 ../js/gdm/authPrompt.js:217
msgid "Next"
msgstr "Naslednji"
#: ../js/gdm/authPrompt.js:212 ../js/ui/shellMountOperation.js:403
#: ../js/gdm/authPrompt.js:213 ../js/ui/shellMountOperation.js:403
#: ../js/ui/unlockDialog.js:59
msgid "Unlock"
msgstr "Odkleni"
#: ../js/gdm/authPrompt.js:214
#: ../js/gdm/authPrompt.js:215
msgctxt "button"
msgid "Sign In"
msgstr "Prijava"
#: ../js/gdm/loginDialog.js:275
#: ../js/gdm/loginDialog.js:269
msgid "Choose Session"
msgstr "Izbor seje"
#: ../js/gdm/loginDialog.js:434
#: ../js/gdm/loginDialog.js:429
msgid "Not listed?"
msgstr "Ali je ni na seznamu?"
#: ../js/gdm/loginDialog.js:619
#: ../js/gdm/loginDialog.js:614
#, javascript-format
msgid "(e.g., user or %s)"
msgstr "(na primer, uporabnika ali %s)"
#: ../js/gdm/loginDialog.js:624 ../js/ui/components/networkAgent.js:269
#: ../js/gdm/loginDialog.js:619 ../js/ui/components/networkAgent.js:269
#: ../js/ui/components/networkAgent.js:287
msgid "Username: "
msgstr "Uporabniško ime: "
#: ../js/gdm/loginDialog.js:955
#: ../js/gdm/loginDialog.js:922
msgid "Login Window"
msgstr "Prijavno okno"
#: ../js/gdm/util.js:341
#: ../js/gdm/util.js:323
msgid "Authentication error"
msgstr "Napaka overitve"
#: ../js/gdm/util.js:473
#: ../js/gdm/util.js:453
msgid "(or swipe finger)"
msgstr "(ali pa povlecite prst)"
@ -391,28 +384,28 @@ msgstr "Pogosto"
msgid "All"
msgstr "Vse"
#: ../js/ui/appDisplay.js:1791
#: ../js/ui/appDisplay.js:1789
msgid "New Window"
msgstr "Novo okno"
#: ../js/ui/appDisplay.js:1817 ../js/ui/dash.js:285
#: ../js/ui/appDisplay.js:1815 ../js/ui/dash.js:285
msgid "Remove from Favorites"
msgstr "Odstrani iz priljubljenih"
#: ../js/ui/appDisplay.js:1823
#: ../js/ui/appDisplay.js:1821
msgid "Add to Favorites"
msgstr "Dodaj med priljubljene"
#: ../js/ui/appDisplay.js:1832
#: ../js/ui/appDisplay.js:1830
msgid "Show Details"
msgstr "Pokaži besedilo"
#: ../js/ui/appFavorites.js:132
#: ../js/ui/appFavorites.js:124
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "Program \"%s\" je dodan med priljubljeno."
#: ../js/ui/appFavorites.js:166
#: ../js/ui/appFavorites.js:158
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "Program \"%s\" je odstranjen iz priljubljenih."
@ -429,14 +422,14 @@ msgstr "Spremeni ozadje ..."
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#. */
#: ../js/ui/calendar.js:70
#: ../js/ui/calendar.js:67
msgctxt "event list time"
msgid "All Day"
msgstr "Celodnevno"
#. Translators: Shown in calendar event list, if 24h format,
#. \u2236 is a ratio character, similar to : */
#: ../js/ui/calendar.js:77
#: ../js/ui/calendar.js:73
msgctxt "event list time"
msgid "%H%M"
msgstr "%H%M"
@ -444,7 +437,7 @@ msgstr "%H%M"
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space */
#: ../js/ui/calendar.js:86
#: ../js/ui/calendar.js:82
msgctxt "event list time"
msgid "%l%M%p"
msgstr "%l%M%p"
@ -454,43 +447,43 @@ msgstr "%l%M%p"
#. * NOTE: These grid abbreviations are always shown together
#. * and in order, e.g. "S M T W T F S".
#. */
#: ../js/ui/calendar.js:100
#: ../js/ui/calendar.js:113
msgctxt "grid sunday"
msgid "S"
msgstr "N"
#. Translators: Calendar grid abbreviation for Monday */
#: ../js/ui/calendar.js:102
#: ../js/ui/calendar.js:115
msgctxt "grid monday"
msgid "M"
msgstr "P"
#. Translators: Calendar grid abbreviation for Tuesday */
#: ../js/ui/calendar.js:104
#: ../js/ui/calendar.js:117
msgctxt "grid tuesday"
msgid "T"
msgstr "T"
#. Translators: Calendar grid abbreviation for Wednesday */
#: ../js/ui/calendar.js:106
#: ../js/ui/calendar.js:119
msgctxt "grid wednesday"
msgid "W"
msgstr "S"
#. Translators: Calendar grid abbreviation for Thursday */
#: ../js/ui/calendar.js:108
#: ../js/ui/calendar.js:121
msgctxt "grid thursday"
msgid "T"
msgstr "Č"
#. Translators: Calendar grid abbreviation for Friday */
#: ../js/ui/calendar.js:110
#: ../js/ui/calendar.js:123
msgctxt "grid friday"
msgid "F"
msgstr "P"
#. Translators: Calendar grid abbreviation for Saturday */
#: ../js/ui/calendar.js:112
#: ../js/ui/calendar.js:125
msgctxt "grid saturday"
msgid "S"
msgstr "S"
@ -501,85 +494,85 @@ msgstr "S"
#. * so they need to be unique (e.g. Tuesday and Thursday cannot
#. * both be 'T').
#. */
#: ../js/ui/calendar.js:125
#: ../js/ui/calendar.js:138
msgctxt "list sunday"
msgid "Su"
msgstr "Ne"
#. Translators: Event list abbreviation for Monday */
#: ../js/ui/calendar.js:127
#: ../js/ui/calendar.js:140
msgctxt "list monday"
msgid "M"
msgstr "P"
#. Translators: Event list abbreviation for Tuesday */
#: ../js/ui/calendar.js:129
#: ../js/ui/calendar.js:142
msgctxt "list tuesday"
msgid "T"
msgstr "T"
#. Translators: Event list abbreviation for Wednesday */
#: ../js/ui/calendar.js:131
#: ../js/ui/calendar.js:144
msgctxt "list wednesday"
msgid "W"
msgstr "S"
#. Translators: Event list abbreviation for Thursday */
#: ../js/ui/calendar.js:133
#: ../js/ui/calendar.js:146
msgctxt "list thursday"
msgid "Th"
msgstr "Če"
#. Translators: Event list abbreviation for Friday */
#: ../js/ui/calendar.js:135
#: ../js/ui/calendar.js:148
msgctxt "list friday"
msgid "F"
msgstr "Pe"
#. Translators: Event list abbreviation for Saturday */
#: ../js/ui/calendar.js:137
#: ../js/ui/calendar.js:150
msgctxt "list saturday"
msgid "S"
msgstr "S"
#: ../js/ui/calendar.js:462
#: ../js/ui/calendar.js:453
msgid "Previous month"
msgstr "Predhodni mesec"
#: ../js/ui/calendar.js:472
#: ../js/ui/calendar.js:463
msgid "Next month"
msgstr "Naslednji mesec"
#. Translators: Text to show if there are no events */
#: ../js/ui/calendar.js:810
#: ../js/ui/calendar.js:781
msgid "Nothing Scheduled"
msgstr "Nič ni razporejeno"
#. Translators: Shown on calendar heading when selected day occurs on current year */
#: ../js/ui/calendar.js:826
#: ../js/ui/calendar.js:799
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %d. %m."
#. Translators: Shown on calendar heading when selected day occurs on different year */
#: ../js/ui/calendar.js:829
#: ../js/ui/calendar.js:802
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %d %B %Y"
#: ../js/ui/calendar.js:839
#: ../js/ui/calendar.js:813
msgid "Today"
msgstr "Danes"
#: ../js/ui/calendar.js:843
#: ../js/ui/calendar.js:817
msgid "Tomorrow"
msgstr "Jutri"
#: ../js/ui/calendar.js:854
#: ../js/ui/calendar.js:828
msgid "This week"
msgstr "Ta teden"
#: ../js/ui/calendar.js:862
#: ../js/ui/calendar.js:836
msgid "Next week"
msgstr "Naslednji teden"
@ -979,7 +972,7 @@ msgstr "Poglej račun"
msgid "Unknown reason"
msgstr "Neznan vzrok"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:155
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:154
msgid "Windows"
msgstr "Okna"
@ -991,22 +984,22 @@ msgstr "Pokaži programe"
msgid "Dash"
msgstr "Pregledna plošča"
#: ../js/ui/dateMenu.js:97
#: ../js/ui/dateMenu.js:96
msgid "Open Calendar"
msgstr "Odpri koledar"
#: ../js/ui/dateMenu.js:101
#: ../js/ui/dateMenu.js:100
msgid "Open Clocks"
msgstr "Odpri ure"
#: ../js/ui/dateMenu.js:108
#: ../js/ui/dateMenu.js:107
msgid "Date & Time Settings"
msgstr "Nastavitve časa in datuma"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. */
#: ../js/ui/dateMenu.js:132
#: ../js/ui/dateMenu.js:204
msgid "%A %B %e, %Y"
msgstr "%a, %e. %b., %R"
@ -1162,7 +1155,7 @@ msgstr "Namesti"
msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "Prejmi in namesti “%s” preko povezave na extensions.gnome.org?"
#: ../js/ui/keyboard.js:700 ../js/ui/status/keyboard.js:535
#: ../js/ui/keyboard.js:692 ../js/ui/status/keyboard.js:523
msgid "Keyboard"
msgstr "Tipkovnica"
@ -1218,49 +1211,39 @@ msgstr "Poglej vir"
msgid "Web Page"
msgstr "Spletna stran"
#: ../js/ui/messageTray.js:1332
#: ../js/ui/messageTray.js:1326
msgid "Open"
msgstr "Odpri"
#: ../js/ui/messageTray.js:1339
#: ../js/ui/messageTray.js:1333
msgid "Remove"
msgstr "Odstrani"
#: ../js/ui/messageTray.js:1636
#: ../js/ui/messageTray.js:1630
msgid "Notifications"
msgstr "Obvestila"
#: ../js/ui/messageTray.js:1643
#: ../js/ui/messageTray.js:1637
msgid "Clear Messages"
msgstr "Počisti sporočila"
#: ../js/ui/messageTray.js:1662
#: ../js/ui/messageTray.js:1656
msgid "Notification Settings"
msgstr "Nastavitve obvestil"
#: ../js/ui/messageTray.js:1715
#: ../js/ui/messageTray.js:1709
msgid "Tray Menu"
msgstr "Meni sistemske vrstice"
#: ../js/ui/messageTray.js:1939
#: ../js/ui/messageTray.js:1926
msgid "No Messages"
msgstr "Ni sporočil"
#: ../js/ui/messageTray.js:1986
#: ../js/ui/messageTray.js:1968
msgid "Message Tray"
msgstr "Sporočilna vrstica"
#: ../js/ui/messageTray.js:2443 ../js/ui/overviewControls.js:483
#: ../js/ui/screenShield.js:151
#, javascript-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d novih sporočil"
msgstr[1] "%d novo sporočilo"
msgstr[2] "%d novi sporočili"
msgstr[3] "%d nova sporočila"
#: ../js/ui/messageTray.js:3013
#: ../js/ui/messageTray.js:2971
msgid "System Information"
msgstr "Podrobnosti sistema"
@ -1269,6 +1252,15 @@ msgctxt "program"
msgid "Unknown"
msgstr "Neznano"
#: ../js/ui/overviewControls.js:482 ../js/ui/screenShield.js:151
#, javascript-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d novih sporočil"
msgstr[1] "%d novo sporočilo"
msgstr[2] "%d novi sporočili"
msgstr[3] "%d nova sporočila"
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Razveljavi"
@ -1338,19 +1330,19 @@ msgstr "Zakleni"
msgid "GNOME needs to lock the screen"
msgstr "Zakleniti je treba zaslon"
#: ../js/ui/screenShield.js:833 ../js/ui/screenShield.js:1309
#: ../js/ui/screenShield.js:833 ../js/ui/screenShield.js:1304
msgid "Unable to lock"
msgstr "Zaklep ni mogoč"
#: ../js/ui/screenShield.js:834 ../js/ui/screenShield.js:1310
#: ../js/ui/screenShield.js:834 ../js/ui/screenShield.js:1305
msgid "Lock was blocked by an application"
msgstr "Zaklep je preprečil program"
#: ../js/ui/search.js:611
#: ../js/ui/search.js:594
msgid "Searching…"
msgstr "Iskanje ..."
#: ../js/ui/search.js:613
#: ../js/ui/search.js:596
msgid "No results."
msgstr "Ni najdenih zadetkov."
@ -1454,7 +1446,7 @@ msgstr "Ni vzpostavljene povezave"
msgid "Brightness"
msgstr "Svetlost"
#: ../js/ui/status/keyboard.js:559
#: ../js/ui/status/keyboard.js:547
msgid "Show Keyboard Layout"
msgstr "Pokaži razporeditev tipkovnice"
@ -1709,11 +1701,11 @@ msgstr "Prijava kot drug uporabnik"
msgid "Unlock Window"
msgstr "Odkleni okno"
#: ../js/ui/viewSelector.js:159
#: ../js/ui/viewSelector.js:158
msgid "Applications"
msgstr "Programi"
#: ../js/ui/viewSelector.js:163
#: ../js/ui/viewSelector.js:162
msgid "Search"
msgstr "Poišči"

File diff suppressed because it is too large Load Diff

View File

@ -176,54 +176,18 @@ static void
calendar_sources_init (CalendarSources *sources)
{
GError *error = NULL;
GDBusConnection *session_bus;
GVariant *result;
sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources);
/* WORKAROUND: the hardcoded timeout for e_source_registry_new_sync()
(and other library calls that eventually call g_dbus_proxy_new[_sync]())
is 25 seconds. This has been shown to be too small for
evolution-source-registry in certain cases (slow disk, concurrent IO,
many configured sources), so we first ensure that the service
starts with a manual call and a higher timeout.
HACK: every time the DBus API is bumped in e-d-s we need
to update this!
*/
session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
if (session_bus == NULL)
{
g_error ("Failed to connect to the session bus: %s", error->message);
}
result = g_dbus_connection_call_sync (session_bus, "org.freedesktop.DBus",
"/", "org.freedesktop.DBus",
"StartServiceByName",
g_variant_new ("(su)",
"org.gnome.evolution.dataserver.Sources3",
0),
NULL,
G_DBUS_CALL_FLAGS_NONE,
60 * 1000,
NULL, &error);
if (result != NULL)
{
g_variant_unref (result);
sources->priv->registry = e_source_registry_new_sync (NULL, &error);
}
/* XXX Not sure what to do if this fails.
* Should this class implement GInitable or pass the
* registry in as a G_PARAM_CONSTRUCT_ONLY property? */
sources->priv->registry = e_source_registry_new_sync (NULL, &error);
if (error != NULL)
{
/* Any error is fatal, but we don't want to crash gnome-shell-calendar-server
because of e-d-s problems. So just exit here.
*/
g_warning ("Failed to start evolution-source-registry: %s", error->message);
exit(EXIT_FAILURE);
g_error ("%s: %s", G_STRFUNC, error->message);
}
g_object_unref (session_bus);
sources->priv->source_added_id = g_signal_connect (sources->priv->registry,
"source-added",
G_CALLBACK (calendar_sources_registry_source_changed_cb),

View File

@ -1132,14 +1132,6 @@ shell_global_end_modal (ShellGlobal *global,
sync_input_region (global);
}
void
shell_global_freeze_keyboard (ShellGlobal *global,
guint32 timestamp)
{
if (global->stage_xwindow != None)
meta_display_freeze_keyboard (global->meta_display, global->stage_xwindow, timestamp);
}
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
*
* Authors: Padraig O'Briain, Matthias Clasen, Lennart Poettering

View File

@ -45,8 +45,6 @@ gboolean shell_global_begin_modal (ShellGlobal *global,
MetaModalOptions options);
void shell_global_end_modal (ShellGlobal *global,
guint32 timestamp);
void shell_global_freeze_keyboard (ShellGlobal *global,
guint32 timestamp);
void shell_global_set_stage_input_region (ShellGlobal *global,
GSList *rectangles);

View File

@ -5,9 +5,6 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <GL/gl.h>
#include <cogl/cogl.h>
#include "shell-util.h"
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
@ -15,6 +12,7 @@
#include <gdk/gdkx.h>
#include <X11/extensions/XTest.h>
#include <locale.h>
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
#include <langinfo.h>
#endif
@ -211,6 +209,32 @@ shell_util_get_week_start ()
return week_start;
}
/**
* shell_util_translate_time_string:
* @str: String to translate
*
* Translate @str according to the locale defined by LC_TIME; unlike
* dcgettext(), the translations is still taken from the LC_MESSAGES
* catalogue and not the LC_TIME one.
*
* Returns: the translated string
*/
const char *
shell_util_translate_time_string (const char *str)
{
const char *locale = g_getenv ("LC_TIME");
const char *res;
if (locale)
setlocale (LC_MESSAGES, locale);
res = gettext (str);
setlocale (LC_MESSAGES, "");
return res;
}
/**
* shell_write_string_to_stream:
* @stream: a #GOutputStream
@ -333,33 +357,3 @@ shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
clutter_actor_hide (CLUTTER_ACTOR (texture));
}
}
typedef const gchar *(*ShellGLGetString) (GLenum);
static const gchar *
get_gl_vendor (void)
{
static const gchar *vendor = NULL;
if (!vendor)
{
ShellGLGetString gl_get_string;
gl_get_string = (ShellGLGetString) cogl_get_proc_address ("glGetString");
if (gl_get_string)
vendor = gl_get_string (GL_VENDOR);
}
return vendor;
}
gboolean
shell_util_need_background_refresh (void)
{
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
return FALSE;
if (g_strcmp0 (get_gl_vendor (), "NVIDIA Corporation") == 0)
return TRUE;
return FALSE;
}

View File

@ -21,6 +21,7 @@ int shell_util_get_week_start (void);
char *shell_util_format_date (const char *format,
gint64 time_ms);
const char *shell_util_translate_time_string (const char *str);
gboolean shell_write_string_to_stream (GOutputStream *stream,
const char *str,
@ -44,8 +45,6 @@ GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar *data,
void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
ClutterTexture *texture);
gboolean shell_util_need_background_refresh (void);
G_END_DECLS
#endif /* __SHELL_UTIL_H__ */

View File

@ -27,7 +27,7 @@
struct _StBorderImage {
GObject parent;
char *filename;
GFile *file;
int border_top;
int border_right;
int border_bottom;
@ -48,7 +48,7 @@ st_border_image_finalize (GObject *object)
{
StBorderImage *image = ST_BORDER_IMAGE (object);
g_free (image->filename);
g_object_unref (image->file);
G_OBJECT_CLASS (st_border_image_parent_class)->finalize (object);
}
@ -67,18 +67,18 @@ st_border_image_init (StBorderImage *image)
}
StBorderImage *
st_border_image_new (const char *filename,
int border_top,
int border_right,
int border_bottom,
int border_left,
int scale_factor)
st_border_image_new (GFile *file,
int border_top,
int border_right,
int border_bottom,
int border_left,
int scale_factor)
{
StBorderImage *image;
image = g_object_new (ST_TYPE_BORDER_IMAGE, NULL);
image->filename = g_strdup (filename);
image->file = g_object_ref (file);
image->border_top = border_top;
image->border_right = border_right;
image->border_bottom = border_bottom;
@ -88,12 +88,18 @@ st_border_image_new (const char *filename,
return image;
}
const char *
st_border_image_get_filename (StBorderImage *image)
/**
* st_border_image_get_file:
* @image: a #StBorder_Image
*
* Returns: (transfer none): the #GFile for the #StBorder_Image
*/
GFile *
st_border_image_get_file (StBorderImage *image)
{
g_return_val_if_fail (ST_IS_BORDER_IMAGE (image), NULL);
return image->filename;
return image->file;
}
void
@ -135,5 +141,5 @@ st_border_image_equal (StBorderImage *image,
image->border_right == other->border_right &&
image->border_bottom == other->border_bottom &&
image->border_left == other->border_left &&
strcmp (image->filename, other->filename) == 0);
g_file_equal (image->file, other->file));
}

View File

@ -22,6 +22,7 @@
#define __ST_BORDER_IMAGE_H__
#include <glib-object.h>
#include <gio/gio.h>
G_BEGIN_DECLS
@ -39,14 +40,14 @@ typedef struct _StBorderImageClass StBorderImageClass;
GType st_border_image_get_type (void) G_GNUC_CONST;
StBorderImage *st_border_image_new (const char *filename,
StBorderImage *st_border_image_new (GFile *file,
int border_top,
int border_right,
int border_bottom,
int border_left,
int scale_factor);
const char *st_border_image_get_filename (StBorderImage *image);
GFile *st_border_image_get_file (StBorderImage *image);
void st_border_image_get_borders (StBorderImage *image,
int *border_top,
int *border_right,

View File

@ -373,6 +373,7 @@ st_scroll_view_get_preferred_width (ClutterActor *actor,
break;
case GTK_POLICY_ALWAYS:
case GTK_POLICY_AUTOMATIC:
case GTK_POLICY_EXTERNAL:
/* Should theoretically use the min width of the hscrollbar,
* but that's not cleanly defined at the moment */
min_width = 0;
@ -382,6 +383,7 @@ st_scroll_view_get_preferred_width (ClutterActor *actor,
switch (priv->vscrollbar_policy)
{
case GTK_POLICY_NEVER:
case GTK_POLICY_EXTERNAL:
account_for_vscrollbar = FALSE;
break;
case GTK_POLICY_ALWAYS:
@ -443,6 +445,7 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
switch (priv->vscrollbar_policy)
{
case GTK_POLICY_NEVER:
case GTK_POLICY_EXTERNAL:
break;
case GTK_POLICY_ALWAYS:
case GTK_POLICY_AUTOMATIC:
@ -454,6 +457,7 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
switch (priv->hscrollbar_policy)
{
case GTK_POLICY_NEVER:
case GTK_POLICY_EXTERNAL:
account_for_hscrollbar = FALSE;
break;
case GTK_POLICY_ALWAYS:
@ -480,6 +484,7 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
break;
case GTK_POLICY_ALWAYS:
case GTK_POLICY_AUTOMATIC:
case GTK_POLICY_EXTERNAL:
/* Should theoretically use the min height of the vscrollbar,
* but that's not cleanly defined at the moment */
min_height = 0;
@ -567,7 +572,7 @@ st_scroll_view_allocate (ClutterActor *actor,
}
else
{
hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
hscrollbar_visible = priv->hscrollbar_policy == GTK_POLICY_ALWAYS;
/* try without a vertical scrollbar */
clutter_actor_get_preferred_height (priv->child, avail_width, &child_min_height, NULL);
@ -576,18 +581,20 @@ st_scroll_view_allocate (ClutterActor *actor,
}
else
{
vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
vscrollbar_visible = priv->vscrollbar_policy == GTK_POLICY_ALWAYS;
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
hscrollbar_visible = child_min_width > avail_height - (vscrollbar_visible ? 0 : sb_width);
else
hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
hscrollbar_visible = priv->hscrollbar_policy == GTK_POLICY_ALWAYS;
}
}
else
{
hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER &&
priv->hscrollbar_policy != GTK_POLICY_EXTERNAL;
vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER &&
priv->vscrollbar_policy != GTK_POLICY_EXTERNAL;
}
/* Whether or not we show the scrollbars, if the scrollbars are visible
@ -629,15 +636,19 @@ st_scroll_view_allocate (ClutterActor *actor,
clutter_actor_allocate (priv->hscroll, &child_box, flags);
/* In case the scrollbar policy is NEVER or scrollbars should be
* overlayed, we don't trim the content box allocation by the
* scrollbar size.
/* In case the scrollbar policy is NEVER or EXTERNAL or scrollbars
* should be overlayed, we don't trim the content box allocation by
* the scrollbar size.
* Fold this into the scrollbar sizes to simplify the rest of the
* computations.
*/
if (priv->hscrollbar_policy == GTK_POLICY_NEVER || priv->overlay_scrollbars)
if (priv->hscrollbar_policy == GTK_POLICY_NEVER ||
priv->hscrollbar_policy == GTK_POLICY_EXTERNAL ||
priv->overlay_scrollbars)
sb_height = 0;
if (priv->vscrollbar_policy == GTK_POLICY_NEVER || priv->overlay_scrollbars)
if (priv->vscrollbar_policy == GTK_POLICY_NEVER ||
priv->vscrollbar_policy == GTK_POLICY_EXTERNAL ||
priv->overlay_scrollbars)
sb_width = 0;
/* Child */

View File

@ -28,8 +28,8 @@
#include <glib.h>
#define CACHE_PREFIX_ICON "icon:"
#define CACHE_PREFIX_URI "uri:"
#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:"
#define CACHE_PREFIX_FILE "file:"
#define CACHE_PREFIX_FILE_FOR_CAIRO "file-for-cairo:"
struct _StTextureCachePrivate
{
@ -101,7 +101,7 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
G_SIGNAL_RUN_LAST,
0, /* no default handler slot */
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_STRING);
G_TYPE_NONE, 1, G_TYPE_FILE);
}
/* Evicts all cached textures for named icons */
@ -147,7 +147,7 @@ st_texture_cache_init (StTextureCache *self)
g_free, cogl_object_unref);
self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
self->priv->file_monitors = g_hash_table_new_full (g_str_hash, g_str_equal,
self->priv->file_monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
g_object_unref, g_object_unref);
}
@ -268,7 +268,7 @@ typedef struct {
GtkIconInfo *icon_info;
StIconColors *colors;
char *uri;
GFile *file;
} AsyncTextureLoadData;
static void
@ -282,8 +282,8 @@ texture_load_data_free (gpointer p)
if (data->colors)
st_icon_colors_unref (data->colors);
}
else if (data->uri)
g_free (data->uri);
else if (data->file)
g_object_unref (data->file);
if (data->key)
g_free (data->key);
@ -405,83 +405,17 @@ out:
return rotated_pixbuf;
}
static GdkPixbuf*
decode_image (const char *val)
{
int i;
GError *error = NULL;
GdkPixbuf *res = NULL;
struct {
const char *prefix;
const char *mime_type;
} formats[] = {
{ "data:image/x-icon;base64,", "image/x-icon" },
{ "data:image/png;base64,", "image/png" }
};
g_return_val_if_fail (val, NULL);
for (i = 0; i < G_N_ELEMENTS (formats); i++)
{
if (g_str_has_prefix (val, formats[i].prefix))
{
gsize len;
guchar *data = NULL;
char *unescaped;
unescaped = g_uri_unescape_string (val + strlen (formats[i].prefix), NULL);
if (unescaped)
{
data = g_base64_decode (unescaped, &len);
g_free (unescaped);
}
if (data)
{
GdkPixbufLoader *loader;
loader = gdk_pixbuf_loader_new_with_mime_type (formats[i].mime_type, &error);
if (loader &&
gdk_pixbuf_loader_write (loader, data, len, &error) &&
gdk_pixbuf_loader_close (loader, &error))
{
res = gdk_pixbuf_loader_get_pixbuf (loader);
g_object_ref (res);
}
g_object_unref (loader);
g_free (data);
}
}
}
if (!res)
{
if (error)
{
g_warning ("%s\n", error->message);
g_error_free (error);
}
else
g_warning ("incorrect data uri");
}
return res;
}
static GdkPixbuf *
impl_load_pixbuf_file (const char *uri,
impl_load_pixbuf_file (GFile *file,
int available_width,
int available_height,
int scale,
GError **error)
{
GdkPixbuf *pixbuf = NULL;
GFile *file;
char *contents = NULL;
gsize size;
if (g_str_has_prefix (uri, "data:"))
return decode_image (uri);
file = g_file_new_for_uri (uri);
if (g_file_load_contents (file, NULL, &contents, &size, NULL, error))
{
pixbuf = impl_load_pixbuf_data ((const guchar *) contents, size,
@ -490,7 +424,6 @@ impl_load_pixbuf_file (const char *uri,
error);
}
g_object_unref (file);
g_free (contents);
return pixbuf;
@ -507,9 +440,9 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
g_assert (data != NULL);
g_assert (data->uri != NULL);
g_assert (data->file != NULL);
pixbuf = impl_load_pixbuf_file (data->uri, data->width, data->height, data->scale, &error);
pixbuf = impl_load_pixbuf_file (data->file, data->width, data->height, data->scale, &error);
if (error != NULL)
{
@ -647,7 +580,7 @@ static void
load_texture_async (StTextureCache *cache,
AsyncTextureLoadData *data)
{
if (data->uri)
if (data->file)
{
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (cache), on_pixbuf_loaded, data, load_texture_async);
@ -1014,46 +947,43 @@ file_changed_cb (GFileMonitor *monitor,
gpointer user_data)
{
StTextureCache *cache = user_data;
char *uri, *key;
char *key;
guint file_hash;
if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
return;
uri = g_file_get_uri (file);
file_hash = g_file_hash (file);
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL);
key = g_strdup_printf (CACHE_PREFIX_FILE "%u", file_hash);
g_hash_table_remove (cache->priv->keyed_cache, key);
g_free (key);
key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL);
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", file_hash);
g_hash_table_remove (cache->priv->keyed_cache, key);
g_free (key);
g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, uri);
g_free (uri);
g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, file);
}
static void
ensure_monitor_for_uri (StTextureCache *cache,
const gchar *uri)
ensure_monitor_for_file (StTextureCache *cache,
GFile *file)
{
StTextureCachePrivate *priv = cache->priv;
GFile *file = g_file_new_for_uri (uri);
if (g_hash_table_lookup (priv->file_monitors, uri) == NULL)
if (g_hash_table_lookup (priv->file_monitors, file) == NULL)
{
GFileMonitor *monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE,
NULL, NULL);
g_signal_connect (monitor, "changed",
G_CALLBACK (file_changed_cb), cache);
g_hash_table_insert (priv->file_monitors, g_strdup (uri), monitor);
g_hash_table_insert (priv->file_monitors, g_object_ref (file), monitor);
}
g_object_unref (file);
}
typedef struct {
gchar *path;
GFile *gfile;
gint grid_width, grid_height;
gint scale_factor;
ClutterActor *actor;
@ -1065,7 +995,7 @@ static void
on_data_destroy (gpointer data)
{
AsyncImageData *d = (AsyncImageData *)data;
g_free (d->path);
g_object_unref (d->gfile);
g_object_unref (d->actor);
g_free (d);
}
@ -1138,7 +1068,7 @@ load_sliced_image (GSimpleAsyncResult *result,
loader = gdk_pixbuf_loader_new ();
g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data);
if (!g_file_get_contents (data->path, &buffer, &length, NULL))
if (!g_file_load_contents (data->gfile, NULL, &buffer, &length, NULL, NULL))
goto out;
if (!gdk_pixbuf_loader_write (loader, (const guchar *) buffer, length, NULL))
@ -1173,7 +1103,7 @@ load_sliced_image (GSimpleAsyncResult *result,
/**
* st_texture_cache_load_sliced_image:
* @cache: A #StTextureCache
* @path: Path to a filename
* @file: A #GFile
* @grid_width: Width in pixels
* @grid_height: Height in pixels
* @scale: Scale factor of the display
@ -1189,7 +1119,7 @@ load_sliced_image (GSimpleAsyncResult *result,
*/
ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
GFile *file,
gint grid_width,
gint grid_height,
gint scale,
@ -1204,7 +1134,7 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
data->grid_width = grid_width;
data->grid_height = grid_height;
data->scale_factor = scale;
data->path = g_strdup (path);
data->gfile = g_object_ref (file);
data->actor = actor;
data->load_callback = load_callback;
data->load_callback_data = user_data;
@ -1221,9 +1151,9 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
}
/**
* st_texture_cache_load_uri_async:
* st_texture_cache_load_file_async:
* @cache: The texture cache instance
* @uri: uri of the image file from which to create a pixbuf
* @file: a #GFile of the image file from which to create a pixbuf
* @available_width: available width for the image, can be -1 if not limited
* @available_height: available height for the image, can be -1 if not limited
* @scale: scale factor of the display
@ -1235,18 +1165,18 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
* Return value: (transfer none): A new #ClutterActor with no image loaded initially.
*/
ClutterActor *
st_texture_cache_load_uri_async (StTextureCache *cache,
const gchar *uri,
int available_width,
int available_height,
int scale)
st_texture_cache_load_file_async (StTextureCache *cache,
GFile *file,
int available_width,
int available_height,
int scale)
{
ClutterActor *texture;
AsyncTextureLoadData *request;
StTextureCachePolicy policy;
gchar *key;
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL);
key = g_strdup_printf (CACHE_PREFIX_FILE "%u", g_file_hash (file));
policy = ST_TEXTURE_CACHE_POLICY_NONE; /* XXX */
@ -1264,7 +1194,7 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
request->cache = cache;
/* Transfer ownership of key */
request->key = key;
request->uri = g_strdup (uri);
request->file = g_object_ref (file);
request->policy = policy;
request->width = available_width;
request->height = available_height;
@ -1273,31 +1203,31 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
load_texture_async (cache, request);
}
ensure_monitor_for_uri (cache, uri);
ensure_monitor_for_file (cache, file);
return CLUTTER_ACTOR (texture);
}
static CoglTexture *
st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
StTextureCachePolicy policy,
const gchar *uri,
int available_width,
int available_height,
int scale,
GError **error)
st_texture_cache_load_file_sync_to_cogl_texture (StTextureCache *cache,
StTextureCachePolicy policy,
GFile *file,
int available_width,
int available_height,
int scale,
GError **error)
{
CoglTexture *texdata;
GdkPixbuf *pixbuf;
char *key;
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL);
key = g_strdup_printf (CACHE_PREFIX_FILE "%u", g_file_hash (file));
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
if (texdata == NULL)
{
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, scale, error);
pixbuf = impl_load_pixbuf_file (file, available_width, available_height, scale, error);
if (!pixbuf)
goto out;
@ -1313,7 +1243,7 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
else
cogl_object_ref (texdata);
ensure_monitor_for_uri (cache, uri);
ensure_monitor_for_file (cache, file);
out:
g_free (key);
@ -1321,25 +1251,25 @@ out:
}
static cairo_surface_t *
st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache *cache,
StTextureCachePolicy policy,
const gchar *uri,
int available_width,
int available_height,
int scale,
GError **error)
st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache,
StTextureCachePolicy policy,
GFile *file,
int available_width,
int available_height,
int scale,
GError **error)
{
cairo_surface_t *surface;
GdkPixbuf *pixbuf;
char *key;
key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL);
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file));
surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
if (surface == NULL)
{
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, scale, error);
pixbuf = impl_load_pixbuf_file (file, available_width, available_height, scale, error);
if (!pixbuf)
goto out;
@ -1355,7 +1285,7 @@ st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache *cache,
else
cairo_surface_reference (surface);
ensure_monitor_for_uri (cache, uri);
ensure_monitor_for_file (cache, file);
out:
g_free (key);
@ -1365,7 +1295,7 @@ out:
/**
* st_texture_cache_load_file_to_cogl_texture: (skip)
* @cache: A #StTextureCache
* @file_path: Path to a file in supported image format
* @file: A #GFile in supported image format
* @scale: Scale factor of the display
*
* This function synchronously loads the given file path
@ -1376,35 +1306,30 @@ out:
*/
CoglTexture *
st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path,
GFile *file,
gint scale)
{
CoglTexture *texture;
GFile *file;
char *uri;
GError *error = NULL;
file = g_file_new_for_path (file_path);
uri = g_file_get_uri (file);
texture = st_texture_cache_load_uri_sync_to_cogl_texture (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
uri, -1, -1, scale, &error);
g_object_unref (file);
g_free (uri);
texture = st_texture_cache_load_file_sync_to_cogl_texture (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
file, -1, -1, scale, &error);
if (texture == NULL)
{
g_warning ("Failed to load %s: %s", file_path, error->message);
char *uri = g_file_get_uri (file);
g_warning ("Failed to load %s: %s", uri, error->message);
g_clear_error (&error);
return NULL;
g_free (uri);
}
return texture;
}
/**
* st_texture_cache_load_file_to_cairo_surface:
* @cache: A #StTextureCache
* @file_path: Path to a file in supported image format
* @file: A #GFile in supported image format
* @scale: Scale factor of the display
*
* This function synchronously loads the given file path
@ -1415,28 +1340,23 @@ st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
*/
cairo_surface_t *
st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
const gchar *file_path,
GFile *file,
gint scale)
{
cairo_surface_t *surface;
GFile *file;
char *uri;
GError *error = NULL;
file = g_file_new_for_path (file_path);
uri = g_file_get_uri (file);
surface = st_texture_cache_load_uri_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
uri, -1, -1, scale, &error);
g_object_unref (file);
g_free (uri);
surface = st_texture_cache_load_file_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
file, -1, -1, scale, &error);
if (surface == NULL)
{
g_warning ("Failed to load %s: %s", file_path, error->message);
char *uri = g_file_get_uri (file);
g_warning ("Failed to load %s: %s", uri, error->message);
g_clear_error (&error);
return NULL;
g_free (uri);
}
return surface;
}

View File

@ -70,7 +70,7 @@ StTextureCache* st_texture_cache_get_default (void);
ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
GFile *file,
gint grid_width,
gint grid_height,
gint scale,
@ -87,18 +87,18 @@ ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache,
gint size,
gint scale);
ClutterActor *st_texture_cache_load_uri_async (StTextureCache *cache,
const gchar *uri,
int available_width,
int available_height,
int scale);
ClutterActor *st_texture_cache_load_file_async (StTextureCache *cache,
GFile *file,
int available_width,
int available_height,
int scale);
CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path,
GFile *file,
gint scale);
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
const gchar *file_path,
GFile *file,
gint scale);
/**

View File

@ -600,7 +600,7 @@ create_cairo_pattern_of_background_image (StThemeNode *node,
cairo_pattern_t *pattern;
cairo_content_t content;
cairo_matrix_t matrix;
const char *file;
GFile *file;
StTextureCache *texture_cache;
@ -1037,7 +1037,7 @@ st_theme_node_prerender_background (StThemeNode *node,
}
else
{
const char *background_image;
GFile *background_image;
background_image = st_theme_node_get_background_image (node);
@ -1303,14 +1303,14 @@ st_theme_node_load_border_image (StThemeNode *node)
if (border_image == NULL)
goto out;
const char *filename;
filename = st_border_image_get_filename (border_image);
GFile *file;
file = st_border_image_get_file (border_image);
int scale_factor;
g_object_get (node->context, "scale-factor", &scale_factor, NULL);
node->border_slices_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (),
filename, scale_factor);
file, scale_factor);
if (node->border_slices_texture == COGL_INVALID_HANDLE)
goto out;
@ -1348,7 +1348,7 @@ st_theme_node_load_background_image (StThemeNode *node)
{
if (node->background_texture == COGL_INVALID_HANDLE)
{
const char *background_image;
GFile *background_image;
StShadow *background_image_shadow_spec;
background_image = st_theme_node_get_background_image (node);

View File

@ -68,7 +68,7 @@ struct _StThemeNode {
int transition_duration;
char *background_image;
GFile *background_image;
StBorderImage *border_image;
StShadow *box_shadow;
StShadow *background_image_shadow;

View File

@ -158,7 +158,10 @@ st_theme_node_finalize (GObject *object)
}
if (node->background_image)
g_free (node->background_image);
{
g_object_unref (node->background_image);
node->background_image = NULL;
}
if (node->background_texture != COGL_INVALID_HANDLE)
cogl_handle_unref (node->background_texture);
@ -905,7 +908,7 @@ st_theme_node_get_double (StThemeNode *node,
* parent's parent, and so forth. Note that if the property has a
* value of 'inherit' it will be inherited even if %FALSE is passed
* in for @inherit; this only affects the default behavior for inheritance.
* @value: (out): location to store the newly allocated value that was
* @file: (out) (transfer full): location to store the newly allocated value that was
* determined. If the property is not found, the value in this location
* will not be changed.
*
@ -920,7 +923,7 @@ gboolean
st_theme_node_lookup_url (StThemeNode *node,
const char *property_name,
gboolean inherit,
char **value)
GFile **file)
{
gboolean result = FALSE;
int i;
@ -935,7 +938,6 @@ st_theme_node_lookup_url (StThemeNode *node,
{
CRTerm *term = decl->value;
CRStyleSheet *base_stylesheet;
GFile *file;
if (term->type != TERM_URI && term->type != TERM_STRING)
continue;
@ -945,23 +947,21 @@ st_theme_node_lookup_url (StThemeNode *node,
else
base_stylesheet = NULL;
file = _st_theme_resolve_url (node->theme,
base_stylesheet,
decl->value->content.str->stryng->str);
*value = g_file_get_path (file);
g_object_unref (file);
*file = _st_theme_resolve_url (node->theme,
base_stylesheet,
decl->value->content.str->stryng->str);
result = TRUE;
break;
}
}
if (!result && inherit && node->parent_node)
result = st_theme_node_lookup_url (node->parent_node, property_name, inherit, value);
result = st_theme_node_lookup_url (node->parent_node, property_name, inherit, file);
return result;
}
/*
/**
* st_theme_node_get_url:
* @node: a #StThemeNode
* @property_name: The name of the string property
@ -972,18 +972,18 @@ st_theme_node_lookup_url (StThemeNode *node,
* and lets you handle the case where the theme does not specify the
* indicated value.
*
* Return value: the newly allocated value if found.
* Returns: (transfer full): the newly allocated value if found.
* If @property_name is not found, a warning will be logged and %NULL
* will be returned.
*/
char *
GFile *
st_theme_node_get_url (StThemeNode *node,
const char *property_name)
{
char *value;
GFile *file;
if (st_theme_node_lookup_url (node, property_name, FALSE, &value))
return value;
if (st_theme_node_lookup_url (node, property_name, FALSE, &file))
return file;
else
{
g_warning ("Did not find string property '%s'", property_name);
@ -1926,8 +1926,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
CRTerm *term;
/* background: property sets all terms to specified or default values */
node->background_color = TRANSPARENT_COLOR;
g_free (node->background_image);
node->background_image = NULL;
g_clear_object (&node->background_image);
node->background_position_set = FALSE;
node->background_size = ST_BACKGROUND_SIZE_AUTO;
@ -1943,7 +1942,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
if (node->parent_node)
{
st_theme_node_get_background_color (node->parent_node, &node->background_color);
node->background_image = g_strdup (st_theme_node_get_background_image (node->parent_node));
node->background_image = g_object_ref (st_theme_node_get_background_image (node->parent_node));
}
}
else if (term_is_none (term))
@ -1964,8 +1963,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
base_stylesheet,
term->content.str->stryng->str);
node->background_image = g_file_get_path (file);
g_object_unref (file);
node->background_image = file;
}
}
}
@ -2062,30 +2060,25 @@ _st_theme_node_ensure_background (StThemeNode *node)
if (decl->value->type == TERM_URI)
{
CRStyleSheet *base_stylesheet;
GFile *file;
if (decl->parent_statement != NULL)
base_stylesheet = decl->parent_statement->parent_sheet;
else
base_stylesheet = NULL;
g_free (node->background_image);
file = _st_theme_resolve_url (node->theme,
base_stylesheet,
decl->value->content.str->stryng->str);
node->background_image = g_file_get_path (file);
g_object_unref (file);
g_clear_object (&node->background_image);
node->background_image = _st_theme_resolve_url (node->theme,
base_stylesheet,
decl->value->content.str->stryng->str);
}
else if (term_is_inherit (decl->value))
{
g_free (node->background_image);
node->background_image = g_strdup (st_theme_node_get_background_image (node->parent_node));
g_clear_object (&node->background_image);
node->background_image = g_object_ref (st_theme_node_get_background_image (node->parent_node));
}
else if (term_is_none (decl->value))
{
g_free (node->background_image);
node->background_image = NULL;
g_clear_object (&node->background_image);
}
}
else if (strcmp (property_name, "-gradient-direction") == 0)
@ -2142,7 +2135,13 @@ st_theme_node_get_background_color (StThemeNode *node,
*color = node->background_color;
}
const char *
/**
* st_theme_node_get_background_image:
* @node: a #StThemeNode
*
* Returns: (transfer none): @node's background image.
*/
GFile *
st_theme_node_get_background_image (StThemeNode *node)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
@ -2894,7 +2893,6 @@ st_theme_node_get_border_image (StThemeNode *node)
int border_left;
GFile *file;
char *filename;
/* Support border-image: none; to suppress a previously specified border image */
if (term_is_none (term))
@ -2973,17 +2971,15 @@ st_theme_node_get_border_image (StThemeNode *node)
base_stylesheet = NULL;
file = _st_theme_resolve_url (node->theme, base_stylesheet, url);
filename = g_file_get_path (file);
g_object_unref (file);
if (filename == NULL)
if (file == NULL)
goto next_property;
node->border_image = st_border_image_new (filename,
node->border_image = st_border_image_new (file,
border_top, border_right, border_bottom, border_left,
scale_factor);
g_free (filename);
g_object_unref (file);
return node->border_image;
}
@ -3853,7 +3849,9 @@ st_theme_node_paint_equal (StThemeNode *node,
!clutter_color_equal (&node->background_gradient_end, &other->background_gradient_end))
return FALSE;
if (g_strcmp0 (node->background_image, other->background_image) != 0)
if ((node->background_image != NULL) &&
(other->background_image != NULL) &&
!g_file_equal (node->background_image, other->background_image))
return FALSE;
_st_theme_node_ensure_geometry (node);

View File

@ -162,7 +162,7 @@ gboolean st_theme_node_lookup_shadow (StThemeNode *node,
gboolean st_theme_node_lookup_url (StThemeNode *node,
const char *property_name,
gboolean inherit,
char **value);
GFile **file);
/* Easier-to-use variants of the above, for application-level use */
void st_theme_node_get_color (StThemeNode *node,
@ -174,7 +174,7 @@ gdouble st_theme_node_get_length (StThemeNode *node,
const char *property_name);
StShadow *st_theme_node_get_shadow (StThemeNode *node,
const char *property_name);
char *st_theme_node_get_url (StThemeNode *node,
GFile *st_theme_node_get_url (StThemeNode *node,
const char *property_name);
/* Specific getters for particular properties: cached
@ -188,7 +188,7 @@ void st_theme_node_get_background_gradient (StThemeNode *node,
ClutterColor *start,
ClutterColor *end);
const char *st_theme_node_get_background_image (StThemeNode *node);
GFile *st_theme_node_get_background_image (StThemeNode *node);
int st_theme_node_get_border_width (StThemeNode *node,
StSide side);

View File

@ -60,13 +60,13 @@ struct _StTheme
{
GObject parent;
char *application_stylesheet;
char *default_stylesheet;
char *theme_stylesheet;
GFile *application_stylesheet;
GFile *default_stylesheet;
GFile *theme_stylesheet;
GSList *custom_stylesheets;
GHashTable *stylesheets_by_filename;
GHashTable *filenames_by_stylesheet;
GHashTable *stylesheets_by_file;
GHashTable *files_by_stylesheet;
CRCascade *cascade;
};
@ -98,12 +98,25 @@ G_DEFINE_TYPE (StTheme, st_theme, G_TYPE_OBJECT)
#define strqcmp(str,lit,lit_len) \
(strlen (str) != (lit_len) || memcmp (str, lit, lit_len))
static gboolean
file_equal0 (GFile *file1,
GFile *file2)
{
if (file1 == file2)
return TRUE;
if ((file1 == NULL) || (file2 == NULL))
return FALSE;
return g_file_equal (file1, file2);
}
static void
st_theme_init (StTheme *theme)
{
theme->stylesheets_by_filename = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free, (GDestroyNotify)cr_stylesheet_unref);
theme->filenames_by_stylesheet = g_hash_table_new (g_direct_hash, g_direct_equal);
theme->stylesheets_by_file = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
(GDestroyNotify)g_object_unref, (GDestroyNotify)cr_stylesheet_unref);
theme->files_by_stylesheet = g_hash_table_new (g_direct_hash, g_direct_equal);
}
static void
@ -124,10 +137,10 @@ st_theme_class_init (StThemeClass *klass)
*/
g_object_class_install_property (object_class,
PROP_APPLICATION_STYLESHEET,
g_param_spec_string ("application-stylesheet",
g_param_spec_object ("application-stylesheet",
"Application Stylesheet",
"Stylesheet with application-specific styling",
NULL,
G_TYPE_FILE,
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
/**
@ -138,10 +151,10 @@ st_theme_class_init (StThemeClass *klass)
*/
g_object_class_install_property (object_class,
PROP_THEME_STYLESHEET,
g_param_spec_string ("theme-stylesheet",
g_param_spec_object ("theme-stylesheet",
"Theme Stylesheet",
"Stylesheet with theme-specific styling",
NULL,
G_TYPE_FILE,
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
/**
@ -152,10 +165,10 @@ st_theme_class_init (StThemeClass *klass)
*/
g_object_class_install_property (object_class,
PROP_DEFAULT_STYLESHEET,
g_param_spec_string ("default-stylesheet",
g_param_spec_object ("default-stylesheet",
"Default Stylesheet",
"Stylesheet with global default styling",
NULL,
G_TYPE_FILE,
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
signals[STYLESHEETS_CHANGED] =
@ -168,23 +181,32 @@ st_theme_class_init (StThemeClass *klass)
}
static CRStyleSheet *
parse_stylesheet (const char *filename,
GError **error)
parse_stylesheet (GFile *file,
GError **error)
{
enum CRStatus status;
CRStyleSheet *stylesheet;
char *contents;
gsize length;
if (filename == NULL)
if (file == NULL)
return NULL;
status = cr_om_parser_simply_parse_file ((const guchar *) filename,
CR_UTF_8,
&stylesheet);
if (!g_file_load_contents (file, NULL, &contents, &length, NULL, error))
return NULL;
status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
length,
CR_UTF_8,
&stylesheet);
g_free (contents);
if (status != CR_OK)
{
char *uri = g_file_get_uri (file);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error parsing stylesheet '%s'; errcode:%d", filename, status);
"Error parsing stylesheet '%s'; errcode:%d", uri, status);
g_free (uri);
return NULL;
}
@ -203,12 +225,12 @@ _st_theme_parse_declaration_list (const char *str)
/* Just g_warning for now until we have something nicer to do */
static CRStyleSheet *
parse_stylesheet_nofail (const char *filename)
parse_stylesheet_nofail (GFile *file)
{
GError *error = NULL;
CRStyleSheet *result;
result = parse_stylesheet (filename, &error);
result = parse_stylesheet (file, &error);
if (error)
{
g_warning ("%s", error->message);
@ -219,35 +241,33 @@ parse_stylesheet_nofail (const char *filename)
static void
insert_stylesheet (StTheme *theme,
const char *filename,
GFile *file,
CRStyleSheet *stylesheet)
{
char *filename_copy;
if (stylesheet == NULL)
return;
filename_copy = g_strdup(filename);
g_object_ref (file);
cr_stylesheet_ref (stylesheet);
g_hash_table_insert (theme->stylesheets_by_filename, filename_copy, stylesheet);
g_hash_table_insert (theme->filenames_by_stylesheet, stylesheet, filename_copy);
g_hash_table_insert (theme->stylesheets_by_file, file, stylesheet);
g_hash_table_insert (theme->files_by_stylesheet, stylesheet, file);
}
gboolean
st_theme_load_stylesheet (StTheme *theme,
const char *path,
GFile *file,
GError **error)
{
CRStyleSheet *stylesheet;
stylesheet = parse_stylesheet (path, error);
stylesheet = parse_stylesheet (file, error);
if (!stylesheet)
return FALSE;
stylesheet->app_data = GUINT_TO_POINTER (TRUE);
insert_stylesheet (theme, path, stylesheet);
insert_stylesheet (theme, file, stylesheet);
cr_stylesheet_ref (stylesheet);
theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet);
g_signal_emit (theme, signals[STYLESHEETS_CHANGED], 0);
@ -257,11 +277,11 @@ st_theme_load_stylesheet (StTheme *theme,
void
st_theme_unload_stylesheet (StTheme *theme,
const char *path)
GFile *file)
{
CRStyleSheet *stylesheet;
stylesheet = g_hash_table_lookup (theme->stylesheets_by_filename, path);
stylesheet = g_hash_table_lookup (theme->stylesheets_by_file, file);
if (!stylesheet)
return;
@ -269,8 +289,8 @@ st_theme_unload_stylesheet (StTheme *theme,
return;
theme->custom_stylesheets = g_slist_remove (theme->custom_stylesheets, stylesheet);
g_hash_table_remove (theme->stylesheets_by_filename, path);
g_hash_table_remove (theme->filenames_by_stylesheet, stylesheet);
g_hash_table_remove (theme->stylesheets_by_file, file);
g_hash_table_remove (theme->files_by_stylesheet, stylesheet);
cr_stylesheet_unref (stylesheet);
g_signal_emit (theme, signals[STYLESHEETS_CHANGED], 0);
}
@ -279,7 +299,7 @@ st_theme_unload_stylesheet (StTheme *theme,
* st_theme_get_custom_stylesheets:
* @theme: an #StTheme
*
* Returns: (transfer full) (element-type utf8): the list of stylesheet filenames
* Returns: (transfer full) (element-type GFile): the list of stylesheet files
* that were loaded with st_theme_load_stylesheet()
*/
GSList*
@ -291,9 +311,9 @@ st_theme_get_custom_stylesheets (StTheme *theme)
for (iter = theme->custom_stylesheets; iter; iter = iter->next)
{
CRStyleSheet *stylesheet = iter->data;
gchar *filename = g_hash_table_lookup (theme->filenames_by_stylesheet, stylesheet);
GFile *file = g_hash_table_lookup (theme->files_by_stylesheet, stylesheet);
result = g_slist_prepend (result, g_strdup (filename));
result = g_slist_prepend (result, g_object_ref (file));
}
return result;
@ -334,12 +354,12 @@ st_theme_finalize (GObject * object)
g_slist_free (theme->custom_stylesheets);
theme->custom_stylesheets = NULL;
g_hash_table_destroy (theme->stylesheets_by_filename);
g_hash_table_destroy (theme->filenames_by_stylesheet);
g_hash_table_destroy (theme->stylesheets_by_file);
g_hash_table_destroy (theme->files_by_stylesheet);
g_free (theme->application_stylesheet);
g_free (theme->theme_stylesheet);
g_free (theme->default_stylesheet);
g_clear_object (&theme->application_stylesheet);
g_clear_object (&theme->theme_stylesheet);
g_clear_object (&theme->default_stylesheet);
if (theme->cascade)
{
@ -362,36 +382,39 @@ st_theme_set_property (GObject *object,
{
case PROP_APPLICATION_STYLESHEET:
{
const char *path = g_value_get_string (value);
GFile *file = g_value_get_object (value);
if (path != theme->application_stylesheet)
if (!file_equal0 (file, theme->application_stylesheet))
{
g_free (theme->application_stylesheet);
theme->application_stylesheet = g_strdup (path);
g_clear_object (&theme->application_stylesheet);
if (file != NULL)
theme->application_stylesheet = g_object_ref (file);
}
break;
}
case PROP_THEME_STYLESHEET:
{
const char *path = g_value_get_string (value);
GFile *file = g_value_get_object (value);
if (path != theme->theme_stylesheet)
if (!file_equal0 (file, theme->theme_stylesheet))
{
g_free (theme->theme_stylesheet);
theme->theme_stylesheet = g_strdup (path);
g_clear_object (&theme->theme_stylesheet);
if (file != NULL)
theme->theme_stylesheet = g_object_ref (file);
}
break;
}
case PROP_DEFAULT_STYLESHEET:
{
const char *path = g_value_get_string (value);
GFile *file = g_value_get_object (value);
if (path != theme->default_stylesheet)
if (!file_equal0 (file, theme->default_stylesheet))
{
g_free (theme->default_stylesheet);
theme->default_stylesheet = g_strdup (path);
g_clear_object (&theme->default_stylesheet);
if (file != NULL)
theme->default_stylesheet = g_object_ref (file);
}
break;
@ -413,13 +436,13 @@ st_theme_get_property (GObject *object,
switch (prop_id)
{
case PROP_APPLICATION_STYLESHEET:
g_value_set_string (value, theme->application_stylesheet);
g_value_set_object (value, theme->application_stylesheet);
break;
case PROP_THEME_STYLESHEET:
g_value_set_string (value, theme->theme_stylesheet);
g_value_set_object (value, theme->theme_stylesheet);
break;
case PROP_DEFAULT_STYLESHEET:
g_value_set_string (value, theme->default_stylesheet);
g_value_set_object (value, theme->default_stylesheet);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -439,9 +462,9 @@ st_theme_get_property (GObject *object,
* Return value: the newly created theme object
**/
StTheme *
st_theme_new (const char *application_stylesheet,
const char *theme_stylesheet,
const char *default_stylesheet)
st_theme_new (GFile *application_stylesheet,
GFile *theme_stylesheet,
GFile *default_stylesheet)
{
StTheme *theme = g_object_new (ST_TYPE_THEME,
"application-stylesheet", application_stylesheet,
@ -852,26 +875,19 @@ add_matched_properties (StTheme *a_this,
if (import_rule->sheet == NULL)
{
char *filename = NULL;
GFile *file = NULL;
if (import_rule->url->stryng && import_rule->url->stryng->str)
{
GFile *file;
file = _st_theme_resolve_url (a_this,
a_nodesheet,
import_rule->url->stryng->str);
filename = g_file_get_path (file);
g_object_unref (file);
import_rule->sheet = parse_stylesheet (file, NULL);
}
if (filename)
import_rule->sheet = parse_stylesheet (filename, NULL);
if (import_rule->sheet)
{
insert_stylesheet (a_this, filename, import_rule->sheet);
insert_stylesheet (a_this, file, import_rule->sheet);
/* refcount of stylesheets starts off at zero, so we don't need to unref! */
}
else
@ -882,8 +898,8 @@ add_matched_properties (StTheme *a_this,
import_rule->sheet = (CRStyleSheet *) - 1;
}
if (filename)
g_free (filename);
if (file)
g_object_unref (file);
}
if (import_rule->sheet != (CRStyleSheet *) - 1)
@ -1008,8 +1024,8 @@ _st_theme_get_matched_properties (StTheme *theme,
return props;
}
/* Resolve an url from an url() reference in a stylesheet into an absolute
* local filename, if possible. The resolution here is distinctly lame and
/* Resolve an url from an url() reference in a stylesheet into a GFile,
* if possible. The resolution here is distinctly lame and
* will fail on many examples.
*/
GFile *
@ -1018,7 +1034,7 @@ _st_theme_resolve_url (StTheme *theme,
const char *url)
{
char *scheme;
GFile *stylesheet, *resource;
GFile *resource;
if ((scheme = g_uri_parse_scheme (url)))
{
@ -1027,21 +1043,18 @@ _st_theme_resolve_url (StTheme *theme,
}
else if (base_stylesheet != NULL)
{
const char *base_filename = NULL;
char *dirname;
GFile *base_file = NULL, *parent;
base_filename = g_hash_table_lookup (theme->filenames_by_stylesheet, base_stylesheet);
base_file = g_hash_table_lookup (theme->files_by_stylesheet, base_stylesheet);
/* This is an internal function, if we get here with
a bad @base_stylesheet we have a problem. */
g_assert (base_filename);
g_assert (base_file);
dirname = g_path_get_dirname (base_filename);
stylesheet = g_file_new_for_path (dirname);
resource = g_file_resolve_relative_path (stylesheet, url);
parent = g_file_get_parent (base_file);
resource = g_file_resolve_relative_path (parent, url);
g_object_unref (stylesheet);
g_free (dirname);
g_object_unref (parent);
}
else
{

View File

@ -47,12 +47,12 @@ typedef struct _StThemeClass StThemeClass;
GType st_theme_get_type (void) G_GNUC_CONST;
StTheme *st_theme_new (const char *application_stylesheet,
const char *theme_stylesheet,
const char *default_stylesheet);
StTheme *st_theme_new (GFile *application_stylesheet,
GFile *theme_stylesheet,
GFile *default_stylesheet);
gboolean st_theme_load_stylesheet (StTheme *theme, const char *path, GError **error);
void st_theme_unload_stylesheet (StTheme *theme, const char *path);
gboolean st_theme_load_stylesheet (StTheme *theme, GFile *file, GError **error);
void st_theme_unload_stylesheet (StTheme *theme, GFile *file);
GSList *st_theme_get_custom_stylesheets (StTheme *theme);
G_END_DECLS

View File

@ -277,26 +277,26 @@ current_paint_state (StWidget *widget)
static void
st_widget_texture_cache_changed (StTextureCache *cache,
const char *uri,
GFile *file,
gpointer user_data)
{
StWidget *actor = ST_WIDGET (user_data);
StThemeNode *node = actor->priv->theme_node;
char *path;
gboolean changed = FALSE;
GFile *theme_file;
if (node == NULL)
return;
path = g_filename_from_uri (uri, NULL, NULL);
if (g_strcmp0 (st_theme_node_get_background_image (node), path) == 0)
theme_file = st_theme_node_get_background_image (node);
if ((theme_file != NULL) && g_file_equal (theme_file, file))
{
st_theme_node_invalidate_background_image (node);
changed = TRUE;
}
if (g_strcmp0 (st_border_image_get_filename (st_theme_node_get_border_image (node)), path) == 0)
theme_file = st_border_image_get_file (st_theme_node_get_border_image (node));
if ((theme_file != NULL) && g_file_equal (theme_file, file))
{
st_theme_node_invalidate_border_image (node);
changed = TRUE;
@ -317,8 +317,6 @@ st_widget_texture_cache_changed (StTextureCache *cache,
if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (actor)))
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
}
g_free (path);
}
static void

View File

@ -173,17 +173,21 @@ assert_background_image (StThemeNode *node,
const char *node_description,
const char *expected)
{
const char *value = st_theme_node_get_background_image (node);
if (expected == NULL)
expected = "(null)";
if (value == NULL)
value = "(null)";
GFile *value = st_theme_node_get_background_image (node);
GFile *expected_file;
if (strcmp (expected, value) != 0)
if (expected != NULL && value != NULL)
{
g_print ("%s: %s.background-image: expected: %s, got: %s\n",
test, node_description, expected, value);
fail = TRUE;
expected_file = g_file_new_for_path (expected);
if (!g_file_equal (expected_file, value))
{
char *uri = g_file_get_uri (expected_file);
g_print ("%s: %s.background-image: expected: %s, got: %s\n",
test, node_description, expected, uri);
fail = TRUE;
g_free (uri);
}
}
}
@ -426,14 +430,16 @@ main (int argc, char **argv)
StTheme *theme;
StThemeContext *context;
PangoFontDescription *font_desc;
GFile *file;
gtk_init (&argc, &argv);
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
theme = st_theme_new ("st/test-theme.css",
NULL, NULL);
file = g_file_new_for_path ("st/test-theme.css");
theme = st_theme_new (file, NULL, NULL);
g_object_unref (file);
stage = clutter_stage_new ();
context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));

View File

@ -312,6 +312,9 @@ function test() {
button.label = 'NEVER';
break;
case 'NEVER':
button.label = 'EXTERNAL';
break;
case 'EXTERNAL':
button.label = 'AUTOMATIC';
break;
}

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const St = imports.gi.St;
@ -10,7 +11,7 @@ function init(stage) {
Environment.init();
let context = St.ThemeContext.get_for_stage(stage);
let stylesheetPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/test.css";
let theme = new St.Theme({ application_stylesheet: stylesheetPath });
let theme = new St.Theme({ application_stylesheet: Gio.File.new_for_path(stylesheetPath) });
context.set_theme(theme);
}