Compare commits

..

25 Commits

Author SHA1 Message Date
Mario Sanchez Prada
1b7577298a window-tracker: check WM_CLASS for sandboxed apps before the app's ID
For sandboxed apps, the shell needs to consider the app's ID when
matching its windows against the right .desktop file, but that
check can't be done before having attempted to match using the
WM_CLASS property of the app's window, otherwise apps installing
multiple desktop files (e.g. LibreOffice) will always match every
single window against the same .desktop file, ignoring hints such
as the StartupWMClass key.

This commit moves the call to get_app_from_sandboxed_app_id() after
get_app_from_window_wmclass() and before get_app_from_window_pid(),
so that we only rely on the sandboxed app's ID when no match has
succeed using the WM_CLASS property, but before checking by PID to
prevent wrong groups that could be created when the PID of the app
inside the sandbox matches the one from a process outside of it.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/219
2018-04-20 14:09:28 +01:00
Stas Solovey
c4e0f6df08 Update Russian translation
(cherry picked from commit 0d031dc20f)
2018-04-19 20:33:21 +00:00
verdre
58aafe9520 theme: Improve look of login user-list
* Remove tiny padding of user-list
* Less space between avatar and username
* Apply the 1em padding only to the user-widget, not the timed-login-indicator
2018-04-19 17:26:14 +02:00
verdre
a46df7f8ec theme: Use a padding of 6px on the user-list items according to HIG 2018-04-19 17:26:14 +02:00
verdre
1dd16618d1 loginDialog: Don't display timed login indicator if unused
This fixes the slightly bigger padding underneath the login item compared to the padding above
2018-04-19 17:26:14 +02:00
verdre
a4190f83ac loginDialog: Correct source name for timed login idle timeout
The _blockTimedLoginUntilIdle method sets a timeout to be called after
the user is idle for 5 seconds.  That timeout is erroneously given the
source name "[gnome-shell] this._timedLoginAnimationTime" which looks
like a copy-and-paste mistake.  The original intention was probably to
use a source name of "[gnome-shell] this._timedLoginIdleTimeOutId" which
more closely matches existing convention for source names.

This commit fixes that.
2018-04-19 17:26:14 +02:00
verdre
a8e17f73ec loginDialog: Use more function scope variables inside _startTimedLogin
Using function scope variables increases readability and prevents
unwanted changes from outside while the batch is running.
2018-04-19 17:26:13 +02:00
verdre
86a741c1ee loginDialog: Make sure timed login indicator is shown after idle timeout
If the idle timeout is done, always show the user list to make sure the
timed login indicator is visible.
2018-04-19 17:25:02 +02:00
verdre
5cc6fef689 loginDialog: Restrict grabbing of focus while timed login is running
Make sure the focus isn't grabbed right after user interaction starts a
new timed login. Only grab it after the idle timeout is done and on the
first run instead.
2018-04-19 09:08:45 +02:00
verdre
522a5fe480 loginDialog: Ensure old timed login timeout is removed before starting a new one
Normally, we give the user a 5 second grace period of inactivity before
starting a timed login operation. Unfortunately, that grace period
timeout isn't properly removed if the timed login operation is restarted
during the grace period. That means the timeout handler can
inadvertently get called multiple times leading to the grace period
duration getting subtracted from the total animation time more than
once.

This commit ensures we only ever have one grace period timeout scheduled
at a time.
2018-04-19 09:08:45 +02:00
verdre
b1239b1257 loginDialog: Use GLib instead of Mainloop for timeout
imports.mainloop is deprecated
2018-04-19 09:08:45 +02:00
verdre
58063d9ee1 loginDialog: Move reset of timed login into _startTimedLogin
This way we can make sure that already running timed logins are
always reset when starting a new one.
2018-04-19 09:08:45 +02:00
verdre
d7aba2dece loginDialog: Ensure timed login indicator is hidden on key presses
The timed login feature currently cancels the timed login operation when
a user presses a key but, oddly, only hides the indicator when the user
releases the key. This means that if a user holds down a key that
doesn't key repeat, the timed login indicator will continue to run after
the timed login operation is cancelled.

This commit address the problem by ensuring the timed login indicator is
hidden on any key press event, at the same time the timed login
operation is canceled.
2018-04-19 09:08:45 +02:00
Takao Fujiwara
35fced27df ibusCandidatePopup: Fix candidate-clicked signal 2018-04-18 13:37:53 +09:00
Mario Sanchez Prada
be76b19300 st-entry: Set text-related CSS properties on the internal ClutterText
Call _st_set_text_from_style() when updating the entry's style, so
that CSS style properties such as text-decoration or letter-spacing
are applied over the internal ClutterText instance.
2018-04-18 00:14:05 +00:00
Mario Sanchez Prada
376d696b8b st-private: Add support for letter-spacing in ClutterText based StWidgets
Add support in _st_set_text_from_style(), so that this CSS property can
be used from any StWidget holding an internal ClutterText.
2018-04-18 00:14:05 +00:00
Mario Sanchez Prada
695d61968d st-theme-node: Add new getter st_theme_node_get_letter_spacing
This will be used by ClutterText-backed StWidgets to update their
list of PangoAttributes according to the letter-spacing property.
2018-04-18 00:14:04 +00:00
Didier Roche
d6d09fd3c8 ui: Theme lookup should respect XDG_DATA_DIRS
Modes, extensions and other GNOME Shell assets are searched in appropriate
subdirectories of each directory in XDG_DATA_DIRS, falling back
to global.datadir.
However, this isn't the case for themes, which are currently always expected
in global.datadir, even when referenced by a mode in a different XDG_DATA_DIR.

The fix is to have the theme finding pattern follow the same logic as other
elements.
Fixes #167.
2018-04-16 19:09:14 +02:00
gogo
f1b1501f9b Update Croatian translation 2018-04-16 12:31:09 +00:00
Mario Sanchez Prada
cdbc99e992 popupMenu: Fix wrong call to clutter_actor_add_child()
Specify the horizontal alignment via the x_align property when creating
the StIcon, since this function expects one argument, not two.
2018-04-16 11:40:04 +00:00
Florian Müllner
69afe7785d remoteMenu: Support icons in app-menu
The HIG discourages the use of icons in menus except for "noun" items
(files, bookmarks, ...). While those should be rarely used in the
application menu, it still makes sense to support them in the few
cases where they are used.

https://bugzilla.gnome.org/show_bug.cgi?id=760985
2018-04-14 09:02:20 +00:00
Marco Trevisan (Treviño)
b99e304f1e workspaceThumbnail: initialize porthole based on workArea
https://bugzilla.gnome.org/show_bug.cgi?id=792687
2018-04-13 16:59:51 -05:00
Marco Trevisan (Treviño)
c29bd46e7a workspaceThumbnail: rebuild thumbnails if workareas size changed
https://bugzilla.gnome.org/show_bug.cgi?id=792687
2018-04-13 16:58:28 -05:00
Marco Trevisan (Treviño)
5fcf40b973 workspaceThumbnail: only update _porthole if the overview is visible
Otherwise it happens that porthole is computed again after that the
overlay is hidden (triggered by a layout reallocation) and thus not
regenerated again afterwards.

https://bugzilla.gnome.org/show_bug.cgi?id=792687
2018-04-13 16:53:18 -05:00
Piotr Drąg
a198dfe3d8 thunderbolt: capitalize Thunderbolt in a translatable string 2018-04-13 21:52:32 +02:00
73 changed files with 1807 additions and 3313 deletions

2
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "subprojects/gvc"]
path = subprojects/gvc
url = https://gitlab.gnome.org/GNOME/libgnome-volume-control.git
url = https://git.gnome.org/browse/libgnome-volume-control

55
NEWS
View File

@@ -1,58 +1,3 @@
3.28.4
======
* Fix wrong window positions in overview on wayland [Marco; #776588]
* overview: Fix handling of confirmation dialogs on wayland [verdre; !180]
* Avoid some full relayout/redraws [Carlos; !197]
* Keep workspace switcher slid out when workspaces are in use [Florian; !161]
* Cancel search on overview hiding [Marco; !205]
* Fix disappearing network icon [Iain; #140]
* Improve performance of app icon animations [Daniel; !253]
* notifications: Support icon theme names in 'image-path' hint [Marco; !285]
* Avoid focus changes when updating keyboard options [Takao; #391]
* Fix unresponsive-app dialog blocking input in other windows [Florian; #273]
* Fix ellipsization in dialog subtitles/bodies [Marco; !531]
* Misc. bug fixes [Marco, Andrea, Florian, Jasper, Sam, verdre, Jonas,
Cosimo, Carlos; #792681, #372, !112, !162, #414, #663461, #788882, #787260,
!188, #791233, #602, #632, !305, !286, !314, #781, #693, #618, #430, #799,
#783, !293, #298, #1015, #539, #1270]
Contributors:
Jonas Ådahl, Andrea Azzarone, Cosimo Cecchi, Takao Fujiwara, Carlos Garnacho,
Iain Lane, Florian Müllner, Georges Basile Stavracas Neto, Jasper St. Pierre,
Sam Spilsbury, Ray Strode, Will Thompson, Marco Trevisan (Treviño), verdre,
Daniel van Vugt
Translators:
Marek Černocký [cs]
3.28.3
======
* Fix lagging pointer when zoomed [Daniel; #682013]
* Fix "Clear All" for calendar events [Florian; #325]
* Misc. bug fixes [Florian, Mario, Marco; #136, #214, #788931, #791233]
Contributors:
Carlos Garnacho, Florian Müllner, Mario Sanchez Prada, Joe Rabinoff,
Didier Roche, Marco Trevisan (Treviño), Daniel van Vugt
Translators:
Pieter Schalk Schoeman [af], Gun Chleoc [gd]
3.28.2
======
* Fix lock-up on cancelling polkit dialog [Florian; #221]
* Guard against untimely keyboard map changes [Carlos; #240]
* Fix blurriness of OSD under some resolutions [Silvère; #782011]
* Fix icons in search provider results [Florian; #249]
* Misc. bug fixes [Marco, Florian; #792687, #781471]
Contributors:
Carlos Garnacho, Silvère Latchurié, Florian Müllner, Mario Sanchez Prada,
Ray Strode, Marco Trevisan (Treviño)
Translators:
Stas Solovey [ru], Rafael Fontenelle [pt_BR]
3.28.1
======
* Fix compose characters in shell entries [Carlos; #115]

View File

@@ -6,7 +6,6 @@
<file>be.json</file>
<file>bg.json</file>
<file>by.json</file>
<file>ca.json</file>
<file>cz.json</file>
<file>de.json</file>
<file>dk.json</file>

View File

@@ -1,599 +0,0 @@
{
"levels": [
{
"level": "",
"mode": "default",
"rows": [
[
[
"q"
],
[
"w"
],
[
"e",
"é",
"è",
"ê",
"ë",
"%",
"ę",
"ė",
"ē"
],
[
"r"
],
[
"t"
],
[
"y",
"%",
"ÿ"
],
[
"u",
"ù",
"û",
"%",
"ü",
"ú",
"ū"
],
[
"i",
"î",
"%",
"ï",
"ì",
"í",
"į",
"ī"
],
[
"o",
"ô",
"œ",
"%",
"ö",
"ò",
"ó",
"õ",
"ø",
"ō",
"º"
],
[
"p"
]
],
[
[
"a",
"à",
"â",
"%",
"æ",
"á",
"ä",
"ã",
"å",
"ā",
"ª"
],
[
"s"
],
[
"d"
],
[
"f"
],
[
"g"
],
[
"h"
],
[
"j"
],
[
"k"
],
[
"l"
]
],
[
[
"z"
],
[
"x"
],
[
"c",
"ç",
"ć",
"č"
],
[
"v"
],
[
"b"
],
[
"n"
],
[
"m"
]
],
[
[
","
],
[
" "
],
[
".",
"#",
"!",
",",
"?",
"-",
":",
"'",
"@"
]
]
]
},
{
"level": "shift",
"mode": "latched",
"rows": [
[
[
"Q"
],
[
"W"
],
[
"E",
"É",
"È",
"Ê",
"Ë",
"%",
"Ę",
"Ė",
"Ē"
],
[
"R"
],
[
"T"
],
[
"Y",
"%",
"Ÿ"
],
[
"U",
"Ù",
"Û",
"%",
"Ü",
"Ú",
"Ū"
],
[
"I",
"Î",
"%",
"Ï",
"Ì",
"Í",
"Į",
"Ī"
],
[
"O",
"Ô",
"Œ",
"%",
"Ö",
"Ò",
"Ó",
"Õ",
"Ø",
"Ō",
"º"
],
[
"P"
]
],
[
[
"A",
"À",
"Â",
"%",
"Æ",
"Á",
"Ä",
"Ã",
"Å",
"Ā",
"ª"
],
[
"S"
],
[
"D"
],
[
"F"
],
[
"G"
],
[
"H"
],
[
"J"
],
[
"K"
],
[
"L"
]
],
[
[
"Z"
],
[
"X"
],
[
"C",
"Ç",
"Ć",
"Č"
],
[
"V"
],
[
"B"
],
[
"N"
],
[
"M"
]
],
[
[
","
],
[
" "
],
[
".",
"#",
"!",
",",
"?",
"-",
":",
"'",
"@"
]
]
]
},
{
"level": "opt",
"mode": "locked",
"rows": [
[
[
"1",
"¹",
"½",
"⅓",
"¼",
"⅛"
],
[
"2",
"²",
"⅔"
],
[
"3",
"³",
"¾",
"⅜"
],
[
"4",
"⁴"
],
[
"5",
"⅝"
],
[
"6"
],
[
"7",
"⅞"
],
[
"8"
],
[
"9"
],
[
"0",
"ⁿ",
"∅"
]
],
[
[
"@"
],
[
"#"
],
[
"$",
"¢",
"£",
"€",
"¥",
"₱"
],
[
"%",
"‰"
],
[
"&"
],
[
"-",
"_",
"",
"—",
"·"
],
[
"+",
"±"
],
[
"(",
"<",
"{",
"["
],
[
")",
">",
"}",
"]"
]
],
[
[
"*",
"†",
"‡",
"★"
],
[
"\"",
"“",
"”",
"«",
"»"
],
[
"'",
"",
"",
"",
""
],
[
":"
],
[
";"
],
[
"!",
"¡"
],
[
"?",
"¿"
]
],
[
[
"_"
],
[
"/"
],
[
" "
],
[
","
],
[
".",
"…"
]
]
]
},
{
"level": "opt+shift",
"mode": "locked",
"rows": [
[
[
"~"
],
[
"`"
],
[
"|"
],
[
"•",
"♪",
"♥",
"♠",
"♦",
"♣"
],
[
"√"
],
[
"Π",
"π"
],
[
"÷"
],
[
"×"
],
[
"¶",
"§"
],
[
"∆"
]
],
[
[
"£"
],
[
"¢"
],
[
"€"
],
[
"¥"
],
[
"^",
"↑",
"↓",
"←",
"→"
],
[
"°",
"",
"″"
],
[
"=",
"≠",
"≈",
"∞"
],
[
"{"
],
[
"}"
]
],
[
[
"\\"
],
[
"©"
],
[
"®"
],
[
"™"
],
[
"℅"
],
[
"["
],
[
"]"
]
],
[
[
"<",
"",
"≤",
"«"
],
[
">",
"",
"≥",
"»"
],
[
" "
],
[
","
],
[
".",
"…"
]
]
]
}
],
"locale": "fr-CA",
"name": "French Canada"
}

View File

@@ -6,20 +6,10 @@
"rows": [
[
[
"a",
"à",
"â",
"%",
"æ",
"á",
"ä",
"ã",
"å",
"ā",
"ª"
"q"
],
[
"z"
"w"
],
[
"e",
@@ -81,7 +71,17 @@
],
[
[
"q"
"a",
"à",
"â",
"%",
"æ",
"á",
"ä",
"ã",
"å",
"ā",
"ª"
],
[
"s"
@@ -106,14 +106,11 @@
],
[
"l"
],
[
"m"
]
],
[
[
"w"
"z"
],
[
"x"
@@ -134,11 +131,7 @@
"n"
],
[
"'",
"",
"",
"",
""
"m"
]
],
[
@@ -168,20 +161,10 @@
"rows": [
[
[
"A",
"À",
"Â",
"%",
"Æ",
"Á",
"Ä",
"Ã",
"Å",
"Ā",
"ª"
"Q"
],
[
"Z"
"W"
],
[
"E",
@@ -243,7 +226,17 @@
],
[
[
"Q"
"A",
"À",
"Â",
"%",
"Æ",
"Á",
"Ä",
"Ã",
"Å",
"Ā",
"ª"
],
[
"S"
@@ -268,14 +261,11 @@
],
[
"L"
],
[
"M"
]
],
[
[
"W"
"Z"
],
[
"X"
@@ -296,11 +286,7 @@
"N"
],
[
"'",
"",
"",
"",
""
"M"
]
],
[
@@ -383,10 +369,10 @@
"#"
],
[
"",
"$",
"¢",
"£",
"$",
"",
"¥",
"₱"
],
@@ -524,16 +510,15 @@
[
"£"
],
[
"¢"
],
[
"€"
],
[
"¥"
],
[
"$",
"¢"
],
[
"¢"
],
[
"^",
"↑",
@@ -609,6 +594,6 @@
]
}
],
"locale": "fr",
"name": "French"
"locale": "fr-CA",
"name": "French Canada"
}

View File

@@ -1788,20 +1788,19 @@ StScrollBar {
.login-dialog-user-list-view { -st-vfade-offset: 1em; }
.login-dialog-user-list {
spacing: 12px;
padding: .2em;
width: 23em;
&:expanded .login-dialog-user-list-item:selected { background-color: $selected_bg_color; color: $selected_fg_color; }
&:expanded .login-dialog-user-list-item:logged-in { border-right: 2px solid $selected_bg_color; }
}
.login-dialog-user-list-item {
border-radius: 5px;
padding: .2em;
padding: 6px;
color: darken($osd_fg_color,30%);
&:ltr { padding-right: 1em; }
&:rtl { padding-left: 1em; }
&:ltr .user-widget { padding-right: 1em; }
&:rtl .user-widget { padding-left: 1em; }
.login-dialog-timed-login-indicator {
height: 2px;
margin: 2px 0 0 0;
margin-top: 6px;
background-color: $osd_fg_color;
}
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
@@ -1816,8 +1815,8 @@ StScrollBar {
padding-left: 15px;
}
.user-widget-label {
&:ltr { padding-left: 18px; }
&:rtl { padding-right: 18px; }
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.login-dialog-prompt-layout {

View File

@@ -242,11 +242,11 @@ var AuthPrompt = new Lang.Class({
this.emit('prompted');
},
_onVerificationFailed(userVerifier, canRetry) {
_onVerificationFailed() {
this._queryingService = null;
this.clear();
this.updateSensitivity(canRetry);
this.updateSensitivity(true);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
},
@@ -439,7 +439,6 @@ var AuthPrompt = new Lang.Class({
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = true;
this.nextButton.label = _("Next");
this._preemptiveAnswer = null;
if (this._userVerifier)
this._userVerifier.cancel();

View File

@@ -25,7 +25,6 @@ const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@@ -86,7 +85,8 @@ var UserListItem = new Lang.Class({
GObject.BindingFlags.SYNC_CREATE);
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0 });
scale_x: 0,
visible: false });
layout.add(this._timedLoginIndicator);
this.actor.connect('clicked', this._onClicked.bind(this));
@@ -126,6 +126,8 @@ var UserListItem = new Lang.Class({
this.hideTimedLoginIndicator();
this._timedLoginIndicator.visible = true;
let startTime = GLib.get_monotonic_time();
this._timedLoginTimeoutId = GLib.timeout_add (GLib.PRIORITY_DEFAULT, 33,
@@ -152,6 +154,8 @@ var UserListItem = new Lang.Class({
GLib.source_remove(this._timedLoginTimeoutId);
this._timedLoginTimeoutId = 0;
}
this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.;
}
});
@@ -991,59 +995,81 @@ var LoginDialog = new Lang.Class({
return hold;
},
_showTimedLoginAnimation() {
this._timedLoginItem.actor.grab_key_focus();
return this._timedLoginItem.showTimedLoginIndicator(this._timedLoginAnimationTime);
},
_blockTimedLoginUntilIdle() {
// This blocks timed login from starting until a few
// seconds after the user stops interacting with the
// login screen.
//
// We skip this step if the timed login delay is very
// short.
if ((this._timedLoginDelay - _TIMED_LOGIN_IDLE_THRESHOLD) <= 0)
return null;
let hold = new Batch.Hold();
this._timedLoginIdleTimeOutId = Mainloop.timeout_add_seconds(_TIMED_LOGIN_IDLE_THRESHOLD,
this._timedLoginIdleTimeOutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, _TIMED_LOGIN_IDLE_THRESHOLD,
() => {
this._timedLoginAnimationTime -= _TIMED_LOGIN_IDLE_THRESHOLD;
this._timedLoginIdleTimeOutId = 0;
hold.release();
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginAnimationTime');
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginIdleTimeOutId');
return hold;
},
_startTimedLogin(userName, delay) {
this._timedLoginItem = null;
this._timedLoginDelay = delay;
this._timedLoginAnimationTime = delay;
let firstRun = true;
// Cancel execution of old batch
if (this._timedLoginBatch) {
this._timedLoginBatch.cancel();
this._timedLoginBatch = null;
firstRun = false;
}
// Reset previous idle-timeout
if (this._timedLoginIdleTimeOutId) {
GLib.source_remove(this._timedLoginIdleTimeOutId);
this._timedLoginIdleTimeOutId = 0;
}
let loginItem = null;
let animationTime;
let tasks = [() => this._waitForItemForUser(userName),
() => {
this._timedLoginItem = this._userList.getItemFromUserName(userName);
loginItem = this._userList.getItemFromUserName(userName);
// If there is an animation running on the item, reset it.
loginItem.hideTimedLoginIndicator();
},
() => {
// If we're just starting out, start on the right
// item.
// If we're just starting out, start on the right item.
if (!this._userManager.is_loaded) {
this._userList.jumpToItem(this._timedLoginItem);
this._userList.jumpToItem(loginItem);
}
},
this._blockTimedLoginUntilIdle,
() => {
this._userList.scrollToItem(this._timedLoginItem);
// This blocks the timed login animation until a few
// seconds after the user stops interacting with the
// login screen.
// We skip this step if the timed login delay is very short.
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD) {
animationTime = delay - _TIMED_LOGIN_IDLE_THRESHOLD;
return this._blockTimedLoginUntilIdle();
} else {
animationTime = delay;
}
},
this._showTimedLoginAnimation,
() => {
// If idle timeout is done, make sure the timed login indicator is shown
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
this._authPrompt.actor.visible)
this._authPrompt.cancel();
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
this._userList.scrollToItem(loginItem);
loginItem.actor.grab_key_focus();
}
},
() => loginItem.showTimedLoginIndicator(animationTime),
() => {
this._timedLoginBatch = null;
@@ -1055,37 +1081,17 @@ var LoginDialog = new Lang.Class({
return this._timedLoginBatch.run();
},
_resetTimedLogin() {
if (this._timedLoginBatch) {
this._timedLoginBatch.cancel();
this._timedLoginBatch = null;
}
if (this._timedLoginItem)
this._timedLoginItem.hideTimedLoginIndicator();
let userName = this._timedLoginItem.user.get_user_name();
if (userName)
this._startTimedLogin(userName, this._timedLoginDelay);
},
_onTimedLoginRequested(client, userName, seconds) {
if (this._timedLoginBatch)
return;
this._startTimedLogin(userName, seconds);
// Restart timed login on user interaction
global.stage.connect('captured-event', (actor, event) => {
if (this._timedLoginDelay == undefined)
return Clutter.EVENT_PROPAGATE;
if (event.type() == Clutter.EventType.KEY_PRESS ||
event.type() == Clutter.EventType.BUTTON_PRESS) {
if (this._timedLoginBatch) {
this._timedLoginBatch.cancel();
this._timedLoginBatch = null;
}
} else if (event.type() == Clutter.EventType.KEY_RELEASE ||
event.type() == Clutter.EventType.BUTTON_RELEASE) {
this._resetTimedLogin();
this._startTimedLogin(userName, seconds);
}
return Clutter.EVENT_PROPAGATE;

View File

@@ -534,13 +534,12 @@ var ShellUserVerifier = new Lang.Class({
_verificationFailed(retry) {
// For Not Listed / enterprise logins, immediately reset
// the dialog
// Otherwise, when in login mode we allow ALLOWED_FAILURES attempts.
// After that, we go back to the welcome screen.
// Otherwise, we allow ALLOWED_FAILURES attempts. After that, we
// go back to the welcome screen.
this._failCounter++;
let canRetry = retry && this._userName &&
(this._reauthOnly ||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY));
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
if (canRetry) {
if (!this.hasPendingMessages) {
@@ -563,7 +562,7 @@ var ShellUserVerifier = new Lang.Class({
}
}
this.emit('verification-failed', canRetry);
this.emit('verification-failed');
},
_onConversationStopped(client, serviceName) {

View File

@@ -115,11 +115,6 @@ var IBusManager = new Lang.Class({
object_path: IBus.PATH_PANEL });
this._candidatePopup.setPanelService(this._panelService);
this._panelService.connect('update-property', this._updateProperty.bind(this));
this._panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
let cursorLocation = { x, y, width: w, height: h };
this.emit('set-cursor-location', cursorLocation);
});
try {
// IBus versions older than 1.5.10 have a bug which
// causes spurious set-content-type emissions when
@@ -205,7 +200,7 @@ var IBusManager = new Lang.Class({
}
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, callback || null);
null, callback);
},
preloadEngines(ids) {

View File

@@ -52,20 +52,11 @@ var KeyboardManager = new Lang.Class({
this._current = null;
this._localeLayoutInfo = this._getLocaleLayout();
this._layoutInfos = {};
this._currentKeymap = null;
},
_applyLayoutGroup(group) {
let options = this._buildOptionsString();
let [layouts, variants] = this._buildGroupStrings(group);
if (this._currentKeymap &&
this._currentKeymap.layouts == layouts &&
this._currentKeymap.variants == variants &&
this._currentKeymap.options == options)
return;
this._currentKeymap = {layouts, variants, options};
Meta.get_backend().set_keymap(layouts, variants, options);
},

View File

@@ -236,12 +236,11 @@ var ObjectManager = new Lang.Class({
_onNameVanished() {
let objectPaths = Object.keys(this._objects);
for (let i = 0; i < objectPaths.length; i++) {
let objectPath = objectPaths[i];
let object = this._objects[objectPath];
let object = this._objects[objectPaths];
let interfaceNames = Object.keys(object);
for (let j = 0; j < interfaceNames.length; j++) {
let interfaceName = interfaceNames[j];
for (let j = 0; i < interfaceNames.length; i++) {
let interfaceName = interfaceNames[i];
if (object[interfaceName])
this._removeInterface(objectPath, interfaceName);

View File

@@ -802,8 +802,6 @@ var NotificationMessage = new Lang.Class({
},
_onDestroy() {
this.parent();
if (this._updatedId)
this.notification.disconnect(this._updatedId);
this._updatedId = 0;
@@ -823,8 +821,6 @@ var EventsSection = new Lang.Class({
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new EmptyEventSource();
this._messageById = new Map();
this.parent();
this._title = new St.Button({ style_class: 'events-section-title',
@@ -879,32 +875,20 @@ var EventsSection = new Lang.Class({
this._reloading = true;
this._list.destroy_all_children();
let periodBegin = _getBeginningOfDay(this._date);
let periodEnd = _getEndOfDay(this._date);
let events = this._eventSource.getEvents(periodBegin, periodEnd);
let ids = events.map(e => e.id);
this._messageById.forEach((message, id) => {
if (ids.includes(id))
return;
this._messageById.delete(id);
this.removeMessage(message);
});
for (let i = 0; i < events.length; i++) {
let event = events[i];
let message = this._messageById.get(event.id);
if (!message) {
message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this._messageById.set(event.id, message);
this.addMessage(message, false);
} else {
this.moveMessage(message, i, false);
}
let message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this.addMessage(message, false);
}
this._reloading = false;

View File

@@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
@@ -14,7 +13,6 @@ const Tweener = imports.ui.tweener;
var FROZEN_WINDOW_BRIGHTNESS = -0.3
var DIALOG_TRANSITION_TIME = 0.15
var ALIVE_TIMEOUT = 5000;
var CloseDialog = new Lang.Class({
Name: 'CloseDialog',
@@ -28,10 +26,6 @@ var CloseDialog = new Lang.Class({
this.parent();
this._window = window;
this._dialog = null;
this._tracked = undefined;
this._timeoutId = 0;
this._windowFocusChangedId = 0;
this._keyFocusChangedId = 0;
},
get window() {
@@ -99,57 +93,10 @@ var CloseDialog = new Lang.Class({
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
},
_onFocusChanged() {
if (Meta.is_wayland_compositor())
return;
let focusWindow = global.display.focus_window;
let keyFocus = global.stage.key_focus;
let shouldTrack;
if (focusWindow != null)
shouldTrack = focusWindow == this._window;
else
shouldTrack = keyFocus && this._dialog.contains(keyFocus);
if (this._tracked === shouldTrack)
return;
if (shouldTrack)
Main.layoutManager.trackChrome(this._dialog,
{ affectsInputRegion: true });
else
Main.layoutManager.untrackChrome(this._dialog);
// The buttons are broken when they aren't added to the input region,
// so disable them properly in that case
this._dialog.buttonLayout.get_children().forEach(b => {
b.reactive = shouldTrack;
});
this._tracked = shouldTrack;
},
vfunc_show() {
if (this._dialog != null)
return;
Meta.disable_unredirect_for_screen(global.screen);
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, ALIVE_TIMEOUT,
() => {
this._window.check_alive(global.display.get_current_time_roundtrip());
return GLib.SOURCE_CONTINUE;
});
this._windowFocusChangedId =
global.display.connect('notify::focus-window',
this._onFocusChanged.bind(this));
this._keyFocusChangedId =
global.stage.connect('notify::key-focus',
this._onFocusChanged.bind(this));
this._addWindowEffect();
this._initDialog();
@@ -160,7 +107,9 @@ var CloseDialog = new Lang.Class({
{ scale_y: 1,
transition: 'linear',
time: DIALOG_TRANSITION_TIME,
onComplete: this._onFocusChanged.bind(this)
onComplete: () => {
Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
}
});
},
@@ -168,17 +117,6 @@ var CloseDialog = new Lang.Class({
if (this._dialog == null)
return;
Meta.enable_unredirect_for_screen(global.screen);
GLib.source_remove(this._timeoutId);
this._timeoutId = 0;
global.display.disconnect(this._windowFocusChangedId)
this._windowFocusChangedId = 0;
global.stage.disconnect(this._keyFocusChangedId);
this._keyFocusChangedId = 0;
let dialog = this._dialog;
this._dialog = null;
this._removeWindowEffect();

View File

@@ -210,10 +210,6 @@ var AutomountManager = new Lang.Class({
},
_onVolumeRemoved(monitor, volume) {
if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
Mainloop.source_remove(volume._allowAutorunExpireId);
delete volume._allowAutorunExpireId;
}
this._volumeQueue =
this._volumeQueue.filter(element => (element != volume));
},
@@ -238,10 +234,8 @@ var AutomountManager = new Lang.Class({
_allowAutorunExpire(volume) {
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
volume.allowAutorun = false;
delete volume._allowAutorunExpireId;
return GLib.SOURCE_REMOVE;
});
volume._allowAutorunExpireId = id;
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
}
});

View File

@@ -655,7 +655,7 @@ var NetworkAgent = new Lang.Class({
switch (connectionType) {
case '802-11-wireless':
let wirelessSetting = connection.get_setting_wireless();
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
title = _("Authentication required by wireless network");
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
break;

View File

@@ -201,9 +201,7 @@ var AuthenticationDialog = new Lang.Class({
close(timestamp) {
this.parent(timestamp);
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
Main.sessionMode.disconnect(this._sessionUpdatedId);
},
_ensureOpen() {

View File

@@ -52,8 +52,6 @@ var DashItemContainer = new Lang.Class({
this.animatingOut = false;
this.connect('destroy', () => {
if (this.child != null)
this.child.destroy();
this.label.destroy();
});
},

View File

@@ -183,7 +183,7 @@ var MessageDialogContent = new Lang.Class({
this[`_${prop}`].add_style_class_name(`message-dialog-${prop}`);
});
let textProps = { ellipsize: Pango.EllipsizeMode.NONE,
let textProps = { ellipsize_mode: Pango.EllipsizeMode.NONE,
line_wrap: true };
Object.assign(this._subtitle.clutter_text, textProps);
Object.assign(this._body.clutter_text, textProps);

View File

@@ -125,16 +125,6 @@ var _Draggable = new Lang.Class({
},
_onTouchEvent(actor, event) {
// Here we only handle touch events on wayland. On X11
// we do get emulated pointer events, which already works
// for single-touch cases. Besides, the X11 passive touch grab
// set up by Mutter will make us see first the touch events
// and later the pointer events, so it will look like two
// unrelated series of events, we want to avoid double handling
// in these cases.
if (!Meta.is_wayland_compositor())
return Clutter.EVENT_PROPAGATE;
if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE;
@@ -406,15 +396,10 @@ var _Draggable = new Lang.Class({
return true;
},
_pickTargetActor() {
return this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
},
_updateDragHover() {
this._updateHoverId = 0;
let target = this._pickTargetActor();
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
let dragEvent = {
x: this._dragX,
y: this._dragY,
@@ -422,18 +407,6 @@ var _Draggable = new Lang.Class({
source: this.actor._delegate,
targetActor: target
};
let targetActorDestroyHandlerId;
let handleTargetActorDestroyClosure;
handleTargetActorDestroyClosure = () => {
target = this._pickTargetActor();
dragEvent.targetActor = target;
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
};
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
for (let i = 0; i < dragMonitors.length; i++) {
let motionFunc = dragMonitors[i].dragMotion;
if (motionFunc) {
@@ -444,7 +417,6 @@ var _Draggable = new Lang.Class({
}
}
}
dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
while (target) {
if (target._delegate && target._delegate.handleDragOver) {

View File

@@ -760,7 +760,7 @@ var EndSessionDialog = new Lang.Class({
let updatePrepared = this._pkOfflineProxy.UpdatePrepared;
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || '');
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText);
this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
this._checkBox.actor.checked = (updatePrepared && updateTriggered);

View File

@@ -76,7 +76,6 @@ function disableExtension(uuid) {
if (extension.stylesheet) {
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.unload_stylesheet(extension.stylesheet);
delete extension.stylesheet;
}
try {
@@ -116,18 +115,13 @@ function enableExtension(uuid) {
extensionOrder.push(uuid);
let stylesheetNames = [global.session_mode + '.css', 'stylesheet.css'];
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (let i = 0; i < stylesheetNames.length; i++) {
try {
let stylesheetFile = extension.dir.get_child(stylesheetNames[i]);
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);
extension.stylesheet = stylesheetFile;
break;
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
continue; // not an error
log(`Failed to load stylesheet for extension ${uuid}: ${e.message}`);
return;
}
}
@@ -137,10 +131,6 @@ function enableExtension(uuid) {
_signals.emit('extension-state-changed', extension);
return;
} catch(e) {
if (extension.stylesheet) {
theme.unload_stylesheet(extension.stylesheet);
delete extension.stylesheet;
}
logExtensionError(uuid, e);
return;
}

View File

@@ -166,7 +166,7 @@ var CandidatePopup = new Lang.Class({
this._panelService.cursor_down();
});
this._candidateArea.connect('candidate-clicked', () => {
this._candidateArea.connect('candidate-clicked', (area, index, button, state) => {
this._panelService.candidate_clicked(index, button, state);
});

View File

@@ -418,11 +418,6 @@ var IconGrid = new Lang.Class({
},
_animationDone() {
this._clonesAnimating.forEach(clone => {
clone.source.reactive = true;
clone.source.opacity = 255;
clone.destroy();
});
this._clonesAnimating = [];
this.emit('animation-done');
},
@@ -543,6 +538,10 @@ var IconGrid = new Lang.Class({
onComplete: () => {
if (isLastItem)
this._animationDone();
actor.opacity = 255;
actor.reactive = true;
actorClone.destroy();
}};
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
transition: 'easeInOutQuad',
@@ -563,8 +562,12 @@ var IconGrid = new Lang.Class({
scale_x: scaleX,
scale_y: scaleY,
onComplete: () => {
if (isLastItem)
if (isLastItem) {
this._animationDone();
this._restoreItemsOpacity();
}
actor.reactive = true;
actorClone.destroy();
}};
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
transition: 'easeInOutQuad',
@@ -578,6 +581,12 @@ var IconGrid = new Lang.Class({
}
},
_restoreItemsOpacity() {
for (let index = 0; index < this._items.length; index++) {
this._items[index].actor.opacity = 255;
}
},
_getAllocatedChildSizeAndSpacing(child) {
let [,, natWidth, natHeight] = child.get_preferred_size();
let width = Math.min(this._getHItemSize(), natWidth);

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const FocusCaretTracker = imports.ui.focusCaretTracker;
const Atspi = imports.gi.Atspi;
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
@@ -12,7 +13,6 @@ const Signals = imports.signals;
const St = imports.gi.St;
const InputSourceManager = imports.ui.status.keyboard;
const IBusManager = imports.misc.ibusManager;
const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
@@ -261,7 +261,6 @@ var Key = new Lang.Class({
this._extended_keyboard = null;
this._pressTimeoutId = 0;
this._capturedPress = false;
this._capturedEventId = 0;
this._unmapId = 0;
this._longPress = false;
@@ -485,79 +484,6 @@ var KeyboardModel = new Lang.Class({
}
});
var FocusTracker = new Lang.Class({
Name: 'FocusTracker',
_init() {
this._currentWindow = null;
this._currentWindowPositionId = 0;
global.screen.get_display().connect('notify::focus-window', () => {
this._setCurrentWindow(global.screen.get_display().focus_window);
this.emit('window-changed', this._currentWindow);
});
/* Valid for wayland clients */
Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
let newRect = { x: rect.get_x(), y: rect.get_y(), width: rect.get_width(), height: rect.get_height() };
this._setCurrentRect(newRect);
});
this._ibusManager = IBusManager.getIBusManager();
this._ibusManager.connect('set-cursor-location', (manager, rect) => {
/* Valid for X11 clients only */
if (Main.inputMethod.currentFocus)
return;
this._setCurrentRect(rect);
});
},
get currentWindow() {
return this._currentWindow;
},
_setCurrentWindow(window) {
if (this._currentWindow)
this._currentWindow.disconnect(this._currentWindowPositionId);
this._currentWindow = window;
if (window) {
this._currentWindowPositionId = this._currentWindow.connect('position-changed', () => {
if (global.display.get_grab_op() == Meta.GrabOp.NONE)
this.emit('position-changed');
else
this.emit('reset');
});
}
},
_setCurrentRect(rect) {
if (this._currentWindow) {
let frameRect = this._currentWindow.get_frame_rect();
rect.x -= frameRect.x;
rect.y -= frameRect.y;
}
this._rect = rect;
this.emit('position-changed');
},
getCurrentRect() {
let rect = { x: this._rect.x, y: this._rect.y,
width: this._rect.width, height: this._rect.height };
if (this._currentWindow) {
let frameRect = this._currentWindow.get_frame_rect();
rect.x += frameRect.x;
rect.y += frameRect.y;
}
return rect;
}
});
Signals.addSignalMethods(FocusTracker.prototype);
var Keyboard = new Lang.Class({
Name: 'Keyboard',
@@ -565,10 +491,15 @@ var Keyboard = new Lang.Class({
this.actor = null;
this._focusInExtendedKeys = false;
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
this._focusCaretTracker.connect('focus-changed', this._onFocusChanged.bind(this));
this._focusCaretTracker.connect('caret-moved', this._onCaretMoved.bind(this));
this._languagePopup = null;
this._currentAccessible = null;
this._caretTrackingEnabled = false;
this._updateCaretPositionId = 0;
this._currentFocusWindow = null;
this._animFocusedWindow = null;
this._delayedAnimFocusWindow = null;
this._originalWindowY = null;
this._enableKeyboard = false; // a11y settings value
this._enabled = false; // enabled state (by setting or device type)
@@ -579,14 +510,6 @@ var Keyboard = new Lang.Class({
this._lastDeviceId = null;
this._suggestions = null;
this._focusTracker = new FocusTracker();
this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
this._focusTracker.connect('reset', () => {
this._delayedAnimFocusWindow = null;
this._animFocusedWindow = null;
this._oskFocusWindow = null;
});
Meta.get_backend().connect('last-device-changed',
(backend, deviceId) => {
let manager = Clutter.DeviceManager.get_default();
@@ -609,15 +532,102 @@ var Keyboard = new Lang.Class({
this._keyboardRestingId = 0;
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
//Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
// if (this._keyboardVisible) {
// let currentWindow = global.screen.get_display().focus_window;
// this.setCursorLocation(currentWindow, rect.get_x(), rect.get_y(),
// rect.get_width(), rect.get_height());
// }
//});
},
get visible() {
return this._keyboardVisible;
},
_onFocusPositionChanged(focusTracker) {
let rect = focusTracker.getCurrentRect();
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
_setCaretTrackerEnabled(enabled) {
if (this._caretTrackingEnabled == enabled)
return;
this._caretTrackingEnabled = enabled;
if (enabled) {
this._focusCaretTracker.registerFocusListener();
this._focusCaretTracker.registerCaretListener();
} else {
this._focusCaretTracker.deregisterFocusListener();
this._focusCaretTracker.deregisterCaretListener();
}
},
_updateCaretPosition(accessible) {
if (this._updateCaretPositionId)
GLib.source_remove(this._updateCaretPositionId);
if (!this._keyboardRequested)
return;
this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
this._updateCaretPositionId = 0;
let currentWindow = global.screen.get_display().focus_window;
if (!currentWindow) {
this.setCursorLocation(null);
return GLib.SOURCE_REMOVE;
}
let windowRect = currentWindow.get_frame_rect();
let text = accessible.get_text_iface();
let component = accessible.get_component_iface();
try {
let caretOffset = text.get_caret_offset();
let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW);
let focusRect = component.get_extents(Atspi.CoordType.WINDOW);
if (caretRect.width == 0 && caretRect.height == 0)
caretRect = focusRect;
this.setCursorLocation(currentWindow, caretRect.x, caretRect.y, caretRect.width, caretRect.height);
} catch (e) {
log('Error updating caret position for OSK: ' + e.message);
}
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition');
},
_focusIsTextEntry(accessible) {
try {
let role = accessible.get_role();
let stateSet = accessible.get_state_set();
return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL;
} catch (e) {
log('Error determining accessible role: ' + e.message);
return false;
}
},
_onFocusChanged(caretTracker, event) {
let accessible = event.source;
if (!this._focusIsTextEntry(accessible))
return;
let focused = event.detail1 != 0;
if (focused) {
this._currentAccessible = accessible;
this._updateCaretPosition(accessible);
this.show(Main.layoutManager.focusIndex);
} else if (this._currentAccessible == accessible) {
this._currentAccessible = null;
this.hide();
}
},
_onCaretMoved(caretTracker, event) {
let accessible = event.source;
if (this._currentAccessible == accessible)
this._updateCaretPosition(accessible);
},
_lastDeviceIsTouchscreen() {
@@ -640,6 +650,8 @@ var Keyboard = new Lang.Class({
if (!this._enabled && !this._keyboardController)
return;
this._setCaretTrackerEnabled(this._enabled);
if (this._enabled && !this._keyboardController)
this._setupKeyboard();
else if (!this._enabled)
@@ -924,11 +936,9 @@ var Keyboard = new Lang.Class({
},
_relayout() {
let monitor = Main.layoutManager.keyboardMonitor;
if (this.actor == null || monitor == null)
if (this.actor == null)
return;
let monitor = Main.layoutManager.keyboardMonitor;
let maxHeight = monitor.height / 3;
this.actor.width = monitor.width;
this.actor.height = maxHeight;
@@ -1017,14 +1027,11 @@ var Keyboard = new Lang.Class({
if (!this._keyboardRequested)
return;
if (this._currentAccessible)
this._updateCaretPosition(this._currentAccessible);
Main.layoutManager.keyboardIndex = monitor;
this._relayout();
Main.layoutManager.showKeyboard();
if (this._delayedAnimFocusWindow) {
this._setAnimationWindow(this._delayedAnimFocusWindow);
this._delayedAnimFocusWindow = null;
}
},
hide() {
@@ -1095,9 +1102,8 @@ var Keyboard = new Lang.Class({
window.move_frame(true, frameRect.x, frameRect.y);
},
_animateWindow(window, show) {
_animateWindow(window, show, deltaY) {
let windowActor = window.get_compositor_private();
let deltaY = Main.layoutManager.keyboardBox.height;
if (!windowActor)
return;
@@ -1118,39 +1124,35 @@ var Keyboard = new Lang.Class({
}
},
_setAnimationWindow(window) {
if (this._animFocusedWindow == window)
setCursorLocation(window, x, y , w, h) {
if (window == this._oskFocusWindow)
return;
if (this._animFocusedWindow)
this._animateWindow(this._animFocusedWindow, false);
if (window)
this._animateWindow(window, true);
if (this._oskFocusWindow) {
let display = global.screen.get_display();
this._animFocusedWindow = window;
},
if (display.get_grab_op() == Meta.GrabOp.NONE ||
display.get_focus_window() != this._oskFocusWindow)
this._animateWindow(this._oskFocusWindow, false, this._oskFocusWindowDelta);
setCursorLocation(window, x, y , w, h) {
let monitor = Main.layoutManager.keyboardMonitor;
if (window && monitor) {
let keyboardHeight = Main.layoutManager.keyboardBox.height;
let focusObscured = false;
if (y + h >= monitor.y + monitor.height - keyboardHeight) {
if (this._keyboardVisible)
this._setAnimationWindow(window);
else
this._delayedAnimFocusWindow = window;
} else if (y < keyboardHeight) {
this._delayedAnimFocusWindow = null;
this._setAnimationWindow(null);
}
} else {
this._setAnimationWindow(null);
this._oskFocusWindow = null;
this._oskFocusWindowDelta = null;
}
this._oskFocusWindow = window;
if (window) {
let monitor = Main.layoutManager.keyboardMonitor;
let keyboardHeight = Main.layoutManager.keyboardBox.height;
let frameRect = window.get_frame_rect();
let windowActor = window.get_compositor_private();
let delta = 0;
if (frameRect.y + y + h >= monitor.height - keyboardHeight)
delta = keyboardHeight;
this._animateWindow(window, true, delta);
this._oskFocusWindow = window;
this._oskFocusWindowDelta = delta;
}
},
});

View File

@@ -203,7 +203,6 @@ var LayoutManager = new Lang.Class({
// Set up stage hierarchy to group all UI actors under one container.
this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
this.uiGroup.set_flags(Clutter.ActorFlags.NO_LAYOUT);
this.uiGroup.connect('allocate', (actor, box, flags) => {
let children = actor.get_children();
for (let i = 0; i < children.length; i++)
@@ -558,8 +557,6 @@ var LayoutManager = new Lang.Class({
},
get focusMonitor() {
if (this.focusIndex < 0)
return null;
return this.monitors[this.focusIndex];
},

View File

@@ -19,6 +19,7 @@ const MagnifierDBus = imports.ui.magnifierDBus;
const Params = imports.misc.params;
const PointerWatcher = imports.ui.pointerWatcher;
var MOUSE_POLL_FREQUENCY = 50;
var CROSSHAIRS_CLIP_SIZE = [100, 100];
var NO_CHANGE = 0.0;
@@ -151,10 +152,8 @@ var Magnifier = new Lang.Class({
* Turn on mouse tracking, if not already doing so.
*/
startTrackingMouse() {
if (!this._pointerWatch) {
let interval = 1000 / Clutter.get_default_frame_rate();
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
}
if (!this._pointerWatch)
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(MOUSE_POLL_FREQUENCY, this.scrollToMousePos.bind(this));
},
/**

View File

@@ -343,9 +343,6 @@ function loadTheme() {
let theme = new St.Theme ({ application_stylesheet: _cssStylesheet,
default_stylesheet: _defaultCssStylesheet });
if (theme.default_stylesheet == null)
throw new Error("No valid stylesheet found for '%s'".format(sessionMode.stylesheetName));
if (previousTheme) {
let customStylesheets = previousTheme.get_custom_stylesheets();

View File

@@ -362,8 +362,7 @@ var Message = new Lang.Class({
this.setBody(body);
this._closeButton.connect('clicked', this.close.bind(this));
let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this));
this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId));
this.actor.connect('notify::hover', this._sync.bind(this));
this.actor.connect('clicked', this._onClicked.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this._sync();

View File

@@ -1320,7 +1320,6 @@ var MessageTray = new Lang.Class({
this._bannerBin.y = -this._banner.actor.height;
this.actor.show();
Meta.disable_unredirect_for_screen(global.screen);
this._updateShowingNotification();
let [x, y, mods] = global.get_pointer();
@@ -1458,7 +1457,6 @@ var MessageTray = new Lang.Class({
this._pointerInNotification = false;
this._notificationRemoved = false;
Meta.enable_unredirect_for_screen(global.screen);
this._banner.actor.destroy();
this._banner = null;

View File

@@ -117,8 +117,10 @@ var FdoNotificationDaemon = new Lang.Class({
bitsPerSample, nChannels, data] = hints['image-data'];
return Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
bitsPerSample, width, height, rowStride);
} else if (hints['image-path']) {
return new Gio.FileIcon({ file: Gio.File.new_for_path(hints['image-path']) });
}
return this._iconForNotificationData(hints['image-path']);
return null;
},
_fallbackIconForNotificationData(hints) {

View File

@@ -108,30 +108,15 @@ var OsdWindow = new Lang.Class({
this._hideTimeoutId = 0;
this._reset();
this.actor.connect('destroy', this._onDestroy.bind(this));
this._monitorsChangedId =
Main.layoutManager.connect('monitors-changed',
this._relayout.bind(this));
Main.layoutManager.connect('monitors-changed',
this._relayout.bind(this));
let themeContext = St.ThemeContext.get_for_stage(global.stage);
this._scaleChangedId =
themeContext.connect('notify::scale-factor',
this._relayout.bind(this));
themeContext.connect('notify::scale-factor',
this._relayout.bind(this));
this._relayout();
Main.uiGroup.add_child(this.actor);
},
_onDestroy() {
if (this._monitorsChangedId)
Main.layoutManager.disconnect(this._monitorsChangedId);
this._monitorsChangedId = 0;
let themeContext = St.ThemeContext.get_for_stage(global.stage);
if (this._scaleChangedId)
themeContext.disconnect(this._scaleChangedId);
this._scaleChangedId = 0;
},
setIcon(icon) {
this._icon.gicon = icon;
},
@@ -219,7 +204,7 @@ var OsdWindow = new Lang.Class({
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._icon.icon_size = popupSize / (2 * scaleFactor);
this._box.translation_y = Math.round(monitor.height / 4);
this._box.translation_y = monitor.height / 4;
this._boxConstraint.minSize = popupSize;
}
});

View File

@@ -393,8 +393,10 @@ var Overview = new Lang.Class({
if (!Main.layoutManager.primaryMonitor)
return;
this._coverPane.set_position(0, 0);
this._coverPane.set_size(global.screen_width, global.screen_height);
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
this._coverPane.set_position(0, workArea.y);
this._coverPane.set_size(workArea.width, workArea.height);
this._updateBackgrounds();
},

View File

@@ -284,11 +284,6 @@ var ThumbnailsSlider = new Lang.Class({
return child.get_theme_node().get_length('visible-width');
},
_onDragEnd() {
this.actor.sync_hover();
this.parent();
},
_getSlide() {
if (!this._visible)
return 0;

View File

@@ -796,7 +796,6 @@ var Panel = new Lang.Class({
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
this.actor.connect('allocate', this._allocate.bind(this));
this.actor.connect('button-press-event', this._onButtonPress.bind(this));
this.actor.connect('touch-event', this._onButtonPress.bind(this));
this.actor.connect('key-press-event', this._onKeyPress.bind(this));
Main.overview.connect('showing', () => {
@@ -940,13 +939,8 @@ var Panel = new Lang.Class({
if (event.get_source() != actor)
return Clutter.EVENT_PROPAGATE;
let type = event.type();
let isPress = type == Clutter.EventType.BUTTON_PRESS;
if (!isPress && type != Clutter.EventType.TOUCH_BEGIN)
return Clutter.EVENT_PROPAGATE;
let button = isPress ? event.get_button() : -1;
if (isPress && button != 1)
let button = event.get_button();
if (button != 1)
return Clutter.EVENT_PROPAGATE;
let focusWindow = global.display.focus_window;
@@ -1085,7 +1079,6 @@ var Panel = new Lang.Class({
let windows = activeWorkspace.list_windows().filter(metaWindow => {
return metaWindow.is_on_primary_monitor() &&
metaWindow.showing_on_its_workspace() &&
!metaWindow.is_hidden() &&
metaWindow.get_window_type() != Meta.WindowType.DESKTOP;
});

View File

@@ -141,17 +141,8 @@ var PopupBaseMenuItem = new Lang.Class({
},
_onKeyPressEvent(actor, event) {
let state = event.get_state();
// if user has a modifier down (except capslock)
// then don't handle the key press here
state &= ~Clutter.ModifierType.LOCK_MASK;
state &= Clutter.ModifierType.MODIFIER_MASK;
if (state)
return Clutter.EVENT_PROPAGATE;
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.activate(event);
return Clutter.EVENT_STOP;

View File

@@ -119,6 +119,9 @@ var RemoteMenuItemMapper = new Lang.Class({
this._trackerItem = trackerItem;
this.menuItem = new PopupMenu.PopupBaseMenuItem();
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
this.menuItem.actor.add_child(this._icon);
this._label = new St.Label();
this.menuItem.actor.add_child(this._label);
this.menuItem.actor.label_actor = this._label;
@@ -129,11 +132,13 @@ var RemoteMenuItemMapper = new Lang.Class({
this._trackerItem.bind_property('visible', this.menuItem.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
this._trackerItem.connect('notify::icon', this._updateIcon.bind(this));
this._trackerItem.connect('notify::label', this._updateLabel.bind(this));
this._trackerItem.connect('notify::sensitive', this._updateSensitivity.bind(this));
this._trackerItem.connect('notify::role', this._updateRole.bind(this));
this._trackerItem.connect('notify::toggled', this._updateDecoration.bind(this));
this._updateIcon();
this._updateLabel();
this._updateSensitivity();
this._updateRole();
@@ -143,6 +148,11 @@ var RemoteMenuItemMapper = new Lang.Class({
});
},
_updateIcon() {
this._icon.gicon = this._trackerItem.icon;
this._icon.visible = (this._icon.gicon != null);
},
_updateLabel() {
this._label.text = stripMnemonics(this._trackerItem.label);
},

View File

@@ -295,7 +295,7 @@ var RemoteSearchProvider = new Lang.Class({
name: metas[i]['name'],
description: metas[i]['description'],
createIcon: size => {
return this.createIcon(size, metas[i]);
this.createIcon(size, metas[i]);
},
clipboardText: metas[i]['clipboardText'] });
}

View File

@@ -114,16 +114,18 @@ var RunDialog = new Lang.Class({
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
entry: this._entryText });
this._entryText.connect('activate', (o) => {
this.popModal();
this._run(o.get_text(),
Clutter.get_current_event().get_state() & Clutter.ModifierType.CONTROL_MASK);
if (!this._commandError ||
!this.pushModal())
this.close();
});
this._entryText.connect('key-press-event', (o, e) => {
let symbol = e.get_key_symbol();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
this.popModal();
this._run(o.get_text(),
e.get_state() & Clutter.ModifierType.CONTROL_MASK);
if (!this._commandError ||
!this.pushModal())
this.close();
return Clutter.EVENT_STOP;
}
if (symbol == Clutter.Tab) {
let text = o.get_text();
let prefix;

View File

@@ -192,7 +192,6 @@ var SearchResultsBase = new Lang.Class({
},
clear() {
this._cancellable.cancel();
for (let resultId in this._resultDisplays)
this._resultDisplays[resultId].actor.destroy();
this._resultDisplays = {};
@@ -226,12 +225,6 @@ var SearchResultsBase = new Lang.Class({
this._cancellable.reset();
this.provider.getResultMetas(metasNeeded, metas => {
if (this._cancellable.is_cancelled()) {
if (metas.length > 0)
log(`Search provider ${this.provider.id} returned results after the request was canceled`);
callback(false);
return;
}
if (metas.length != metasNeeded.length) {
log('Wrong number of result metas returned by search provider ' + this.provider.id +
': expected ' + metasNeeded.length + ' but got ' + metas.length);

View File

@@ -360,14 +360,11 @@ var InputSourceManager = new Lang.Class({
this._settings.connect('per-window-changed', this._sourcesPerWindowChanged.bind(this));
this._sourcesPerWindowChanged();
this._disableIBus = false;
this._reloading = false;
},
reload() {
this._reloading = true;
this._keyboardManager.setKeyboardOptions(this._settings.keyboardOptions);
this._inputSourcesChanged();
this._reloading = false;
},
_ibusReadyCallback(im, ready) {
@@ -461,15 +458,7 @@ var InputSourceManager = new Lang.Class({
},
activateInputSource(is, interactive) {
// The focus changes during holdKeyboard/releaseKeyboard may trick
// the client into hiding UI containing the currently focused entry.
// So holdKeyboard/releaseKeyboard are not called when
// 'set-content-type' signal is received.
// E.g. Focusing on a password entry in a popup in Xorg Firefox
// will emit 'set-content-type' signal.
// https://gitlab.gnome.org/GNOME/gnome-shell/issues/391
if (!this._reloading)
KeyboardManager.holdKeyboard();
KeyboardManager.holdKeyboard();
this._keyboardManager.apply(is.xkbId);
// All the "xkb:..." IBus engines simply "echo" back symbols,
@@ -484,10 +473,7 @@ var InputSourceManager = new Lang.Class({
else
engine = 'xkb:us::eng';
if (!this._reloading)
this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard);
else
this._ibusManager.setEngine(engine);
this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard);
this._currentInputSourceChanged(is);
if (interactive)

View File

@@ -419,14 +419,12 @@ var NMConnectionDevice = new Lang.Class({
this._deactivateItem.actor.visible = this._device.state > NM.DeviceState.DISCONNECTED;
if (this._activeConnection == null) {
let activeConnection = this._device.active_connection;
if (activeConnection && activeConnection.connection) {
let item = this._connectionItems.get(activeConnection.connection.get_uuid());
if (item) {
this._activeConnection = activeConnection;
ensureActiveConnectionProps(this._activeConnection, this._client);
item.setActiveConnection(this._activeConnection);
}
this._activeConnection = this._device.active_connection;
if (this._activeConnection) {
ensureActiveConnectionProps(this._activeConnection, this._client);
let item = this._connectionItems.get(this._activeConnection.connection.get_uuid());
item.setActiveConnection(this._activeConnection);
}
}
@@ -1946,7 +1944,6 @@ var NMApplet = new Lang.Class({
this.indicators.visible = this._client.nm_running;
this.menu.actor.visible = this._client.networking_enabled;
this._updateIcon();
this._syncConnectivity();
},

View File

@@ -58,9 +58,6 @@ var AltSwitcher = new Lang.Class({
childToShow = this._standard;
} else if (this._alternate.visible) {
childToShow = this._alternate;
} else {
this.actor.hide();
return;
}
let childShown = this.actor.get_child();
@@ -82,7 +79,7 @@ var AltSwitcher = new Lang.Class({
global.sync_pointer();
}
this.actor.show();
this.actor.visible = (childToShow != null);
},
_onDestroy() {

View File

@@ -354,7 +354,7 @@ var Indicator = new Lang.Class({
_onEnrollFailed(obj, device, error) {
const title = _('Thunderbolt authorization error');
const body = _('Could not authorize the thunderbolt device: %s'.format(error.message));
const body = _('Could not authorize the Thunderbolt device: %s'.format(error.message));
this._notify(title, body);
}

View File

@@ -311,7 +311,6 @@ var ViewSelector = new Lang.Class({
},
hide() {
this.reset();
this._workspacesDisplay.hide();
},
@@ -460,11 +459,7 @@ var ViewSelector = new Lang.Class({
},
reset() {
// Don't drop the key focus on Clutter's side if anything but the
// overview has pushed a modal (e.g. system modals when activated using
// the overview).
if (Main.modalCount <= 1)
global.stage.set_key_focus(null);
global.stage.set_key_focus(null);
this._entry.text = '';

View File

@@ -24,7 +24,7 @@ const EdgeDragAction = imports.ui.edgeDragAction;
const CloseDialog = imports.ui.closeDialog;
const SwitchMonitor = imports.ui.switchMonitor;
var SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
var MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
var SHOW_WINDOW_ANIMATION_TIME = 0.15;
var DIALOG_SHOW_WINDOW_ANIMATION_TIME = 0.1;
@@ -627,8 +627,8 @@ var AppSwitchAction = new Lang.Class({
if (this.get_n_current_points() == 3) {
for (let i = 0; i < this.get_n_current_points(); i++) {
let [startX, startY] = this.get_press_coords(i);
let [x, y] = this.get_motion_coords(i);
[startX, startY] = this.get_press_coords(i);
[x, y] = this.get_motion_coords(i);
if (Math.abs(x - startX) > MOTION_THRESHOLD ||
Math.abs(y - startY) > MOTION_THRESHOLD)
@@ -1173,10 +1173,6 @@ var WindowManager = new Lang.Class({
yScale = geom.height / actor.height;
} else {
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
if (!monitor) {
this._minimizeWindowDone();
return;
}
xDest = monitor.x;
yDest = monitor.y;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
@@ -1252,11 +1248,6 @@ var WindowManager = new Lang.Class({
geom.height / actor.height);
} else {
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
if (!monitor) {
actor.show();
this._unminimizeWindowDone();
return;
}
actor.set_position(monitor.x, monitor.y);
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
actor.x += monitor.width;
@@ -1763,14 +1754,6 @@ var WindowManager = new Lang.Class({
}
}
for (let i = 0; i < switchData.windows.length; i++) {
let w = switchData.windows[i];
w.windowDestroyId = w.window.connect('destroy', () => {
switchData.windows.splice(switchData.windows.indexOf(w), 1);
});
}
switchData.inGroup.set_position(-xDest, -yDest);
switchData.inGroup.raise_top();
@@ -1801,8 +1784,8 @@ var WindowManager = new Lang.Class({
for (let i = 0; i < switchData.windows.length; i++) {
let w = switchData.windows[i];
w.window.disconnect(w.windowDestroyId);
if (w.window.is_destroyed()) // Window gone
continue;
if (w.window.get_parent() == switchData.outGroup) {
w.window.reparent(w.parent);
w.window.hide();

View File

@@ -128,10 +128,11 @@ var WindowMenu = new Lang.Class({
let screen = global.screen;
let nMonitors = screen.get_n_monitors();
let monitorIndex = window.get_monitor();
if (nMonitors > 1 && monitorIndex >= 0) {
if (nMonitors > 1) {
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
let monitorIndex = window.get_monitor();
let dir = Meta.ScreenDirection.UP;
let upMonitorIndex =
screen.get_monitor_neighbor_index(monitorIndex, dir);

View File

@@ -137,10 +137,8 @@ var WindowClone = new Lang.Class({
this._dragSlot = [0, 0, 0, 0];
this._stackAbove = null;
this._windowClone._sizeChangedId = this.metaWindow.connect('size-changed',
this._onMetaWindowSizeChanged.bind(this));
this._windowClone._posChangedId = this.metaWindow.connect('position-changed',
this._computeBoundingBox.bind(this));
this._windowClone._updateId = this.metaWindow.connect('size-changed',
this._onRealWindowSizeChanged.bind(this));
this._windowClone._destroyId =
this.realWindow.connect('destroy', () => {
// First destroy the clone and then destroy everything
@@ -208,7 +206,8 @@ var WindowClone = new Lang.Class({
addAttachedDialog(win) {
this._doAddAttachedDialog(win, win.get_compositor_private());
this._onMetaWindowSizeChanged();
this._computeBoundingBox();
this.emit('size-changed');
},
hasAttachedDialogs() {
@@ -217,14 +216,15 @@ var WindowClone = new Lang.Class({
_doAddAttachedDialog(metaWin, realWin) {
let clone = new Clutter.Clone({ source: realWin });
clone._sizeChangedId = metaWin.connect('size-changed',
this._onMetaWindowSizeChanged.bind(this));
clone._posChangedId = metaWin.connect('position-changed',
this._onMetaWindowSizeChanged.bind(this));
clone._updateId = metaWin.connect('size-changed', () => {
this._computeBoundingBox();
this.emit('size-changed');
});
clone._destroyId = realWin.connect('destroy', () => {
clone.destroy();
this._onMetaWindowSizeChanged();
this._computeBoundingBox();
this.emit('size-changed');
});
this.actor.add_child(clone);
},
@@ -321,13 +321,12 @@ var WindowClone = new Lang.Class({
else
realWindow = child.source;
realWindow.meta_window.disconnect(child._sizeChangedId);
realWindow.meta_window.disconnect(child._posChangedId);
realWindow.meta_window.disconnect(child._updateId);
realWindow.disconnect(child._destroyId);
});
},
_onMetaWindowSizeChanged() {
_onRealWindowSizeChanged() {
this._computeBoundingBox();
this.emit('size-changed');
},
@@ -470,6 +469,7 @@ var WindowOverlay = new Lang.Class({
this._windowAddedId = 0;
button.hide();
title.hide();
this.title = title;
this.closeButton = button;
@@ -544,10 +544,12 @@ var WindowOverlay = new Lang.Class({
let titleX = cloneX + (cloneWidth - title.width) / 2;
let titleY = cloneY + cloneHeight - (title.height - this.borderSize) / 2;
if (animate)
this._animateOverlayActor(title, Math.floor(titleX), Math.floor(titleY));
else
if (animate) {
this._animateOverlayActor(title, Math.floor(titleX), Math.floor(titleY), title.width);
} else {
title.width = title.width;
title.set_position(Math.floor(titleX), Math.floor(titleY));
}
let borderX = cloneX - this.borderSize;
let borderY = cloneY - this.borderSize;
@@ -566,12 +568,10 @@ var WindowOverlay = new Lang.Class({
_animateOverlayActor(actor, x, y, width, height) {
let params = { x: x,
y: y,
width: width,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' };
if (width !== undefined)
params.width = width;
if (height !== undefined)
params.height = height;
@@ -1431,26 +1431,34 @@ var Workspace = new Lang.Class({
_doRemoveWindow(metaWin) {
let win = metaWin.get_compositor_private();
let clone = this._removeWindowClone(metaWin);
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (clone) {
// If metaWin.get_compositor_private() returned non-NULL, that
// means the window still exists (and is just being moved to
// another workspace or something), so set its overviewHint
// accordingly. (If it returned NULL, then the window is being
// destroyed; we'd like to animate this, but it's too late at
// this point.)
if (win) {
let [stageX, stageY] = clone.actor.get_transformed_position();
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
win._overviewHint = {
x: stageX,
y: stageY,
scale: stageWidth / clone.actor.width
};
}
clone.destroy();
if (index == -1)
return;
let clone = this._windows[index];
this._windows.splice(index, 1);
this._windowOverlays.splice(index, 1);
// If metaWin.get_compositor_private() returned non-NULL, that
// means the window still exists (and is just being moved to
// another workspace or something), so set its overviewHint
// accordingly. (If it returned NULL, then the window is being
// destroyed; we'd like to animate this, but it's too late at
// this point.)
if (win) {
let [stageX, stageY] = clone.actor.get_transformed_position();
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
win._overviewHint = {
x: stageX,
y: stageY,
scale: stageWidth / clone.actor.width
};
}
clone.destroy();
// We need to reposition the windows; to avoid shuffling windows
// around while the user is interacting with the workspace, we delay
@@ -1506,7 +1514,7 @@ var Workspace = new Lang.Class({
if (metaWin.is_attached_dialog()) {
let parent = metaWin.get_transient_for();
while (parent.is_attached_dialog())
parent = parent.get_transient_for();
parent = metaWin.get_transient_for();
let idx = this._lookupIndex (parent);
if (idx < 0) {
@@ -1840,9 +1848,6 @@ var Workspace = new Lang.Class({
clone.connect('size-changed', () => {
this._recalculateWindowPositions(WindowPositionFlags.NONE);
});
clone.actor.connect('destroy', () => {
this._removeWindowClone(clone.metaWindow);
});
this.actor.add_actor(clone.actor);
@@ -1864,17 +1869,6 @@ var Workspace = new Lang.Class({
return [clone, overlay];
},
_removeWindowClone(metaWin) {
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (index == -1)
return null;
this._windowOverlays.splice(index, 1);
return this._windows.splice(index, 1).pop();
},
_onShowOverlayClose(windowOverlay) {
for (let i = 0; i < this._windowOverlays.length; i++) {
let overlay = this._windowOverlays[i];

View File

@@ -31,7 +31,7 @@ var WORKSPACE_CUT_SIZE = 10;
var WORKSPACE_KEEP_ALIVE_TIME = 100;
var OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
/* A layout manager that requests size only for primary_actor, but then allocates
all using a fixed layout */
@@ -68,7 +68,7 @@ var WindowClone = new Lang.Class({
this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window;
this.clone._updateId = this.realWindow.connect('notify::position',
this.clone._updateId = this.metaWindow.connect('position-changed',
this._onPositionChanged.bind(this));
this.clone._destroyId = this.realWindow.connect('destroy', () => {
// First destroy the clone and then destroy everything
@@ -153,7 +153,7 @@ var WindowClone = new Lang.Class({
let clone = new Clutter.Clone({ source: realDialog });
this._updateDialogPosition(realDialog, clone);
clone._updateId = realDialog.connect('notify::position', dialog => {
clone._updateId = metaDialog.connect('position-changed', dialog => {
this._updateDialogPosition(dialog, clone);
});
clone._destroyId = realDialog.connect('destroy', () => {
@@ -171,6 +171,7 @@ var WindowClone = new Lang.Class({
},
_onPositionChanged() {
let rect = this.metaWindow.get_frame_rect();
this.actor.set_position(this.realWindow.x, this.realWindow.y);
},
@@ -178,7 +179,7 @@ var WindowClone = new Lang.Class({
this.actor.get_children().forEach(child => {
let realWindow = child.source;
realWindow.disconnect(child._updateId);
realWindow.meta_window.disconnect(child._updateId);
realWindow.disconnect(child._destroyId);
});
},
@@ -240,7 +241,7 @@ var WindowClone = new Lang.Class({
Signals.addSignalMethods(WindowClone.prototype);
var ThumbnailState = {
const ThumbnailState = {
NEW : 0,
ANIMATING_IN : 1,
NORMAL: 2,
@@ -371,9 +372,18 @@ var WorkspaceThumbnail = new Lang.Class({
},
_doRemoveWindow(metaWin) {
let clone = this._removeWindowClone(metaWin);
if (clone)
clone.destroy();
let win = metaWin.get_compositor_private();
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (index == -1)
return;
let clone = this._windows[index];
this._windows.splice(index, 1);
clone.destroy();
},
_doAddWindow(metaWin) {
@@ -416,7 +426,7 @@ var WorkspaceThumbnail = new Lang.Class({
} else if (metaWin.is_attached_dialog()) {
let parent = metaWin.get_transient_for();
while (parent.is_attached_dialog())
parent = parent.get_transient_for();
parent = metaWin.get_transient_for();
let idx = this._lookupIndex (parent);
if (idx < 0) {
@@ -525,9 +535,6 @@ var WorkspaceThumbnail = new Lang.Class({
clone.connect('drag-end', () => {
Main.overview.endWindowDrag(clone.metaWindow);
});
clone.actor.connect('destroy', () => {
this._removeWindowClone(clone.metaWindow);
});
this._contents.add_actor(clone.actor);
if (this._windows.length == 0)
@@ -540,16 +547,6 @@ var WorkspaceThumbnail = new Lang.Class({
return clone;
},
_removeWindowClone(metaWin) {
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (index == -1)
return null;
return this._windows.splice(index, 1).pop();
},
activate(time) {
if (this.state > ThumbnailState.NORMAL)
return;
@@ -676,11 +673,7 @@ var ThumbnailsBox = new Lang.Class({
this._settings.connect('changed::dynamic-workspaces',
this._updateSwitcherVisibility.bind(this));
Main.layoutManager.connect('monitors-changed', () => {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
});
Main.layoutManager.connect('monitors-changed', this._rebuildThumbnails.bind(this));
},
_updateSwitcherVisibility() {
@@ -873,6 +866,9 @@ var ThumbnailsBox = new Lang.Class({
Main.overview.connect('windows-restacked',
this._syncStacking.bind(this));
this._workareasChangedId =
global.screen.connect('workareas-changed', this._rebuildThumbnails.bind(this));
this._targetScale = 0;
this._scale = 0;
this._pendingScaleUpdate = false;
@@ -902,12 +898,24 @@ var ThumbnailsBox = new Lang.Class({
this._syncStackingId = 0;
}
if (this._workareasChangedId > 0) {
global.screen.disconnect(this._workareasChangedId);
this._workareasChangedId = 0;
}
for (let w = 0; w < this._thumbnails.length; w++)
this._thumbnails[w].destroy();
this._thumbnails = [];
this._porthole = null;
},
_rebuildThumbnails() {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
},
_workspacesChanged() {
let validThumbnails =
this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL);

View File

@@ -470,7 +470,6 @@ var WorkspacesDisplay = new Lang.Class({
this._switchWorkspaceNotifyId = 0;
this._notifyOpacityId = 0;
this._restackedNotifyId = 0;
this._scrollEventId = 0;
this._keyPressEventId = 0;

View File

@@ -1,5 +1,5 @@
project('gnome-shell', 'c',
version: '3.28.4',
version: '3.28.1',
meson_version: '>= 0.42.0',
license: 'GPLv2+'
)

1506
po/af.po

File diff suppressed because it is too large Load Diff

View File

@@ -1064,7 +1064,7 @@ msgstr "Načítá se…"
#: js/ui/dateMenu.js:321
#, javascript-format
msgid "Feels like %s."
msgstr "Pocitová teplota %s."
msgstr "Pocitově jako %s."
#: js/ui/dateMenu.js:324
msgid "Go online for weather information"

757
po/gd.po

File diff suppressed because it is too large Load Diff

View File

@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2018-02-26 17:00+0000\n"
"PO-Revision-Date: 2018-03-07 22:46+0100\n"
"POT-Creation-Date: 2018-04-13 19:54+0000\n"
"PO-Revision-Date: 2018-04-16 14:30+0200\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <hr@li.org>\n"
"Language: hr\n"
@@ -337,7 +337,7 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "Dogodila se greška učitavanja dijaloga osobitosti za %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@@ -663,12 +663,12 @@ msgstr "Dodaj u omiljene"
msgid "Show Details"
msgstr "Prikaži pojedinosti"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s je dodan u omiljene."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s je uklonjen iz omiljenih."
@@ -863,7 +863,7 @@ msgstr "Vanjski uređaj odspojen"
msgid "Open with %s"
msgstr "Otvori s(a) %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
msgid "Password:"
msgstr "Lozinka:"
@@ -950,15 +950,15 @@ msgstr "Potrebna je lozinka za povezivanje s “%s”."
msgid "Network Manager"
msgstr "Mrežni upravitelj"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Potrebna je ovjera"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Administrator"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Ovjeri"
@@ -966,7 +966,7 @@ msgstr "Ovjeri"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Nažalost, to ne radi. Pokušajte ponovno."
@@ -1014,7 +1014,7 @@ msgstr "Dodaj satove iz svijeta…"
msgid "World Clocks"
msgstr "Svjetski satovi"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "Vrijeme"
@@ -1022,7 +1022,7 @@ msgstr "Vrijeme"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s cijeli dan."
@@ -1031,7 +1031,7 @@ msgstr "%s cijeli dan."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, zatim %s kasnije."
@@ -1040,30 +1040,30 @@ msgstr "%s, zatim %s kasnije."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, zatim %s, praćena s %s kasnije."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Odaberi lokaciju…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "Pretraživanje…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Kao da je %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Posjetite za opširnije vremenske informacije"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "Vremenske informacije su trenutno nedostupne"
@@ -1977,16 +1977,16 @@ msgstr "Suspendiraj"
msgid "Power Off"
msgstr "Isključivanje"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:294
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:350
msgid "Unknown Thunderbolt device"
msgstr "Nepoznati Thunderbolt uređaj"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:351
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@@ -1994,14 +1994,14 @@ msgstr ""
"Otkriven je novi uređaj dok ste bili odsutni. Odspojite i ponovno spojite "
"uređaj kako bi ga mogli koristiti."
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:356
msgid "Thunderbolt authorization error"
msgstr "Greška Thunderbolt ovjere"
msgstr "Greška Thunderbolt odobravanja"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:357
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgstr "Nemoguća ovjera Thunderbolt uređaja: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Nemoguće odobravanje Thunderbolt uređaja: %s"
#: js/ui/status/volume.js:128
msgid "Volume changed"

665
po/ja.po

File diff suppressed because it is too large Load Diff

View File

@@ -15,22 +15,22 @@
# Georges Basile Stavracas Neto <georges.stavracas@gmail.com>, 2014.
# Felipe Braga <fbobraga@gmail.com>, 2015.
# Artur de Aquino Morais <artur.morais93@outlook.com>, 2016.
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2018.
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2017.
# Enrico Nicoletto <liverig@gmail.com>, 2013-2018.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2018-04-13 18:31+0000\n"
"PO-Revision-Date: 2018-05-02 15:45-0200\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"POT-Creation-Date: 2018-03-16 21:34+0000\n"
"PO-Revision-Date: 2018-02-09 21:52-0200\n"
"Last-Translator: Enrico Nicoletto <liverig@gmail.com>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Virtaal 1.0.0-beta1\n"
"X-Generator: Poedit 2.0.6\n"
"X-Project-Style: gnome\n"
#: data/50-gnome-shell-system.xml:6
@@ -356,7 +356,7 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "Ocorreu um erro ao carregar o dialogo de preferências para %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@@ -642,7 +642,7 @@ msgstr "Negar acesso"
#: js/ui/accessDialog.js:64 js/ui/status/location.js:396
msgid "Grant Access"
msgstr "Conceder acesso"
msgstr "Garantir acesso"
#: js/ui/appDisplay.js:793
msgid "Frequently used applications will appear here"
@@ -676,12 +676,12 @@ msgstr "Adicionar aos favoritos"
msgid "Show Details"
msgstr "Mostrar detalhes"
#: js/ui/appFavorites.js:140
#: js/ui/appFavorites.js:138
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s foi adicionado aos seus favoritos."
#: js/ui/appFavorites.js:174
#: js/ui/appFavorites.js:172
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s foi removido dos seus favoritos."
@@ -876,7 +876,7 @@ msgstr "Unidade externa desconectada"
msgid "Open with %s"
msgstr "Abrir com %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
msgid "Password:"
msgstr "Senha:"
@@ -964,15 +964,15 @@ msgstr "Uma senha é necessária para se conectar a “%s”."
msgid "Network Manager"
msgstr "Gerenciador de rede"
#: js/ui/components/polkitAgent.js:48
#: js/ui/components/polkitAgent.js:43
msgid "Authentication Required"
msgstr "Autenticação necessária"
#: js/ui/components/polkitAgent.js:76
#: js/ui/components/polkitAgent.js:71
msgid "Administrator"
msgstr "Administrador"
#: js/ui/components/polkitAgent.js:156
#: js/ui/components/polkitAgent.js:151
msgid "Authenticate"
msgstr "Autenticação"
@@ -980,7 +980,7 @@ msgstr "Autenticação"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Desculpe, isto não funcionou. Por favor, tente novamente."
@@ -1028,7 +1028,7 @@ msgstr "Adicionar relógios mundiais…"
msgid "World Clocks"
msgstr "Relógios mundiais"
#: js/ui/dateMenu.js:227
#: js/ui/dateMenu.js:225
msgid "Weather"
msgstr "Meteorologia"
@@ -1036,7 +1036,7 @@ msgstr "Meteorologia"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:291
#: js/ui/dateMenu.js:289
#, javascript-format
msgid "%s all day."
msgstr "%s por todo o dia."
@@ -1045,7 +1045,7 @@ msgstr "%s por todo o dia."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:297
#: js/ui/dateMenu.js:295
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, depois %s mais tarde."
@@ -1054,30 +1054,30 @@ msgstr "%s, depois %s mais tarde."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:303
#: js/ui/dateMenu.js:301
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, depois %s, seguido de %s mais tarde."
#: js/ui/dateMenu.js:314
#: js/ui/dateMenu.js:312
msgid "Select a location…"
msgstr "Selecione uma localização…"
#: js/ui/dateMenu.js:317
#: js/ui/dateMenu.js:315
msgid "Loading…"
msgstr "Carregando…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:323
#: js/ui/dateMenu.js:321
#, javascript-format
msgid "Feels like %s."
msgstr "Sensação térmica de %s."
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:324
msgid "Go online for weather information"
msgstr "Conecte-se à internet para obter as informações meteorológicas"
#: js/ui/dateMenu.js:328
#: js/ui/dateMenu.js:326
msgid "Weather information is currently unavailable"
msgstr "No momento as informações meteorológicas não estão disponíveis"

View File

@@ -87,8 +87,6 @@ struct _ShellGlobal {
/* For sound notifications */
ca_context *sound_context;
GHashTable *save_ops;
gboolean has_modal;
gboolean frame_timestamps;
gboolean frame_finish_timestamp;
@@ -324,10 +322,6 @@ shell_global_init (ShellGlobal *global)
NULL);
g_strfreev (search_path);
global->save_ops = g_hash_table_new_full (g_file_hash,
(GEqualFunc) g_file_equal,
g_object_unref, g_object_unref);
}
static void
@@ -347,8 +341,6 @@ shell_global_finalize (GObject *object)
g_free (global->imagedir);
g_free (global->userdatadir);
g_hash_table_unref (global->save_ops);
G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
}
@@ -1765,77 +1757,20 @@ shell_global_get_session_mode (ShellGlobal *global)
}
static void
delete_variant_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
ShellGlobal *global = user_data;
GError *error = NULL;
if (!g_file_delete_finish (G_FILE (object), result, &error))
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
g_warning ("Could not delete runtime/persistent state file: %s\n",
error->message);
}
g_error_free (error);
}
g_hash_table_remove (global->save_ops, object);
}
static void
replace_variant_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
ShellGlobal *global = user_data;
GError *error = NULL;
if (!g_file_replace_contents_finish (G_FILE (object), result, NULL, &error))
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
g_warning ("Could not replace runtime/persistent state file: %s\n",
error->message);
}
g_error_free (error);
}
g_hash_table_remove (global->save_ops, object);
}
static void
save_variant (ShellGlobal *global,
GFile *dir,
const char *property_name,
GVariant *variant)
save_variant (GFile *dir,
const char *property_name,
GVariant *variant)
{
GFile *path = g_file_get_child (dir, property_name);
GCancellable *cancellable;
cancellable = g_hash_table_lookup (global->save_ops, path);
g_cancellable_cancel (cancellable);
cancellable = g_cancellable_new ();
g_hash_table_insert (global->save_ops, g_object_ref (path), cancellable);
if (variant == NULL || g_variant_get_data (variant) == NULL)
{
g_file_delete_async (path, G_PRIORITY_DEFAULT, cancellable,
delete_variant_cb, global);
}
(void) g_file_delete (path, NULL, NULL);
else
{
g_file_replace_contents_async (path,
g_variant_get_data (variant),
g_variant_get_size (variant),
NULL, FALSE,
G_FILE_CREATE_REPLACE_DESTINATION,
cancellable, replace_variant_cb, global);
gsize size = g_variant_get_size (variant);
g_file_replace_contents (path, g_variant_get_data (variant), size,
NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
NULL, NULL, NULL);
}
g_object_unref (path);
@@ -1889,7 +1824,7 @@ shell_global_set_runtime_state (ShellGlobal *global,
const char *property_name,
GVariant *variant)
{
save_variant (global, global->runtime_state_path, property_name, variant);
save_variant (global->runtime_state_path, property_name, variant);
}
/**
@@ -1924,7 +1859,7 @@ shell_global_set_persistent_state (ShellGlobal *global,
const char *property_name,
GVariant *variant)
{
save_variant (global, global->userdatadir_path, property_name, variant);
save_variant (global->userdatadir_path, property_name, variant);
}
/**

View File

@@ -395,13 +395,6 @@ get_app_for_window (ShellWindowTracker *tracker,
if (meta_window_is_remote (window))
return _shell_app_new_for_window (window);
/* Check if the window was opened from within a sandbox; if this
* is the case, a corresponding .desktop file is guaranteed to match;
*/
result = get_app_from_sandboxed_app_id (window);
if (result != NULL)
return result;
/* Check if the window has a GApplication ID attached; this is
* canonical if it does
*/
@@ -416,6 +409,15 @@ get_app_for_window (ShellWindowTracker *tracker,
if (result != NULL)
return result;
/* Check if the window was opened from within a sandbox; if this
* is the case, a corresponding .desktop file is guaranteed to match;
* Do this after having checked by WM_CLASS so that sandboxed apps
* installing multiple .desktop files can properly match their windows.
*/
result = get_app_from_sandboxed_app_id (window);
if (result != NULL)
return result;
result = get_app_from_window_pid (tracker, window);
if (result != NULL)
return result;

View File

@@ -142,7 +142,7 @@ libst_gir = gnome.generate_gir(libst,
sources: st_gir_sources,
nsversion: '1.0',
namespace: 'St',
includes: ['Clutter-' + mutter_api_version, 'Cally-' + mutter_api_version, 'Gtk-3.0'],
includes: ['Clutter-' + mutter_api_version, 'Gtk-3.0'],
dependencies: [mutter_dep],
include_directories: include_directories('..'),
extra_args: ['-DST_COMPILATION', '--quiet'],

View File

@@ -205,8 +205,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
G_MAXDOUBLE,
0.0,
ST_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY));
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_UPPER,
g_param_spec_double ("upper",
@@ -216,8 +215,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
G_MAXDOUBLE,
0.0,
ST_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY));
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_VALUE,
g_param_spec_double ("value",
@@ -227,8 +225,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
G_MAXDOUBLE,
0.0,
ST_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY));
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_STEP_INC,
g_param_spec_double ("step-increment",
@@ -238,8 +235,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
G_MAXDOUBLE,
0.0,
ST_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY));
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_PAGE_INC,
g_param_spec_double ("page-increment",
@@ -249,8 +245,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
G_MAXDOUBLE,
0.0,
ST_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY));
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_PAGE_SIZE,
g_param_spec_double ("page-size",
@@ -260,8 +255,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
G_MAXDOUBLE,
0.0,
ST_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY));
G_PARAM_CONSTRUCT));
/**
* StAdjustment::changed:
* @self: the #StAdjustment

View File

@@ -177,15 +177,15 @@ st_bin_get_preferred_height (ClutterActor *self,
}
static void
st_bin_destroy (ClutterActor *actor)
st_bin_dispose (GObject *gobject)
{
StBinPrivate *priv = st_bin_get_instance_private (ST_BIN (actor));
StBinPrivate *priv = st_bin_get_instance_private (ST_BIN (gobject));
if (priv->child)
clutter_actor_destroy (priv->child);
g_assert (priv->child == NULL);
CLUTTER_ACTOR_CLASS (st_bin_parent_class)->destroy (actor);
G_OBJECT_CLASS (st_bin_parent_class)->dispose (gobject);
}
static void
@@ -315,11 +315,11 @@ st_bin_class_init (StBinClass *klass)
gobject_class->set_property = st_bin_set_property;
gobject_class->get_property = st_bin_get_property;
gobject_class->dispose = st_bin_dispose;
actor_class->get_preferred_width = st_bin_get_preferred_width;
actor_class->get_preferred_height = st_bin_get_preferred_height;
actor_class->allocate = st_bin_allocate;
actor_class->destroy = st_bin_destroy;
widget_class->popup_menu = st_bin_popup_menu;
widget_class->navigate_focus = st_bin_navigate_focus;

View File

@@ -90,7 +90,7 @@ adjustment_value_notify_cb (StAdjustment *adjustment,
GParamSpec *pspec,
StBoxLayout *box)
{
clutter_actor_queue_relayout (CLUTTER_ACTOR (box));
clutter_actor_queue_redraw (CLUTTER_ACTOR (box));
}
static void
@@ -490,7 +490,7 @@ st_box_layout_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
StBoxLayout *self = ST_BOX_LAYOUT (actor);
gdouble x, y, lower, upper;
gdouble x, y;
StBoxLayoutPrivate *priv = self->priv;
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
ClutterActorBox allocation_box;
@@ -505,42 +505,13 @@ st_box_layout_get_paint_volume (ClutterActor *actor,
* our paint volume on that. */
if (priv->hadjustment || priv->vadjustment)
{
gdouble width, height;
clutter_actor_get_allocation_box (actor, &allocation_box);
st_theme_node_get_content_box (theme_node, &allocation_box, &content_box);
origin.x = content_box.x1 - allocation_box.x1;
origin.y = content_box.y1 - allocation_box.y2;
origin.z = 0.f;
if (priv->hadjustment)
{
g_object_get (priv->hadjustment,
"lower", &lower,
"upper", &upper,
NULL);
width = upper - lower;
}
else
{
width = content_box.x2 - content_box.x1;
}
if (priv->vadjustment)
{
g_object_get (priv->vadjustment,
"lower", &lower,
"upper", &upper,
NULL);
height = upper - lower;
}
else
{
height = content_box.y2 - content_box.y1;
}
clutter_paint_volume_set_width (volume, width);
clutter_paint_volume_set_height (volume, height);
clutter_paint_volume_set_width (volume, content_box.x2 - content_box.x1);
clutter_paint_volume_set_height (volume, content_box.y2 - content_box.y1);
}
else if (!CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->get_paint_volume (actor, volume))
return FALSE;

View File

@@ -248,17 +248,14 @@ st_button_touch_event (ClutterActor *actor,
if (event->type == CLUTTER_TOUCH_BEGIN && !priv->press_sequence)
{
clutter_input_device_sequence_grab (device, sequence, actor);
if (!clutter_event_is_pointer_emulated ((ClutterEvent*) event))
st_button_press (button, device, 0, sequence);
st_button_press (button, device, 0, sequence);
return CLUTTER_EVENT_STOP;
}
else if (event->type == CLUTTER_TOUCH_END &&
priv->device == device &&
priv->press_sequence == sequence)
{
if (!clutter_event_is_pointer_emulated ((ClutterEvent*) event))
st_button_release (button, device, mask, 0, sequence);
st_button_release (button, device, mask, 0, sequence);
clutter_input_device_sequence_ungrab (device, sequence);
return CLUTTER_EVENT_STOP;
}

View File

@@ -308,9 +308,8 @@ st_entry_style_changed (StWidget *self)
}
theme_node = st_widget_get_theme_node (self);
st_theme_node_get_foreground_color (theme_node, &color);
clutter_text_set_color (CLUTTER_TEXT (priv->entry), &color);
_st_set_text_from_style (CLUTTER_TEXT (priv->entry), theme_node);
if (st_theme_node_lookup_length (theme_node, "caret-size", TRUE, &size))
clutter_text_set_cursor_size (CLUTTER_TEXT (priv->entry), (int)(.5 + size));
@@ -906,13 +905,6 @@ st_entry_unmap (ClutterActor *actor)
CLUTTER_ACTOR_CLASS (st_entry_parent_class)->unmap (actor);
}
static gboolean
st_entry_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, actor);
}
static void
st_entry_class_init (StEntryClass *klass)
{
@@ -930,7 +922,6 @@ st_entry_class_init (StEntryClass *klass)
actor_class->allocate = st_entry_allocate;
actor_class->paint = st_entry_paint;
actor_class->unmap = st_entry_unmap;
actor_class->get_paint_volume = st_entry_get_paint_volume;
actor_class->key_press_event = st_entry_key_press_event;
actor_class->key_focus_in = st_entry_key_focus_in;
@@ -1295,10 +1286,10 @@ st_entry_get_input_hints (StEntry *entry)
return clutter_text_get_input_hints (CLUTTER_TEXT (priv->entry));
}
static void
_st_entry_icon_clicked_cb (ClutterClickAction *action,
ClutterActor *actor,
StEntry *entry)
static gboolean
_st_entry_icon_press_cb (ClutterActor *actor,
ClutterButtonEvent *event,
StEntry *entry)
{
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
@@ -1306,6 +1297,8 @@ _st_entry_icon_clicked_cb (ClutterClickAction *action,
g_signal_emit (entry, entry_signals[PRIMARY_ICON_CLICKED], 0);
else
g_signal_emit (entry, entry_signals[SECONDARY_ICON_CLICKED], 0);
return FALSE;
}
static void
@@ -1315,24 +1308,21 @@ _st_entry_set_icon (StEntry *entry,
{
if (*icon)
{
clutter_actor_remove_action_by_name (*icon, "entry-icon-action");
g_signal_handlers_disconnect_by_func (*icon,
_st_entry_icon_press_cb,
entry);
clutter_actor_remove_child (CLUTTER_ACTOR (entry), *icon);
*icon = NULL;
}
if (new_icon)
{
ClutterAction *action;
*icon = g_object_ref (new_icon);
clutter_actor_set_reactive (*icon, TRUE);
clutter_actor_add_child (CLUTTER_ACTOR (entry), *icon);
action = clutter_click_action_new ();
clutter_actor_add_action_with_name (*icon, "entry-icon-action", action);
g_signal_connect (action, "clicked",
G_CALLBACK (_st_entry_icon_clicked_cb), entry);
g_signal_connect (*icon, "button-release-event",
G_CALLBACK (_st_entry_icon_press_cb), entry);
}
clutter_actor_queue_relayout (CLUTTER_ACTOR (entry));

View File

@@ -180,7 +180,6 @@ st_label_dispose (GObject *object)
{
StLabelPrivate *priv = ST_LABEL (object)->priv;
priv->label = NULL;
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
G_OBJECT_CLASS (st_label_parent_class)->dispose (object);

View File

@@ -116,6 +116,7 @@ _st_set_text_from_style (ClutterText *text,
PangoAttrList *attribs = NULL;
const PangoFontDescription *font;
StTextAlign align;
gdouble spacing;
st_theme_node_get_foreground_color (theme_node, &color);
clutter_text_set_color (text, &color);
@@ -123,11 +124,11 @@ _st_set_text_from_style (ClutterText *text,
font = st_theme_node_get_font (theme_node);
clutter_text_set_font_description (text, (PangoFontDescription *) font);
attribs = pango_attr_list_new ();
decoration = st_theme_node_get_text_decoration (theme_node);
if (decoration)
{
attribs = pango_attr_list_new ();
if (decoration & ST_TEXT_DECORATION_UNDERLINE)
{
PangoAttribute *underline = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
@@ -143,6 +144,13 @@ _st_set_text_from_style (ClutterText *text,
*/
}
spacing = st_theme_node_get_letter_spacing (theme_node);
if (spacing)
{
PangoAttribute *letter_spacing = pango_attr_letter_spacing_new ((int)(.5 + spacing) * PANGO_SCALE);
pango_attr_list_insert (attribs, letter_spacing);
}
clutter_text_set_attributes (text, attribs);
if (attribs)

View File

@@ -304,13 +304,6 @@ st_scroll_view_pick (ClutterActor *actor,
clutter_actor_paint (priv->vscroll);
}
static gboolean
st_scroll_view_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, actor);
}
static double
get_scrollbar_width (StScrollView *scroll,
gfloat for_height)
@@ -800,7 +793,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
actor_class->paint = st_scroll_view_paint;
actor_class->pick = st_scroll_view_pick;
actor_class->get_paint_volume = st_scroll_view_get_paint_volume;
actor_class->get_preferred_width = st_scroll_view_get_preferred_width;
actor_class->get_preferred_height = st_scroll_view_get_preferred_height;
actor_class->allocate = st_scroll_view_allocate;

View File

@@ -37,7 +37,6 @@ struct _StTextureCachePrivate
/* Things that were loaded with a cache policy != NONE */
GHashTable *keyed_cache; /* char * -> CoglTexture* */
GHashTable *keyed_surface_cache; /* char * -> cairo_surface_t* */
/* Presently this is used to de-duplicate requests for GIcons and async URIs. */
GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */
@@ -146,10 +145,6 @@ st_texture_cache_init (StTextureCache *self)
self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, cogl_object_unref);
self->priv->keyed_surface_cache = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) cairo_surface_destroy);
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_file_hash, (GEqualFunc) g_file_equal,
@@ -171,7 +166,6 @@ st_texture_cache_dispose (GObject *object)
}
g_clear_pointer (&self->priv->keyed_cache, g_hash_table_destroy);
g_clear_pointer (&self->priv->keyed_surface_cache, g_hash_table_destroy);
g_clear_pointer (&self->priv->outstanding_requests, g_hash_table_destroy);
g_clear_pointer (&self->priv->file_monitors, g_hash_table_destroy);
@@ -526,8 +520,6 @@ finish_texture_load (AsyncTextureLoadData *data,
goto out;
texdata = pixbuf_to_cogl_texture (pixbuf);
if (!texdata)
goto out;
if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
{
@@ -780,13 +772,13 @@ st_texture_cache_load (StTextureCache *cache,
if (!texture)
{
texture = load (cache, key, data, error);
if (texture && policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
if (texture)
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texture);
else
return NULL;
}
if (texture && policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
cogl_object_ref (texture);
cogl_object_ref (texture);
return texture;
}
@@ -984,7 +976,7 @@ file_changed_cb (GFileMonitor *monitor,
char *key;
guint file_hash;
if (event_type != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
return;
file_hash = g_file_hash (file);
@@ -994,7 +986,7 @@ file_changed_cb (GFileMonitor *monitor,
g_free (key);
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", file_hash);
g_hash_table_remove (cache->priv->keyed_surface_cache, key);
g_hash_table_remove (cache->priv->keyed_cache, key);
g_free (key);
g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, file);
@@ -1281,9 +1273,6 @@ st_texture_cache_load_file_sync_to_cogl_texture (StTextureCache *cache,
texdata = pixbuf_to_cogl_texture (pixbuf);
g_object_unref (pixbuf);
if (!texdata)
goto out;
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
{
cogl_object_ref (texdata);
@@ -1315,7 +1304,7 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache,
key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file));
surface = g_hash_table_lookup (cache->priv->keyed_surface_cache, key);
surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
if (surface == NULL)
{
@@ -1329,8 +1318,7 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache,
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
{
cairo_surface_reference (surface);
g_hash_table_insert (cache->priv->keyed_surface_cache,
g_strdup (key), surface);
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface);
}
}
else

View File

@@ -229,9 +229,9 @@ unpremultiply (ClutterColor *color)
{
if (color->alpha != 0)
{
color->red = MIN((color->red * 255 + 127) / color->alpha, 255);
color->green = MIN((color->green * 255 + 127) / color->alpha, 255);
color->blue = MIN((color->blue * 255 + 127) / color->alpha, 255);
color->red = (color->red * 255 + 127) / color->alpha;
color->green = (color->green * 255 + 127) / color->alpha;
color->blue = (color->blue * 255 + 127) / color->alpha;
}
}
@@ -402,7 +402,7 @@ st_theme_node_lookup_corner (StThemeNode *node,
return COGL_INVALID_HANDLE;
key = corner_to_string (&corner);
texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_FOREVER, load_corner, &corner, NULL);
texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_NONE, load_corner, &corner, NULL);
if (texture)
{
@@ -1414,32 +1414,6 @@ st_theme_node_load_background_image (StThemeNode *node)
return node->background_texture != COGL_INVALID_HANDLE;
}
static gboolean
st_theme_node_invalidate_resources_for_file (StThemeNode *node,
GFile *file)
{
StBorderImage *border_image;
gboolean changed = FALSE;
GFile *theme_file;
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;
}
border_image = st_theme_node_get_border_image (node);
theme_file = border_image ? st_border_image_get_file (border_image) : NULL;
if ((theme_file != NULL) && g_file_equal (theme_file, file))
{
st_theme_node_invalidate_border_image (node);
changed = TRUE;
}
return changed;
}
static void st_theme_node_prerender_shadow (StThemeNodePaintState *state);
static void
@@ -2777,17 +2751,3 @@ st_theme_node_paint_state_invalidate (StThemeNodePaintState *state)
state->alloc_width = 0;
state->alloc_height = 0;
}
gboolean
st_theme_node_paint_state_invalidate_for_file (StThemeNodePaintState *state,
GFile *file)
{
if (state->node != NULL &&
st_theme_node_invalidate_resources_for_file (state->node, file))
{
st_theme_node_paint_state_invalidate (state);
return TRUE;
}
return FALSE;
}

View File

@@ -2545,6 +2545,28 @@ st_theme_node_get_text_align(StThemeNode *node)
return ST_TEXT_ALIGN_LEFT;
}
/**
* st_theme_node_get_letter_spacing:
* @node: a #StThemeNode
*
* Gets the value for the letter-spacing style property, in pixels.
*
* Return value: the value of the letter-spacing property, if
* found, or zero if such property has not been found.
*/
gdouble
st_theme_node_get_letter_spacing (StThemeNode *node)
{
gdouble spacing = 0.;
g_return_val_if_fail (ST_IS_THEME_NODE (node), spacing);
ensure_properties (node);
st_theme_node_lookup_length (node, "letter-spacing", FALSE, &spacing);
return spacing;
}
static gboolean
font_family_from_terms (CRTerm *term,
char **family)

View File

@@ -223,6 +223,8 @@ StTextDecoration st_theme_node_get_text_decoration (StThemeNode *node);
StTextAlign st_theme_node_get_text_align (StThemeNode *node);
double st_theme_node_get_letter_spacing (StThemeNode *node);
/* Font rule processing is pretty complicated, so we just hardcode it
* under the standard font/font-family/font-size/etc names. This means
* you can't have multiple separate styled fonts for a single item,
@@ -287,9 +289,6 @@ void st_theme_node_paint_state_free (StThemeNodePaintState *state);
void st_theme_node_paint_state_copy (StThemeNodePaintState *state,
StThemeNodePaintState *other);
void st_theme_node_paint_state_invalidate (StThemeNodePaintState *state);
gboolean st_theme_node_paint_state_invalidate_for_file (StThemeNodePaintState *state,
GFile *file);
void st_theme_node_paint_state_set_node (StThemeNodePaintState *state,
StThemeNode *node);

View File

@@ -289,17 +289,44 @@ st_widget_texture_cache_changed (StTextureCache *cache,
{
StWidget *actor = ST_WIDGET (user_data);
StWidgetPrivate *priv = st_widget_get_instance_private (actor);
StThemeNode *node = priv->theme_node;
StBorderImage *border_image;
gboolean changed = FALSE;
int i;
GFile *theme_file;
for (i = 0; i < G_N_ELEMENTS (priv->paint_states); i++)
if (node == NULL)
return;
theme_file = st_theme_node_get_background_image (node);
if ((theme_file != NULL) && g_file_equal (theme_file, file))
{
StThemeNodePaintState *paint_state = &priv->paint_states[i];
changed |= st_theme_node_paint_state_invalidate_for_file (paint_state, file);
st_theme_node_invalidate_background_image (node);
changed = TRUE;
}
if (changed && clutter_actor_is_mapped (CLUTTER_ACTOR (actor)))
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
border_image = st_theme_node_get_border_image (node);
theme_file = border_image ? st_border_image_get_file (border_image) : NULL;
if ((theme_file != NULL) && g_file_equal (theme_file, file))
{
st_theme_node_invalidate_border_image (node);
changed = TRUE;
}
if (changed)
{
/* If we prerender the background / border, we need to update
* the paint state. We should probably implement a method to
* the theme node to determine this, but for now, just wipe
* the entire paint state.
*
* Use the existing state instead of a new one because it's
* assumed the rest of the state will stay the same.
*/
st_theme_node_paint_state_invalidate (current_paint_state (actor));
if (clutter_actor_is_mapped (CLUTTER_ACTOR (actor)))
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
}
}
static void