Compare commits

..

7 Commits

Author SHA1 Message Date
Florian Müllner
ee3cd450a5 build: Don't introspect ShellMenu
It is now only used internally by ShellApp to track remote actions,
so there's no need to expose it to javascript code.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:35:30 +01:00
Florian Müllner
996369a22d build: Remove remote menu support
It is now unused.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:35:30 +01:00
Florian Müllner
ce6ab7e121 app: Remove :menu property
It is now unused.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:59 +01:00
Florian Müllner
3da747ec2d app: Don't rely on app menu to check for GtkApplications
As the app menu is being phased out, it is no longer a good indicator
for GtkApplications. Instead, base the check directly on the appropriate
D-Bus properties.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:59 +01:00
Florian Müllner
593f15ad63 windowMenu: Remove fallback app menu support
With the app menu being phased out entirely, there's no good reason to
keep support for the fallback app menu in decorations either - the number
of applications that set an app menu and haven't embraced client-side
decorations is extremely small, and they should already have alternative
fallbacks for non-GNOME environment in place.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:59 +01:00
Florian Müllner
acdbd28262 panel: Remove the app menu
As the app menu is in the process of being retired[0], stop displaying
it in the shell - GTK+ still has a fallback path for applications that
haven't removed it yet.

[0] https://gitlab.gnome.org/GNOME/Initiatives/wikis/App-Menu-Retirement

https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:34:00 +01:00
Florian Müllner
ca70a4fc17 panel: Remove unused import
https://gitlab.gnome.org/GNOME/gnome-shell/issues/624
2019-01-26 14:32:20 +01:00
109 changed files with 5512 additions and 23882 deletions

View File

@@ -1,18 +0,0 @@
stages:
- source_check
variables:
JS_LOG: "js-report.txt"
js_check:
image: registry.fedoraproject.org/fedora:latest
stage: source_check
before_script:
- dnf install -y findutils mozjs60-devel
script:
- find js -name '*.js' -exec js60 -c -s '{}' ';' 2>&1 | tee $JS_LOG
- (! grep -q . $JS_LOG)
artifacts:
paths:
- ${JS_LOG}
when: on_failure

View File

@@ -158,15 +158,15 @@ you to inherit from a type to use it, you can do so:
var MyClutterActor = GObject.registerClass(
class MyClutterActor extends Clutter.Actor {
vfunc_get_preferred_width(forHeight) {
vfunc_get_preferred_width(actor, forHeight) {
return [100, 100];
}
vfunc_get_preferred_height(forWidth) {
vfunc_get_preferred_height(actor, forWidth) {
return [100, 100];
}
vfunc_paint() {
vfunc_paint(actor) {
let alloc = this.get_allocation_box();
Cogl.set_source_color4ub(255, 0, 0, 255);
Cogl.rectangle(alloc.x1, alloc.y1,

35
NEWS
View File

@@ -1,38 +1,3 @@
3.31.90
=======
* Fix input methods after ibus restarts [Takao; #295]
* Refresh world clocks and weather sections [Florian; #262]
* Port to ES6 classes (update your extensions!) [Florian; !361]
* networkAgent: Advise users when WPS support is available [Lubomir; !329]
* Performance improvements [Carlos; #832, #815]
* Fix drag-and-drop with wacom pens [Carlos; #540]
* Fix CAPS LOCK indication on wayland [Carlos; #762881]
* Show details of non-sensitive notifications on lock screen [Philip; #726]
* Refine extension-prefs' error UI [Florian; !193]
* Add switch-to-application-n keybindings [Florian; #648000]
* Remove top bar translucency [Florian; #408]
* Support emojis and keypads in on-screen keyboard [Carlos; #675]
* Don't allow popups to re-enable keyboard shortcuts on lock screen
(CVE-2019-3820) [Florian, Ray; #851]
* Replace app menu [Florian; #624]
* Include commonly copied+pasted extension helpers [Florian; !150]
* Misc. bug fixes and cleanups [Florian, Daniel, Philip, Sergio, Pascal,
Georges, verdre, Carlos, Christopher; #780, #909, !316, !308, !309, #915,
!350, !362, !357, !365, !366, !283, !367, #942, !371, !373, !374, !343,
!375, !292, !317, !377, !379, !346, !383, #953, !388]
Contributors:
Sergio Costas, Christopher Davis, Bilal Elmoussaoui, Takao Fujiwara,
Carlos Garnacho, Niels De Graef, Christian Kellner, Ignat Loskutov,
Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, Lubomir Rintel,
Jakub Steiner, Ray Strode, verdre, Daniel van Vugt, Philip Withnall
Translators:
Daniel Mustieles [es], Carmen Bianca BAKKER [eo], Charles Monzat [fr],
Pieter Schalk Schoeman [af], Jordi Mas [ca], Matej Urbančič [sl],
Fran Dieguez [gl], Balázs Úr [hu], A S Alam [pa], Fabio Tomat [fur],
Aurimas Černius [lt], Piotr Drąg [pl], Marek Cernocky [cs], Ryuta Fujii [ja]
3.31.4
======
* Improve icon grid performance [Daniel; #174]

File diff suppressed because it is too large Load Diff

View File

@@ -54,6 +54,5 @@
<file>us.json</file>
<file>vn.json</file>
<file>za.json</file>
<file>emoji.json</file>
</gresource>
</gresources>

View File

@@ -104,13 +104,6 @@
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary>
<description>
Keybinding to open the application menu.
</description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the “Show Applications” view</summary>
@@ -145,42 +138,6 @@
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
<description></description>
</key>
<key name="switch-to-application-1" type="as">
<default>["&lt;Super&gt;1"]</default>
<summary>Switch to application 1</summary>
</key>
<key name="switch-to-application-2" type="as">
<default>["&lt;Super&gt;2"]</default>
<summary>Switch to application 2</summary>
</key>
<key name="switch-to-application-3" type="as">
<default>["&lt;Super&gt;3"]</default>
<summary>Switch to application 3</summary>
</key>
<key name="switch-to-application-4" type="as">
<default>["&lt;Super&gt;4"]</default>
<summary>Switch to application 4</summary>
</key>
<key name="switch-to-application-5" type="as">
<default>["&lt;Super&gt;5"]</default>
<summary>Switch to application 5</summary>
</key>
<key name="switch-to-application-6" type="as">
<default>["&lt;Super&gt;6"]</default>
<summary>Switch to application 6</summary>
</key>
<key name="switch-to-application-7" type="as">
<default>["&lt;Super&gt;7"]</default>
<summary>Switch to application 7</summary>
</key>
<key name="switch-to-application-8" type="as">
<default>["&lt;Super&gt;8"]</default>
<summary>Switch to application 8</summary>
</key>
<key name="switch-to-application-9" type="as">
<default>["&lt;Super&gt;9"]</default>
<summary>Switch to application 9</summary>
</key>
</schema>
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"

View File

@@ -2,23 +2,26 @@
// it gets @if ed depending on $variant
$base_color: if($variant == 'light', #ffffff, lighten(desaturate(#241f31, 20%), 2%));
$bg_color: if($variant == 'light', #f6f5f4, desaturate(#3d3846, 10%));
$fg_color: if($variant == 'light', #2e3436, #eeeeec);
$base_color: if($variant =='light', #ffffff, #292929);
$bg_color: if($variant =='light', #ededed, #393f3f);
$fg_color: if($variant =='light', #2e3436, #eeeeec);
$selected_fg_color: #ffffff;
$selected_bg_color: if($variant == 'light', #3584e4, darken(#3584e4, 20%));
$selected_borders_color: if($variant== 'light', darken($selected_bg_color, 15%), darken($selected_bg_color, 30%));
$borders_color: if($variant == 'light', darken($bg_color, 18%), darken($bg_color, 10%));
$borders_edge: if($variant == 'light', transparentize(white, 0.2), transparentize($fg_color, 0.93));
$link_color: if($variant == 'light', darken($selected_bg_color, 10%), lighten($selected_bg_color, 20%));
$link_visited_color: if($variant == 'light', darken($selected_bg_color, 20%), lighten($selected_bg_color, 10%));
$selected_bg_color: if($variant == 'light', #4a90d9, darken(#4a90d9,20%));
$selected_borders_color: if($variant=='light', darken($selected_bg_color, 30%),
darken($selected_bg_color, 20%));
$borders_color: if($variant =='light', darken($bg_color,30%), darken($bg_color,12%));
$borders_edge: if($variant =='light', white, transparentize($fg_color, 0.9));
$link_color: if($variant == 'light', darken($selected_bg_color,10%),
lighten($selected_bg_color,20%));
$link_visited_color: if($variant == 'light', darken($selected_bg_color,20%),
lighten($selected_bg_color,10%));
$top_hilight: $borders_edge;
$warning_color: #f57900;
$error_color: #cc0000;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$success_color: if($variant =='light', #73d216, darken(#73d216,10%));
$destructive_color: if($variant =='light', #ef2929, darken(#ef2929,10%));
$osd_fg_color: #eeeeec;
$osd_bg_color: #2e3436;

View File

@@ -729,7 +729,9 @@ StScrollBar {
/* TOP BAR */
#panel {
background-color: black;
background-color: rgba(0, 0, 0, 0.35);
/* transition from solid to transparent */
transition-duration: 500ms;
font-weight: bold;
height: 1.86em;
font-feature-settings: "tnum";
@@ -746,7 +748,7 @@ StScrollBar {
.panel-corner {
-panel-corner-radius: $panel-corner-radius;
-panel-corner-background-color: black;
-panel-corner-background-color: rgba(0, 0, 0, 0.35);
-panel-corner-border-width: 2px;
-panel-corner-border-color: transparent;
@@ -765,7 +767,9 @@ StScrollBar {
-natural-hpadding: 12px;
-minimum-hpadding: 6px;
font-weight: bold;
color: #ccc;
color: #eee;
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
transition-duration: 100ms;
.app-menu-icon {
-st-icon-style: symbolic;
@@ -774,8 +778,21 @@ StScrollBar {
//dimensions of the icon are hardcoded
}
.system-status-icon,
.app-menu-icon > StIcon,
.popup-menu-arrow {
icon-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
}
&:hover {
color: lighten($fg_color, 10%);
text-shadow: 0px 1px 6px rgba(0, 0, 0, 1);
.system-status-icon,
.app-menu-icon > StIcon,
.popup-menu-arrow {
icon-shadow: 0px 1px 6px rgba(0, 0, 0, 1);
}
}
&:active, &:overview, &:focus, &:checked {
@@ -784,6 +801,8 @@ StScrollBar {
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0px lighten($selected_bg_color,5%);
color: lighten($fg_color,10%);
& > .system-status-icon { icon-shadow: black 0 2px 2px; }
}
.system-status-icon { icon-size: 1.09em; padding: 0 5px; }
@@ -808,6 +827,31 @@ StScrollBar {
.screencast-indicator { color: $warning_color; }
.remote-access-indicator { color: $warning_color; }
&.solid {
background-color: black;
/* transition from transparent to solid */
transition-duration: 300ms;
.panel-corner {
-panel-corner-background-color: black;
}
.panel-button {
color: #ccc;
text-shadow: none;
&:hover, &:active, &:overview, &:focus, &:checked {
color: lighten($fg_color, 10%);
}
}
.system-status-icon,
.app-menu-icon > StIcon,
.popup-menu-arrow {
icon-shadow: none;
}
}
}
// calendar popover
@@ -878,47 +922,14 @@ StScrollBar {
font-weight: bold;
}
.weather-header.location {
font-weight: normal;
font-size: 0.9em;
}
.world-clocks-grid,
.weather-grid {
.world-clocks-grid {
spacing-rows: 0.4em;
spacing-columns: 0.8em;
}
.weather-box {
spacing: 0.4em;
}
.world-clocks-city {
font-weight: bold;
font-size: 0.9em;
}
.world-clocks-time {
color: darken($fg_color,20%);
font-feature-settings: "tnum";
font-size: 1.2em;
}
.world-clocks-timezone {
color: darken($fg_color,40%);
font-feature-settings: "tnum";
font-size: 0.9em;
}
.weather-forecast-icon {
icon-size: 2.18em;
}
.weather-forecast-time {
color: darken($fg_color,40%);
font-size: 0.8em;
}
.calendar-month-label {
color: darken($fg_color,5%);
font-weight: bold;
@@ -1096,11 +1107,6 @@ StScrollBar {
.label-shadow { color: transparent; }
}
.app-menu,
.app-well-menu {
max-width: 27.25em;
}
.aggregate-menu {
min-width: 21em;
.popup-menu-icon { padding: 0 4px; }
@@ -1640,15 +1646,6 @@ StScrollBar {
#keyboard {
background-color: transparentize($osd_bg_color, 0.3);
.page-indicator {
padding: 4px 4px;
.page-indicator-icon {
width: 6px;
height: 6px
}
}
}
.key-container {
@@ -1658,8 +1655,8 @@ StScrollBar {
.keyboard-key {
background-color: #393f3f;
min-height: 1.2em;
min-width: 1.2em;
min-height: 2em;
min-width: 2em;
font-size: 16pt;
border-radius: 3px;
border: 1px solid #464d4d;
@@ -1710,20 +1707,6 @@ StScrollBar {
-boxpointer-gap: 5px;
}
.emoji-page {
.keyboard-key {
background-color: transparent;
border: none;
}
}
.emoji-panel {
.keyboard-key:latched {
border-color: #005684;
background-color: #006098;
}
}
// IBus Candidate Popup
.candidate-popup-content {

View File

@@ -104,111 +104,29 @@ var Application = class {
}
_buildErrorUI(extension, exc) {
let scroll = new Gtk.ScrolledWindow({
hscrollbar_policy: Gtk.PolicyType.NEVER,
propagate_natural_height: true
});
let box = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
spacing: 12,
margin: 100,
margin_bottom: 60
});
scroll.add(box);
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
let label = new Gtk.Label({
label: '<span size="x-large">%s</span>'.format(_("Somethings gone wrong")),
use_markup: true
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
box.add(label);
label = new Gtk.Label({
label: _("Were very sorry, but theres been a problem: the settings for this extension cant be displayed. We recommend that you report the issue to the extension authors."),
justify: Gtk.Justification.CENTER,
wrap: true
label: _("There was an error loading the preferences dialog for %s:").format(extension.metadata.name)
});
box.add(label);
let expander = new Expander({
label: _("Technical Details"),
margin_top: 12
});
box.add(expander);
let errortext = '';
errortext += exc;
errortext += '\n\n';
errortext += 'Stack trace:\n';
let errortext = `${exc}\n\nStack trace:\n${
// Indent stack trace.
exc.stack.split('\n').map(line => ` ${line}`).join('\n')
}`;
// Indent stack trace.
errortext += exc.stack.split('\n').map(line => ' ' + line).join('\n');
let scroll = new Gtk.ScrolledWindow({ vexpand: true });
let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({
buffer: buffer,
wrap_mode: Gtk.WrapMode.WORD,
monospace: true,
editable: false,
top_margin: 12,
bottom_margin: 12,
left_margin: 12,
right_margin: 12
});
let textview = new Gtk.TextView({ buffer: buffer });
textview.override_font(Pango.font_description_from_string('monospace'));
scroll.add(textview);
box.add(scroll);
let toolbar = new Gtk.Toolbar();
let provider = new Gtk.CssProvider();
provider.load_from_data(`* {
border: 0 solid @borders;
border-top-width: 1px;
}`);
toolbar.get_style_context().add_provider(
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
let copyButton = new Gtk.ToolButton({
icon_name: 'edit-copy-symbolic',
tooltip_text: _("Copy Error")
});
toolbar.add(copyButton);
copyButton.connect('clicked', w => {
let clipboard = Gtk.Clipboard.get_default(w.get_display());
let backticks = '```';
clipboard.set_text(
// markdown for pasting in gitlab issues
`The settings of extension ${extension.uuid} had an error:\n${
backticks}\n${exc}\n${backticks}\n\nStack trace:\n${
backticks}\n${exc.stack}${backticks}\n`, -1
);
});
let spacing = new Gtk.SeparatorToolItem({ draw: false });
toolbar.add(spacing);
toolbar.child_set_property(spacing, "expand", true);
let urlButton = new Gtk.ToolButton({
label: _("Homepage"),
tooltip_text: _("Visit extension homepage"),
no_show_all: true,
visible: extension.metadata.url != null
});
toolbar.add(urlButton);
urlButton.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
Gio.AppInfo.launch_default_for_uri(extension.metadata.url, context);
});
let expandedBox = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL
});
expandedBox.add(textview);
expandedBox.add(toolbar);
expander.add(expandedBox);
scroll.show_all();
return scroll;
box.show_all();
return box;
}
_buildUI(app) {
@@ -229,12 +147,8 @@ var Application = class {
Gio.SettingsBindFlags.DEFAULT |
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._mainStack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE
});
this._window.add(this._mainStack);
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
this._window.add(scroll);
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
this._extensionSelector.set_sort_func(this._sortList.bind(this));
@@ -242,8 +156,6 @@ var Application = class {
scroll.add(this._extensionSelector);
this._mainStack.add_named(scroll, 'listing');
this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder');
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => {
@@ -288,11 +200,6 @@ var Application = class {
}
_extensionsLoaded() {
if (this._extensionSelector.get_children().length > 0)
this._mainStack.visible_child_name = 'listing';
else
this._mainStack.visible_child_name = 'placeholder';
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
this._selectExtension(this._startupUuid);
this._startupUuid = null;
@@ -332,171 +239,6 @@ var Application = class {
}
};
var Expander = GObject.registerClass({
Properties: {
'label': GObject.ParamSpec.string(
'label', 'label', 'label',
GObject.ParamFlags.READWRITE,
null
)
}
}, class Expander extends Gtk.Box {
_init(params = {}) {
this._labelText = null;
super._init(Object.assign(params, {
orientation: Gtk.Orientation.VERTICAL,
spacing: 0
}));
this._frame = new Gtk.Frame({
shadow_type: Gtk.ShadowType.IN,
hexpand: true
});
let eventBox = new Gtk.EventBox();
this._frame.add(eventBox);
let hbox = new Gtk.Box({
spacing: 6,
margin: 12
});
eventBox.add(hbox);
this._arrow = new Gtk.Image({
icon_name: 'pan-end-symbolic'
});
hbox.add(this._arrow);
this._label = new Gtk.Label({ label: this._labelText });
hbox.add(this._label);
this._revealer = new Gtk.Revealer();
this._childBin = new Gtk.Frame({
shadow_type: Gtk.ShadowType.IN
});
this._revealer.add(this._childBin);
// Directly chain up to parent for internal children
super.add(this._frame);
super.add(this._revealer);
let provider = new Gtk.CssProvider();
provider.load_from_data('* { border-top-width: 0; }');
this._childBin.get_style_context().add_provider(
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
this._gesture = new Gtk.GestureMultiPress({
widget: this._frame,
button: 0,
exclusive: true
});
this._gesture.connect('released', (gesture, nPress) => {
if (nPress == 1)
this._revealer.reveal_child = !this._revealer.reveal_child;
});
this._revealer.connect('notify::reveal-child', () => {
if (this._revealer.reveal_child)
this._arrow.icon_name = 'pan-down-symbolic';
else
this._arrow.icon_name = 'pan-end-symbolic';
});
}
get label() {
return this._labelText;
}
set label(text) {
if (this._labelText == text)
return;
if (this._label)
this._label.label = text;
this._labelText = text;
this.notify('label');
}
add(child) {
// set expanded child
this._childBin.get_children().forEach(c => {
this._childBin.remove(c);
});
if (child)
this._childBin.add(child);
}
});
var EmptyPlaceholder = GObject.registerClass(
class EmptyPlaceholder extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 6,
margin: 32
});
let image = new Gtk.Image({
icon_name: 'application-x-addon-symbolic',
pixel_size: 96,
visible: true,
vexpand: true,
valign: Gtk.Align.END
});
image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(image);
let label = new Gtk.Label({
label: `<b><span size="x-large">${_("No Extensions Installed" )}</span></b>`,
use_markup: true,
visible: true
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop');
let desc = new Gtk.Label({
label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."),
use_markup: true,
wrap: true,
justify: Gtk.Justification.CENTER,
visible: true,
max_width_chars: 50,
hexpand: true,
vexpand: (appInfo == null),
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START
});
this.add(desc);
if (appInfo) {
let button = new Gtk.Button({
label: _("Browse in Software"),
image: new Gtk.Image({
icon_name: "org.gnome.Software-symbolic"
}),
always_show_image: true,
margin_top: 12,
visible: true,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
vexpand: true
});
this.add(button);
button.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
appInfo.launch([], context);
});
}
}
});
var DescriptionLabel = GObject.registerClass(
class DescriptionLabel extends Gtk.Label {
vfunc_get_preferred_height_for_width(width) {

View File

@@ -10,7 +10,6 @@ const Animation = imports.ui.animation;
const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util;
const Params = imports.misc.params;
const Shell = imports.gi.Shell;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
@@ -97,7 +96,7 @@ var AuthPrompt = class {
x_align: St.Align.START });
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
ShellEntry.addContextMenu(this._entry, { isPassword: true });
this.actor.add(this._entry,
{ expand: true,

View File

@@ -23,6 +23,7 @@ const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@@ -160,8 +161,8 @@ Signals.addSignalMethods(UserListItem.prototype);
var UserList = class {
constructor() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
this.actor.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
this.actor.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
this._box = new St.BoxLayout({ vertical: true,
style_class: 'login-dialog-user-list',
@@ -182,7 +183,7 @@ var UserList = class {
if (global.stage.get_key_focus() != this.actor)
return;
let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
if (!focusSet) {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._moveFocusToItems();
@@ -334,8 +335,7 @@ var SessionMenuButton = class {
this._button.remove_style_pseudo_class('active');
});
this._manager = new PopupMenu.PopupMenuManager({ actor: this._button },
{ actionMode: Shell.ActionMode.NONE });
this._manager = new PopupMenu.PopupMenuManager({ actor: this._button });
this._manager.addMenu(this._menu);
this._button.connect('clicked', () => { this._menu.toggle(); });
@@ -473,8 +473,8 @@ var LoginDialog = GObject.registerClass({
this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
opacity: 0,
vscrollbar_policy: St.PolicyType.AUTOMATIC,
hscrollbar_policy: St.PolicyType.NEVER });
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER });
this.add_child(this._bannerView);
let bannerBox = new St.BoxLayout({ vertical: true });

View File

@@ -78,7 +78,6 @@
<file>ui/overview.js</file>
<file>ui/overviewControls.js</file>
<file>ui/padOsd.js</file>
<file>ui/pageIndicators.js</file>
<file>ui/panel.js</file>
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>

View File

@@ -3,7 +3,6 @@
// Common utils for the extension system and the extension
// preferences tool
const Gettext = imports.gettext;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
@@ -64,66 +63,6 @@ function getCurrentExtension() {
return null;
}
/**
* initTranslations:
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
*/
function initTranslations(domain) {
let extension = getCurrentExtension();
if (!extension)
throw new Error('initTranslations() can only be called from extensions');
domain = domain || extension.metadata['gettext-domain'];
// Expect USER extensions to have a locale/ subfolder, otherwise assume a
// SYSTEM extension that has been installed in the same prefix as the shell
let localeDir = extension.dir.get_child('locale');
if (localeDir.query_exists(null))
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
/**
* getSettings:
* @schema: (optional): the GSettings schema id
*
* Builds and returns a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is omitted, it is taken from
* metadata['settings-schema'].
*/
function getSettings(schema) {
let extension = getCurrentExtension();
if (!extension)
throw new Error('getSettings() can only be called from extensions');
schema = schema || extension.metadata['settings-schema'];
const GioSSS = Gio.SettingsSchemaSource;
// Expect USER extensions to have a schemas/ subfolder, otherwise assume a
// SYSTEM extension that has been installed in the same prefix as the shell
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
else
schemaSource = GioSSS.get_default();
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
throw new Error(`Schema ${schema} could not be found for extension ${extension.metadata.uuid}. Please check your installation`);
return new Gio.Settings({ settings_schema: schemaObj });
}
/**
* versionCheck:
* @required: an array of versions we're compatible with

View File

@@ -160,7 +160,7 @@ var ObjectManager = class {
try {
initable.init_finish(result);
} catch(e) {
logError(e, 'could not initialize object manager for object ' + this._serviceName);
logError(e, 'could not initialize object manager for object ' + params.name);
this._tryToCompleteLoad();
return;
@@ -281,8 +281,8 @@ var ObjectManager = class {
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])
proxies.push(object(interfaceName));
}

View File

@@ -61,8 +61,8 @@ var WeatherClient = class {
this.emit('changed');
});
this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.desktop',
'org.gnome.Weather');
this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.Application.desktop',
'org.gnome.Weather.Application');
this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); });
this._weatherAppMon.watchSetting('automatic-location',
this._onAutomaticLocationChanged.bind(this));
@@ -234,7 +234,7 @@ var WeatherClient = class {
if (table != 'gnome' || id != 'geolocation')
return;
let permission = perms['org.gnome.Weather'] || ['NONE'];
let permission = perms['org.gnome.Weather.Application'] || ['NONE'];
let [accuracy] = permission;
this._weatherAuthorized = accuracy != 'NONE';

View File

@@ -65,7 +65,7 @@ let WINDOW_CONFIGS = [
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' }
];
function *run() {
function run() {
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");

View File

@@ -89,7 +89,7 @@ function extractBootTimestamp() {
return result;
}
function *run() {
function run() {
Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const Meta = imports.gi.Meta;
@@ -19,7 +20,6 @@ const IconGrid = imports.ui.iconGrid;
const Main = imports.ui.main;
const Overview = imports.ui.overview;
const OverviewControls = imports.ui.overviewControls;
const PageIndicators = imports.ui.pageIndicators;
const PopupMenu = imports.ui.popupMenu;
const Tweener = imports.ui.tweener;
const Workspace = imports.ui.workspace;
@@ -175,7 +175,7 @@ class BaseAppView {
_selectAppInternal(id) {
if (this._items[id])
this._items[id].actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
this._items[id].actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
else
log('No such application ' + id);
}
@@ -246,6 +246,116 @@ class BaseAppView {
};
Signals.addSignalMethods(BaseAppView.prototype);
var PageIndicatorsActor = GObject.registerClass(
class PageIndicatorsActor extends St.BoxLayout {
_init() {
super._init({ style_class: 'page-indicators',
vertical: true,
x_expand: true, y_expand: true,
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
reactive: true,
clip_to_allocation: true });
}
vfunc_get_preferred_height(forWidth) {
// We want to request the natural height of all our children as our
// natural height, so we chain up to St.BoxLayout, but we only request 0
// as minimum height, since it's not that important if some indicators
// are not shown
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
return [0, natHeight];
}
});
class PageIndicators {
constructor() {
this.actor = new PageIndicatorsActor();
this._nPages = 0;
this._currentPage = undefined;
this.actor.connect('notify::mapped', () => {
this.animateIndicators(IconGrid.AnimationDirection.IN);
});
}
setNPages(nPages) {
if (this._nPages == nPages)
return;
let diff = nPages - this._nPages;
if (diff > 0) {
for (let i = 0; i < diff; i++) {
let pageIndex = this._nPages + i;
let indicator = new St.Button({ style_class: 'page-indicator',
button_mask: St.ButtonMask.ONE |
St.ButtonMask.TWO |
St.ButtonMask.THREE,
toggle_mode: true,
checked: pageIndex == this._currentPage });
indicator.child = new St.Widget({ style_class: 'page-indicator-icon' });
indicator.connect('clicked', () => {
this.emit('page-activated', pageIndex);
});
this.actor.add_actor(indicator);
}
} else {
let children = this.actor.get_children().splice(diff);
for (let i = 0; i < children.length; i++)
children[i].destroy();
}
this._nPages = nPages;
this.actor.visible = (this._nPages > 1);
}
setCurrentPage(currentPage) {
this._currentPage = currentPage;
let children = this.actor.get_children();
for (let i = 0; i < children.length; i++)
children[i].set_checked(i == this._currentPage);
}
animateIndicators(animationDirection) {
if (!this.actor.mapped)
return;
let children = this.actor.get_children();
if (children.length == 0)
return;
for (let i = 0; i < this._nPages; i++)
Tweener.removeTweens(children[i]);
let offset;
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
offset = -children[0].width;
else
offset = children[0].width;
let isAnimationIn = animationDirection == IconGrid.AnimationDirection.IN;
let delay = isAnimationIn ? INDICATORS_ANIMATION_DELAY :
INDICATORS_ANIMATION_DELAY_OUT;
let baseTime = isAnimationIn ? INDICATORS_BASE_TIME : INDICATORS_BASE_TIME_OUT;
let totalAnimationTime = baseTime + delay * this._nPages;
let maxTime = isAnimationIn ? INDICATORS_ANIMATION_MAX_TIME :
INDICATORS_ANIMATION_MAX_TIME_OUT;
if (totalAnimationTime > maxTime)
delay -= (totalAnimationTime - maxTime) / this._nPages;
for (let i = 0; i < this._nPages; i++) {
children[i].translation_x = isAnimationIn ? offset : 0;
Tweener.addTween(children[i],
{ translation_x: isAnimationIn ? 0 : offset,
time: baseTime + delay * i,
transition: 'easeInOutQuad',
delay: isAnimationIn ? VIEWS_SWITCH_ANIMATION_DELAY : 0
});
}
}
};
Signals.addSignalMethods(PageIndicators.prototype);
var AllView = class AllView extends BaseAppView {
constructor() {
super({ usePagination: true }, null);
@@ -260,17 +370,17 @@ var AllView = class AllView extends BaseAppView {
x_expand:true, y_expand:true });
this.actor.add_actor(this._scrollView);
this._scrollView.set_policy(St.PolicyType.NEVER,
St.PolicyType.EXTERNAL);
this._scrollView.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.EXTERNAL);
this._adjustment = this._scrollView.vscroll.adjustment;
this._pageIndicators = new PageIndicators.AnimatedPageIndicators();
this._pageIndicators = new PageIndicators();
this._pageIndicators.connect('page-activated',
(indicators, pageIndex) => {
this.goToPage(pageIndex);
});
this._pageIndicators.connect('scroll-event', this._onScroll.bind(this));
this.actor.add_actor(this._pageIndicators);
this._pageIndicators.actor.connect('scroll-event', this._onScroll.bind(this));
this.actor.add_actor(this._pageIndicators.actor);
this.folderIcons = [];
@@ -377,21 +487,15 @@ var AllView = class AllView extends BaseAppView {
});
}
getAppInfos() {
return this._appInfoList;
}
_loadApps() {
this._appInfoList = Shell.AppSystem.get_default().get_installed().filter(appInfo => {
let apps = Gio.AppInfo.get_all().filter(appInfo => {
try {
let id = appInfo.get_id(); // catch invalid file encodings
} catch(e) {
return false;
}
return appInfo.should_show();
});
let apps = this._appInfoList.map(app => app.get_id());
}).map(app => app.get_id());
let appSys = Shell.AppSystem.get_default();
@@ -1014,7 +1118,7 @@ var FolderView = class FolderView extends BaseAppView {
this._grid.x_expand = true;
this.actor = new St.ScrollView({ overlay_scrollbars: true });
this.actor.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
let scrollableContainer = new St.BoxLayout({ vertical: true, reactive: true });
scrollableContainer.add_actor(this._grid);
this.actor.add_actor(scrollableContainer);
@@ -1194,13 +1298,15 @@ var FolderIcon = class FolderIcon {
folderApps.forEach(addAppId);
let folderCategories = this._folder.get_strv('categories');
let appInfos = this._parentView.getAppInfos();
appInfos.forEach(appInfo => {
Gio.AppInfo.get_all().forEach(appInfo => {
let appCategories = _getCategories(appInfo);
if (!_listsIntersect(folderCategories, appCategories))
return;
addAppId(appInfo.get_id());
try {
addAppId(appInfo.get_id()); // catch invalid file encodings
} catch(e) {
}
});
this.actor.visible = this.view.getAllItems().length > 0;
@@ -1358,18 +1464,18 @@ var AppFolderPopup = class AppFolderPopup {
let isLtr = Clutter.get_default_text_direction() == Clutter.TextDirection.LTR;
switch (event.get_key_symbol()) {
case Clutter.Down:
direction = St.DirectionType.TAB_FORWARD;
direction = Gtk.DirectionType.TAB_FORWARD;
break;
case Clutter.Right:
direction = isLtr ? St.DirectionType.TAB_FORWARD :
St.DirectionType.TAB_BACKWARD;
direction = isLtr ? Gtk.DirectionType.TAB_FORWARD :
Gtk.DirectionType.TAB_BACKWARD;
break;
case Clutter.Up:
direction = St.DirectionType.TAB_BACKWARD;
direction = Gtk.DirectionType.TAB_BACKWARD;
break;
case Clutter.Left:
direction = isLtr ? St.DirectionType.TAB_BACKWARD :
St.DirectionType.TAB_FORWARD;
direction = isLtr ? Gtk.DirectionType.TAB_BACKWARD :
Gtk.DirectionType.TAB_FORWARD;
break;
default:
return Clutter.EVENT_PROPAGATE;
@@ -1580,7 +1686,7 @@ var AppIcon = class AppIcon {
_onKeyboardPopupMenu() {
this.popupMenu();
this._menu.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
this._menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
getId() {

View File

@@ -36,14 +36,13 @@ const RENAMED_DESKTOP_IDS = {
'gnome-software.desktop': 'org.gnome.Software.desktop',
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
'gnomine.desktop': 'gnome-mines.desktop',
'gnotravex.desktop': 'gnome-tetravex.desktop',
'gnotski.desktop': 'gnome-klotski.desktop',
'gtali.desktop': 'tali.desktop',
'iagno.desktop': 'org.gnome.Iagno.desktop',
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
'polari.desktop': 'org.gnome.Polari.desktop',
'totem.desktop': 'org.gnome.Totem.desktop',
'evince.desktop': 'org.gnome.Evince.desktop',
@@ -154,7 +153,7 @@ class AppFavorites {
}
_removeFavorite(appId) {
if (!(appId in this._favorites))
if (!appId in this._favorites)
return false;
let ids = this._getIds().filter(id => id != appId);

View File

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const St = imports.gi.St;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
@@ -1082,7 +1083,7 @@ var CalendarMessageList = class CalendarMessageList {
overlay_scrollbars: true,
x_expand: true, y_expand: true,
x_fill: true, y_fill: true });
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
box.add_actor(this._scrollView);
this._clearButton = new St.Button({ style_class: 'message-list-clear-button button',

View File

@@ -111,10 +111,10 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
descriptionLabel.clutter_text.line_wrap = true;
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
contentBox.messageBox.add(descriptionLabel,
{ y_fill: true,
y_align: St.Align.START,
expand: true });
messageBox.add(descriptionLabel,
{ y_fill: true,
y_align: St.Align.START,
expand: true });
}
this._okButton = { label: _("Connect"),
@@ -705,14 +705,14 @@ var NetworkAgent = class {
if (hints.indexOf('pin') != -1) {
let gsmSetting = connection.get_setting_gsm();
title = _("PIN code required");
body = _("PIN code is needed for the mobile broadband device");
message = _("PIN code is needed for the mobile broadband device");
break;
}
// fall through
case 'cdma':
case 'bluetooth':
title = _("Mobile broadband network password");
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
default:
log('Invalid connection type: ' + connectionType);

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
@@ -820,8 +821,8 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
});
this._scrollArea = new St.ScrollView({ style_class: 'chat-scrollview vfade',
vscrollbar_policy: St.PolicyType.AUTOMATIC,
hscrollbar_policy: St.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER,
visible: this.expanded });
this._contentArea = new St.BoxLayout({ style_class: 'chat-body',
vertical: true });

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -57,7 +58,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
if (item.focusCallback)
item.focusCallback(timestamp);
else
item.root.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
// Sort the items into a consistent order; panel first, tray last,

View File

@@ -4,6 +4,7 @@ const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const GWeather = imports.gi.GWeather;
const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
@@ -22,8 +23,6 @@ const Calendar = imports.ui.calendar;
const Weather = imports.misc.weather;
const System = imports.system;
const MAX_FORECASTS = 5;
function _isToday(date) {
let now = new Date();
return now.getYear() == date.getYear() &&
@@ -156,27 +155,18 @@ var WorldClocksSection = class WorldClocksSection {
let label = new St.Label({ style_class: 'world-clocks-city',
text: name,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true });
let time = new St.Label({ style_class: 'world-clocks-time' });
let offset = l.get_timezone().get_offset() / 60.;
let fmt = (Math.trunc(offset) == offset) ? '%s%.0f' : '%s%.1f';
let prefix = (offset >= 0) ? '+' : '-';
let tz = new St.Label({ style_class: 'world-clocks-timezone',
text: fmt.format(prefix, Math.abs(offset)),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER });
let time = new St.Label({ style_class: 'world-clocks-time',
x_align: Clutter.ActorAlign.END,
x_expand: true });
if (this._grid.text_direction == Clutter.TextDirection.RTL) {
layout.attach(tz, 0, i + 1, 1, 1);
layout.attach(time, 1, i + 1, 1, 1);
layout.attach(label, 2, i + 1, 1, 1);
layout.attach(time, 0, i + 1, 1, 1);
layout.attach(label, 1, i + 1, 1, 1);
} else {
layout.attach(label, 0, i + 1, 1, 1);
layout.attach(time, 1, i + 1, 1, 1);
layout.attach(tz, 2, i + 1, 1, 1);
}
this._locations[i].actor = time;
@@ -227,114 +217,110 @@ var WeatherSection = class WeatherSection {
this.actor.child = box;
let titleBox = new St.BoxLayout();
titleBox.add_child(new St.Label({ style_class: 'weather-header',
x_align: Clutter.ActorAlign.START,
x_expand: true,
text: _("Weather") }));
box.add_child(titleBox);
box.add_child(new St.Label({ style_class: 'weather-header',
x_align: Clutter.ActorAlign.START,
text: _("Weather") }));
this._titleLocation = new St.Label({ style_class: 'weather-header location',
x_align: Clutter.ActorAlign.END });
titleBox.add_child(this._titleLocation);
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
this._forecastGrid = new St.Widget({ style_class: 'weather-grid',
layout_manager: layout });
layout.hookup_style(this._forecastGrid);
box.add_child(this._forecastGrid);
this._conditionsLabel = new St.Label({ style_class: 'weather-conditions',
x_align: Clutter.ActorAlign.START });
this._conditionsLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._conditionsLabel.clutter_text.line_wrap = true;
box.add_child(this._conditionsLabel);
this._weatherClient.connect('changed', this._sync.bind(this));
this._sync();
}
_getInfos() {
_getSummary(info, capitalize=false) {
let options = capitalize ? GWeather.FormatOptions.SENTENCE_CAPITALIZATION
: GWeather.FormatOptions.NO_CAPITALIZATION;
let [ok, phenomenon, qualifier] = info.get_value_conditions();
if (ok)
return new GWeather.Conditions({ significant: true,
phenomenon,
qualifier }).to_string_full(options);
let [, sky] = info.get_value_sky();
return GWeather.Sky.to_string_full(sky, options);
}
_sameSummary(info1, info2) {
let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
let [ok2, phenom2, qualifier2] = info2.get_value_conditions();
if (ok1 || ok2)
return ok1 == ok2 && phenom1 == phenom2 && qualifier1 == qualifier2;
let [, sky1] = info1.get_value_sky();
let [, sky2] = info2.get_value_sky();
return sky1 == sky2;
}
_getSummaryText() {
let info = this._weatherClient.info;
let forecasts = info.get_forecast_list();
if (forecasts.length == 0) // No forecasts, just current conditions
return '%s.'.format(this._getSummary(info, true));
let current = info;
let infos = [info];
for (let i = 0; i < forecasts.length; i++) {
let [ok, timestamp] = forecasts[i].get_value_update();
let datetime = new Date(timestamp * 1000);
if (!_isToday(datetime))
if (!_isToday(new Date(timestamp * 1000)))
continue; // Ignore forecasts from other days
[ok, timestamp] = current.get_value_update();
let currenttime = new Date(timestamp * 1000);
if (currenttime.getHours() == datetime.getHours())
continue; // Enforce a minimum interval of 1h
if (this._sameSummary(current, forecasts[i]))
continue; // Ignore consecutive runs of equal summaries
current = forecasts[i];
if (infos.push(current) == MAX_FORECASTS)
break; // Use a maximum of five forecasts
if (infos.push(current) == 3)
break; // Use a maximum of three summaries
}
return infos;
}
_addForecasts() {
let layout = this._forecastGrid.layout_manager;
let fmt;
switch(infos.length) {
/* Translators: %s is a weather condition like "Clear sky"; see
libgweather for the possible condition strings. If at all
possible, the sentence should match the grammatical case etc. of
the inserted conditions. */
case 1: fmt = _("%s all day."); break;
let infos = this._getInfos();
if (this._forecastGrid.text_direction == Clutter.TextDirection.RTL)
infos.reverse();
/* Translators: %s is a weather condition like "Clear sky"; see
libgweather for the possible condition strings. If at all
possible, the sentence should match the grammatical case etc. of
the inserted conditions. */
case 2: fmt = _("%s, then %s later."); break;
let col = 0;
infos.forEach(fc => {
let [ok, timestamp] = fc.get_value_update();
let timeStr = Util.formatTime(new Date(timestamp * 1000), {
timeOnly: true
});
let icon = new St.Icon({ style_class: 'weather-forecast-icon',
icon_name: fc.get_symbolic_icon_name(),
x_align: Clutter.ActorAlign.CENTER,
x_expand: true });
let temp = new St.Label({ style_class: 'weather-forecast-temp',
text: fc.get_temp_summary(),
x_align: Clutter.ActorAlign.CENTER });
let time = new St.Label({ style_class: 'weather-forecast-time',
text: timeStr,
x_align: Clutter.ActorAlign.CENTER });
layout.attach(icon, col, 0, 1, 1);
layout.attach(temp, col, 1, 1, 1);
layout.attach(time, col, 2, 1, 1);
col++;
/* Translators: %s is a weather condition like "Clear sky"; see
libgweather for the possible condition strings. If at all
possible, the sentence should match the grammatical case etc. of
the inserted conditions. */
case 3: fmt = _("%s, then %s, followed by %s later."); break;
}
let summaries = infos.map((info, i) => {
let capitalize = i == 0 && fmt.startsWith('%s');
return this._getSummary(info, capitalize);
});
return String.prototype.format.apply(fmt, summaries);
}
_setStatusLabel(text) {
let layout = this._forecastGrid.layout_manager;
let label = new St.Label({ text });
layout.attach(label, 0, 0, 1, 1);
}
_getLabelText() {
if (!this._weatherClient.hasLocation)
return _("Select a location…");
_updateForecasts() {
this._forecastGrid.destroy_all_children();
if (!this._weatherClient.hasLocation) {
this._setStatusLabel(_("Select a location…"));
return;
}
if (this._weatherClient.loading)
return _("Loading…");
let info = this._weatherClient.info;
this._titleLocation.text = info.get_location().get_name();
if (this._weatherClient.loading) {
this._setStatusLabel(_("Loading…"));
return;
}
if (info.is_valid()) {
this._addForecasts();
return;
}
if (info.is_valid())
return this._getSummaryText() + ' ' +
/* Translators: %s is a temperature with unit, e.g. "23℃" */
_("Feels like %s.").format(info.get_apparent());
if (info.network_error())
this._setStatusLabel(_("Go online for weather information"));
else
this._setStatusLabel(_("Weather information is currently unavailable"));
return _("Go online for weather information");
return _("Weather information is currently unavailable");
}
_sync() {
@@ -343,9 +329,7 @@ var WeatherSection = class WeatherSection {
if (!this.actor.visible)
return;
this._titleLocation.visible = this._weatherClient.hasLocation;
this._updateForecasts();
this._conditionsLabel.text = this._getLabelText();
}
};
@@ -394,13 +378,13 @@ class IndicatorPad extends St.Widget {
super._init();
}
vfunc_get_preferred_width(forHeight) {
vfunc_get_preferred_width(container, forHeight) {
if (this._source.visible)
return this._source.get_preferred_width(forHeight);
return [0, 0];
}
vfunc_get_preferred_height(forWidth) {
vfunc_get_preferred_height(container, forWidth) {
if (this._source.visible)
return this._source.get_preferred_height(forWidth);
return [0, 0];
@@ -531,7 +515,7 @@ class DateMenuButton extends PanelMenu.Button {
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true, x_fill: true,
overlay_scrollbars: true });
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._displaysSection.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
vbox.add_actor(this._displaysSection);
let displaysBox = new St.BoxLayout({ vertical: true,

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const St = imports.gi.St;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -108,7 +109,6 @@ var _Draggable = class _Draggable {
this._dragCancellable = true;
this._eventsGrabbed = false;
this._capturedEventId = 0;
}
_onButtonPress(actor, event) {
@@ -119,7 +119,7 @@ var _Draggable = class _Draggable {
return Clutter.EVENT_PROPAGATE;
this._buttonDown = true;
this._grabActor(event.get_device());
this._grabActor();
let [stageX, stageY] = event.get_coords();
this._dragStartX = stageX;
@@ -136,8 +136,10 @@ var _Draggable = class _Draggable {
if (Tweener.getTweenCount(actor))
return Clutter.EVENT_PROPAGATE;
this._touchSequence = event.get_event_sequence();
this._buttonDown = true;
this._grabActor(event.get_device(), event.get_event_sequence());
this._grabActor();
let [stageX, stageY] = event.get_coords();
this._dragStartX = stageX;
@@ -146,30 +148,19 @@ var _Draggable = class _Draggable {
return Clutter.EVENT_PROPAGATE;
}
_grabDevice(actor, pointer, touchSequence) {
if (touchSequence)
pointer.sequence_grab(touchSequence, actor);
_grabDevice(actor) {
let manager = Clutter.DeviceManager.get_default();
let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
if (pointer && this._touchSequence)
pointer.sequence_grab(this._touchSequence, actor);
else if (pointer)
pointer.grab (actor);
this._grabbedDevice = pointer;
this._touchSequence = touchSequence;
this._capturedEventId = global.stage.connect('captured-event', (actor, event) => {
let device = event.get_device();
if (device != this._grabbedDevice &&
device.get_device_type() != Clutter.InputDeviceType.KEYBOARD_DEVICE)
return Clutter.EVENT_STOP;
return Clutter.EVENT_PROPAGATE;
});
}
_ungrabDevice() {
if (this._capturedEventId != 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
if (this._touchSequence)
this._grabbedDevice.sequence_ungrab (this._touchSequence);
else
@@ -179,8 +170,8 @@ var _Draggable = class _Draggable {
this._grabbedDevice = null;
}
_grabActor(device, touchSequence) {
this._grabDevice(this.actor, device, touchSequence);
_grabActor() {
this._grabDevice(this.actor);
this._onEventId = this.actor.connect('event',
this._onEvent.bind(this));
}
@@ -194,11 +185,11 @@ var _Draggable = class _Draggable {
this._onEventId = null;
}
_grabEvents(device, touchSequence) {
_grabEvents() {
if (!this._eventsGrabbed) {
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
if (this._eventsGrabbed)
this._grabDevice(_getEventHandlerActor(), device, touchSequence);
this._grabDevice(_getEventHandlerActor());
}
}
@@ -210,36 +201,14 @@ var _Draggable = class _Draggable {
}
}
_eventIsRelease(event) {
if (event.type() == Clutter.EventType.BUTTON_RELEASE) {
let buttonMask = (Clutter.ModifierType.BUTTON1_MASK |
Clutter.ModifierType.BUTTON2_MASK |
Clutter.ModifierType.BUTTON3_MASK);
/* We only obey the last button release from the device,
* other buttons may get pressed/released during the DnD op.
*/
return (event.get_state() & buttonMask) == 0;
} else if (event.type() == Clutter.EventType.TOUCH_END) {
/* For touch, we only obey the pointer emulating sequence */
return global.display.is_pointer_emulating_sequence(event.get_event_sequence());
}
return false;
}
_onEvent(actor, event) {
let device = event.get_device();
if (this._grabbedDevice &&
device != this._grabbedDevice &&
device.get_device_type() != Clutter.InputDeviceType.KEYBOARD_DEVICE)
return Clutter.EVENT_PROPAGATE;
// We intercept BUTTON_RELEASE event to know that the button was released in case we
// didn't start the drag, to drop the draggable in case the drag was in progress, and
// to complete the drag and ensure that whatever happens to be under the pointer does
// not get triggered if the drag was cancelled with Esc.
if (this._eventIsRelease(event)) {
if (event.type() == Clutter.EventType.BUTTON_RELEASE ||
(event.type() == Clutter.EventType.TOUCH_END &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
this._buttonDown = false;
if (this._dragState == DragState.DRAGGING) {
return this._dragActorDropped(event);
@@ -299,19 +268,7 @@ var _Draggable = class _Draggable {
* This function is useful to call if you've specified manualMode
* for the draggable.
*/
startDrag(stageX, stageY, time, sequence, device) {
if (device == undefined) {
let event = Clutter.get_current_event();
if (event)
device = event.get_device();
if (device == undefined) {
let manager = Clutter.DeviceManager.get_default();
device = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
}
}
startDrag(stageX, stageY, time, sequence) {
currentDraggable = this;
this._dragState = DragState.DRAGGING;
@@ -326,7 +283,8 @@ var _Draggable = class _Draggable {
if (this._onEventId)
this._ungrabActor();
this._grabEvents(device, sequence);
this._touchSequence = sequence;
this._grabEvents();
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
this._dragX = this._dragStartX = stageX;
@@ -394,8 +352,7 @@ var _Draggable = class _Draggable {
this._finishAnimation();
this._dragActor = null;
if (this._dragState == DragState.DRAGGING)
this._dragState = DragState.CANCELLED;
this._dragState = DragState.CANCELLED;
});
this._dragOrigOpacity = this._dragActor.opacity;
if (this._dragActorOpacity != undefined)
@@ -441,11 +398,10 @@ var _Draggable = class _Draggable {
let [stageX, stageY] = event.get_coords();
// See if the user has moved the mouse enough to trigger a drag
let threshold = St.Settings.get().drag_threshold;
if (!currentDraggable &&
(Math.abs(stageX - this._dragStartX) > threshold ||
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
if ((Math.abs(stageX - this._dragStartX) > threshold ||
Math.abs(stageY - this._dragStartY) > threshold)) {
this.startDrag(stageX, stageY, event.get_time(), this._touchSequence, event.get_device());
this.startDrag(stageX, stageY, event.get_time(), this._touchSequence);
this._updateDragPosition(event);
}

View File

@@ -30,7 +30,7 @@ var EdgeDragAction = GObject.registerClass({
return global.display.get_monitor_geometry(monitorIndex);
}
vfunc_gesture_prepare(actor) {
vfunc_gesture_prepare(action, actor) {
if (this.get_n_current_points() == 0)
return false;
@@ -46,7 +46,7 @@ var EdgeDragAction = GObject.registerClass({
(this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
}
vfunc_gesture_progress(actor) {
vfunc_gesture_progress(action, actor) {
let [startX, startY] = this.get_press_coords(0);
let [x, y] = this.get_motion_coords(0);
let offsetX = Math.abs (x - startX);
@@ -66,7 +66,7 @@ var EdgeDragAction = GObject.registerClass({
return true;
}
vfunc_gesture_end(actor) {
vfunc_gesture_end(action, actor) {
let [startX, startY] = this.get_press_coords(0);
let [x, y] = this.get_motion_coords(0);
let monitorRect = this._getMonitorRect(startX, startY);

View File

@@ -22,6 +22,7 @@ const AccountsService = imports.gi.AccountsService;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const Polkit = imports.gi.Polkit;
const St = imports.gi.St;
@@ -319,7 +320,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
messageLayout.add(this._batteryWarning);
this._scrollView = new St.ScrollView({ style_class: 'end-session-dialog-list' });
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.contentLayout.add(this._scrollView,
{ x_fill: true,
y_fill: true });

View File

@@ -4,6 +4,7 @@ const Config = imports.misc.config;
imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION;
imports.gi.versions.Gio = '2.0';
imports.gi.versions.Gdk = '3.0';
imports.gi.versions.GdkPixbuf = '2.0';
imports.gi.versions.Gtk = '3.0';
imports.gi.versions.TelepathyGLib = '0.12';

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -186,7 +187,7 @@ var GrabHelper = class GrabHelper {
if (params.focus) {
params.focus.grab_key_focus();
} else if (newFocus && hadFocus) {
if (!newFocus.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
newFocus.grab_key_focus();
}

View File

@@ -236,7 +236,7 @@ var CandidatePopup = class CandidatePopup {
let indexes = [];
let indexLabel;
for (let i = 0; (indexLabel = lookupTable.get_label(i)); ++i)
for (let i = 0; indexLabel = lookupTable.get_label(i); ++i)
indexes.push(indexLabel.get_text());
Main.keyboard.resetSuggestions();
@@ -295,7 +295,7 @@ var CandidatePopup = class CandidatePopup {
_setTextAttributes(clutterText, ibusAttrList) {
let attr;
for (let i = 0; (attr = ibusAttrList.get(i)); ++i)
for (let i = 0; attr = ibusAttrList.get(i); ++i)
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
}

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -669,7 +670,7 @@ var IconGrid = GObject.registerClass({
}
addItem(item, index) {
if (!(item.icon instanceof BaseIcon))
if (!item.icon instanceof BaseIcon)
throw new Error('Only items with a BaseIcon icon property can be added to IconGrid');
this._items.push(item);
@@ -905,8 +906,10 @@ var PaginatedIconGrid = GObject.registerClass({
getItemPage(item) {
let children = this._getVisibleChildren();
let index = children.indexOf(item);
if (index == -1)
if (index == -1) {
throw new Error('Item not found.');
return 0;
}
return Math.floor(index / this._childrenPerPage);
}
@@ -921,9 +924,10 @@ var PaginatedIconGrid = GObject.registerClass({
openExtraSpace(sourceItem, side, nRows) {
let children = this._getVisibleChildren();
let index = children.indexOf(sourceItem.actor);
if (index == -1)
if (index == -1) {
throw new Error('Item not found.');
return;
}
let pageIndex = Math.floor(index / this._childrenPerPage);
let pageOffset = pageIndex * this._childrenPerPage;
@@ -955,8 +959,8 @@ var PaginatedIconGrid = GObject.registerClass({
this._translatedChildren = [];
this.emit('space-opened');
} else {
this._translateChildren(childrenUp, St.DirectionType.UP, nRowsUp);
this._translateChildren(childrenDown, St.DirectionType.DOWN, nRowsDown);
this._translateChildren(childrenUp, Gtk.DirectionType.UP, nRowsUp);
this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown);
this._translatedChildren = childrenUp.concat(childrenDown);
}
}
@@ -966,7 +970,7 @@ var PaginatedIconGrid = GObject.registerClass({
if (translationY == 0)
return;
if (direction == St.DirectionType.UP)
if (direction == Gtk.DirectionType.UP)
translationY *= -1;
for (let i = 0; i < children.length; i++) {

View File

@@ -8,7 +8,7 @@ const KEYBOARD_A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable';
const KEY_SLOW_KEYS_ENABLED = 'slowkeys-enable';
var KbdA11yDialog = GObject.registerClass(
var KbdA11yDialog = new GObject.registerClass(
class KbdA11yDialog extends GObject.Object {
_init() {
super._init();

View File

@@ -2,6 +2,7 @@
const Atspi = imports.gi.Atspi;
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
@@ -15,15 +16,12 @@ const IBusManager = imports.misc.ibusManager;
const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const PageIndicators = imports.ui.pageIndicators;
const PopupMenu = imports.ui.popupMenu;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
var KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2 * 1000;
var KEY_LONG_PRESS_TIME = 250;
var PANEL_SWITCH_ANIMATION_TIME = 0.5;
var PANEL_SWITCH_RELATIVE_DISTANCE = 1 / 3; /* A third of the actor width */
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
@@ -42,66 +40,28 @@ const defaultKeysPost = [
[ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ width: 3, level: 1, right: true, extraClassName: 'shift-key-lowercase' }],
[{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ],
[{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ],
[ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ width: 3, level: 0, right: true, extraClassName: 'shift-key-uppercase' }],
[{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ],
[{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ],
[ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ label: '=/<', width: 3, level: 3, right: true }],
[{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ],
[{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ],
[ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ label: '?123', width: 3, level: 2, right: true }],
[{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ],
[{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ],
];
var AspectContainer = GObject.registerClass(
class AspectContainer extends St.Widget {
_init(params) {
super._init(params);
this._ratio = 1;
}
setRatio(relWidth, relHeight) {
this._ratio = relWidth / relHeight;
this.queue_relayout();
}
vfunc_allocate(box, flags) {
if (box.get_width() > 0 && box.get_height() > 0) {
let sizeRatio = box.get_width() / box.get_height();
if (sizeRatio >= this._ratio) {
/* Restrict horizontally */
let width = box.get_height() * this._ratio;
let diff = box.get_width() - width;
box.x1 += Math.floor(diff / 2);
box.x2 -= Math.ceil(diff / 2);
} else {
/* Restrict vertically */
let height = box.get_width() / this._ratio;
let diff = box.get_height() - height;
box.y1 += Math.floor(diff / 2);
box.y2 -= Math.floor(diff / 2);
}
}
super.vfunc_allocate(box, flags);
}
});
var KeyContainer = GObject.registerClass(
var KeyContainer = new GObject.registerClass(
class KeyContainer extends St.Widget {
_init() {
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true,
row_homogeneous: true });
super._init({ layout_manager: gridLayout,
x_expand: true, y_expand: true });
super._init({ layout_manager: gridLayout });
this._gridLayout = gridLayout;
this._currentRow = 0;
this._currentCol = 0;
@@ -138,7 +98,32 @@ class KeyContainer extends St.Widget {
this._maxCols = Math.max(this._currentCol, this._maxCols);
}
layoutButtons(container) {
vfunc_allocate(box, flags) {
if (box.get_width() > 0 && box.get_height() > 0 && this._maxCols > 0) {
let keyboardRatio = this._maxCols / this._rows.length;
let sizeRatio = box.get_width() / box.get_height();
if (sizeRatio >= keyboardRatio) {
/* Restrict horizontally */
let width = box.get_height() * keyboardRatio;
let diff = box.get_width() - width;
box.x1 += Math.floor(diff / 2);
box.x2 -= Math.ceil(diff / 2);
} else {
/* Restrict vertically */
let height = box.get_width() / keyboardRatio;
let diff = box.get_height() - height;
box.y1 += Math.floor(diff / 2);
box.y2 -= Math.floor(diff / 2);
}
}
super.vfunc_allocate(box, flags);
}
layoutButtons() {
let nCol = 0, nRow = 0;
for (let i = 0; i < this._rows.length; i++) {
@@ -165,9 +150,6 @@ class KeyContainer extends St.Widget {
nRow += KEY_SIZE;
nCol = 0;
}
if (container)
container.setRatio(this._maxCols, this._rows.length);
}
});
@@ -250,7 +232,7 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
};
var Key = class Key {
constructor(key, extendedKeys) {
constructor(key) {
this.key = key || "";
this.keyButton = this._makeKey(this.key);
@@ -276,8 +258,6 @@ var Key = class Key {
this._boxPointer.destroy();
this._boxPointer = null;
}
this.cancel();
}
_ensureExtendedKeysPopup() {
@@ -299,13 +279,11 @@ var Key = class Key {
}
_getKeyval(key) {
let unicode = key.charCodeAt(0);
return Clutter.unicode_to_keysym(unicode);
let unicode = String.charCodeAt(key, 0);
return Gdk.unicode_to_keyval(unicode);
}
_press(key) {
this.emit('activated')
if (key != this.key || this._extended_keys.length == 0) {
this.emit('pressed', this._getKeyval(key), key);
}
@@ -346,16 +324,6 @@ var Key = class Key {
this._longPress = false;
}
cancel() {
if (this._pressTimeoutId != 0) {
GLib.source_remove(this._pressTimeoutId);
this._pressTimeoutId = 0;
}
this._touchPressed = false;
this.keyButton.set_hover(false);
this.keyButton.fake_release();
}
_onCapturedEvent(actor, event) {
let type = event.type();
let press = (type == Clutter.EventType.BUTTON_PRESS || type == Clutter.EventType.TOUCH_BEGIN);
@@ -427,10 +395,13 @@ var Key = class Key {
if (!this._touchPressed &&
event.type() == Clutter.EventType.TOUCH_BEGIN) {
device.sequence_grab(sequence, actor);
this._touchPressed = true;
this._press(key);
} else if (this._touchPressed &&
event.type() == Clutter.EventType.TOUCH_END) {
event.type() == Clutter.EventType.TOUCH_END &&
device.sequence_get_grabbed_actor(sequence) == actor) {
device.sequence_ungrab(sequence);
this._touchPressed = false;
this._release(key);
}
@@ -579,460 +550,10 @@ var FocusTracker = class {
};
Signals.addSignalMethods(FocusTracker.prototype);
var EmojiPager = class EmojiPager {
constructor(sections, nCols, nRows) {
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
reactive: true,
clip_to_allocation: true });
this._sections = sections;
this._nCols = nCols;
this._nRows = nRows;
this._pages = [];
this._panel = null;
this._curPage = null;
this._followingPage = null;
this._followingPanel = null;
this._currentKey = null;
this._delta = 0;
this._width = null;
this._initPagingInfo();
let panAction = new Clutter.PanAction({ interpolate: false });
panAction.connect('pan', this._onPan.bind(this));
panAction.connect('gesture-begin', this._onPanBegin.bind(this));
panAction.connect('gesture-cancel', this._onPanCancel.bind(this));
panAction.connect('gesture-end', this._onPanEnd.bind(this));
this._panAction = panAction;
this.actor.add_action(panAction);
}
get delta() {
return this._delta;
}
set delta(value) {
if (value > this._width)
value = this._width;
else if (value < -this._width)
value = -this._width;
this._delta = value;
if (value == 0)
return;
let relValue = Math.abs(value / this._width);
let followingPage = this.getFollowingPage();
if (this._followingPage != followingPage) {
if (this._followingPanel) {
this._followingPanel.destroy();
this._followingPanel = null;
}
if (followingPage != null) {
this._followingPanel = this._generatePanel(followingPage);
this._followingPanel.set_pivot_point(0.5, 0.5);
this.actor.add_child(this._followingPanel);
this.actor.set_child_below_sibling(this._followingPanel, this._panel);
}
this._followingPage = followingPage;
}
this._panel.translation_x = value;
this._panel.opacity = 255 * (1 - Math.pow(relValue, 3));
if (this._followingPanel) {
this._followingPanel.scale_x = 0.8 + (0.2 * relValue);
this._followingPanel.scale_y = 0.8 + (0.2 * relValue);
this._followingPanel.opacity = 255 * relValue;
}
}
_prevPage(nPage) {
return (nPage + this._pages.length - 1) % this._pages.length;
}
_nextPage(nPage) {
return (nPage + 1) % this._pages.length;
}
getFollowingPage() {
if (this.delta == 0)
return null;
if ((this.delta < 0 && global.stage.text_direction == Clutter.TextDirection.LTR) ||
(this.delta > 0 && global.stage.text_direction == Clutter.TextDirection.RTL))
return this._nextPage(this._curPage);
else
return this._prevPage(this._curPage);
}
_onPan(action) {
let [dist, dx, dy] = action.get_motion_delta(0);
this.delta = this.delta + dx;
if (this._currentKey != null) {
this._currentKey.cancel();
this._currentKey = null;
}
return false;
}
_onPanBegin() {
this._width = this.actor.width;
return true;
}
_onPanEnd() {
if (Math.abs(this._delta) < this.actor.width * PANEL_SWITCH_RELATIVE_DISTANCE) {
this._onPanCancel()
} else {
let value;
if (this._delta > 0)
value = this._width;
else if (this._delta < 0)
value = -this._width;
let relDelta = Math.abs(this._delta - value) / this._width;
let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta);
Tweener.removeTweens(this);
Tweener.addTween(this,
{ delta: value,
time: time,
transition: 'easeInOutQuad',
onComplete() {
this.setCurrentPage(this.getFollowingPage());
}
});
}
}
_onPanCancel() {
let relDelta = Math.abs(this._delta) / this.actor.width;
let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta);
Tweener.removeTweens(this);
Tweener.addTween(this,
{ delta: 0,
time: time,
transition: 'easeInOutQuad',
});
}
_initPagingInfo() {
for (let i = 0; i < this._sections.length; i++) {
let section = this._sections[i];
let itemsPerPage = this._nCols * this._nRows;
let nPages = Math.ceil(section.keys.length / itemsPerPage);
let page = -1;
let pageKeys;
for (let j = 0; j < section.keys.length; j++) {
if (j % itemsPerPage == 0) {
page++;
pageKeys = [];
this._pages.push({ pageKeys, nPages, page, section: this._sections[i] });
}
pageKeys.push(section.keys[j]);
}
}
}
_lookupSection(section, nPage) {
for (let i = 0; i < this._pages.length; i++) {
let page = this._pages[i];
if (page.section == section && page.page == nPage)
return i;
}
return -1;
}
_generatePanel(nPage) {
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true,
row_homogeneous: true });
let panel = new St.Widget({ layout_manager: gridLayout,
style_class: 'emoji-page',
x_expand: true,
y_expand: true });
/* Set an expander actor so all proportions are right despite the panel
* not having all rows/cols filled in.
*/
let expander = new Clutter.Actor();
gridLayout.attach(expander, 0, 0, this._nCols, this._nRows);
let page = this._pages[nPage];
let col = 0;
let row = 0;
for (let i = 0; i < page.pageKeys.length; i++) {
let modelKey = page.pageKeys[i];
let key = new Key(modelKey.label, modelKey.variants);
key.keyButton.set_button_mask(0);
key.connect('activated', () => {
this._currentKey = key;
});
key.connect('long-press', () => {
this._panAction.cancel();
});
key.connect('released', (actor, keyval, str) => {
if (this._currentKey != key)
return;
this._currentKey = null;
this.emit('emoji', str);
});
gridLayout.attach(key.actor, col, row, 1, 1);
col++;
if (col >= this._nCols) {
col = 0;
row++;
}
}
return panel;
}
setCurrentPage(nPage) {
if (this._curPage == nPage)
return;
this._curPage = nPage;
if (this._panel) {
this._panel.destroy();
this._panel = null;
}
/* Reuse followingPage if possible */
if (nPage == this._followingPage) {
this._panel = this._followingPanel;
this._followingPanel = null;
}
if (this._followingPanel)
this._followingPanel.destroy();
this._followingPanel = null;
this._followingPage = null;
this._delta = 0;
if (!this._panel) {
this._panel = this._generatePanel(nPage);
this.actor.add_child(this._panel);
}
let page = this._pages[nPage];
this.emit('page-changed', page.section, page.page, page.nPages);
}
setCurrentSection(section, nPage) {
for (let i = 0; i < this._pages.length; i++) {
let page = this._pages[i];
if (page.section == section && page.page == nPage) {
this.setCurrentPage(i);
break;
}
}
}
};
Signals.addSignalMethods(EmojiPager.prototype);
var EmojiSelection = class EmojiSelection {
constructor() {
this._sections = [
{ first: 'grinning face', label: '🙂️' },
{ first: 'selfie', label: '👍️' },
{ first: 'monkey face', label: '🌷️' },
{ first: 'grapes', label: '🍴️' },
{ first: 'globe showing Europe-Africa', label: '✈️' },
{ first: 'jack-o-lantern', label: '🏃️' },
{ first: 'muted speaker', label: '🔔️' },
{ first: 'ATM sign', label: '❤️' },
{ first: 'chequered flag', label: '🚩️' },
];
this._populateSections();
this.actor = new St.BoxLayout({ style_class: 'emoji-panel',
x_expand: true,
y_expand: true,
vertical: true });
this.actor.connect('notify::mapped', () => { this._emojiPager.setCurrentPage(0); });
this._emojiPager = new EmojiPager(this._sections, 11, 3);
this._emojiPager.connect('page-changed', (pager, section, page, nPages) => {
this._onPageChanged(section, page, nPages);
});
this._emojiPager.connect('emoji', (pager, str) => {
this.emit('emoji-selected', str);
});
this.actor.add(this._emojiPager.actor, { expand: true });
this._pageIndicator = new PageIndicators.PageIndicators(false);
this.actor.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
this._pageIndicator.setReactive(false);
let bottomRow = this._createBottomRow();
this.actor.add(bottomRow, { x_fill: true, y_fill: false });
this._emojiPager.setCurrentPage(0);
}
_onPageChanged(section, page, nPages) {
this._pageIndicator.setNPages(nPages);
this._pageIndicator.setCurrentPage(page);
for (let i = 0; i < this._sections.length; i++) {
let sect = this._sections[i];
sect.button.setLatched(section == sect);
}
}
_findSection(emoji) {
for (let i = 0; i < this._sections.length; i++) {
if (this._sections[i].first == emoji)
return this._sections[i];
}
return null;
}
_populateSections() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/osk-layouts/emoji.json');
let [success, contents] = file.load_contents(null);
if (contents instanceof Uint8Array)
contents = imports.byteArray.toString(contents);
let emoji = JSON.parse(contents);
let pages = [];
let variants = [];
let currentKey = 0;
let currentSection = null;
for (let i = 0; i < emoji.length; i++) {
/* Group variants of a same emoji so they appear on the key popover */
if (emoji[i].name.startsWith(emoji[currentKey].name)) {
variants.push(emoji[i].char);
if (i < emoji.length - 1)
continue;
}
let newSection = this._findSection(emoji[currentKey].name);
if (newSection != null) {
currentSection = newSection;
currentSection.keys = [];
}
/* Create the key */
let label = emoji[currentKey].char + String.fromCharCode(0xFE0F);
currentSection.keys.push({ label, variants });
currentKey = i;
variants = [];
}
}
_createBottomRow() {
let row = new KeyContainer();
let key;
row.appendRow();
key = new Key('ABC', []);
key.keyButton.add_style_class_name('default-key');
key.connect('released', () => { this.emit('toggle'); });
row.appendKey(key.actor, 1.5);
for (let i = 0; i < this._sections.length; i++) {
let section = this._sections[i];
key = new Key(section.label, []);
key.connect('released', () => { this._emojiPager.setCurrentSection(section, 0) });
row.appendKey(key.actor);
section.button = key;
}
key = new Key(null, []);
key.keyButton.add_style_class_name('default-key');
key.keyButton.add_style_class_name('hide-key');
key.connect('released', () => {
this.emit('hide');
});
row.appendKey(key.actor);
row.layoutButtons();
return row;
}
};
Signals.addSignalMethods(EmojiSelection.prototype);
var Keypad = class Keypad {
constructor() {
let keys = [
{ label: '1', keyval: Clutter.KEY_1, left: 0, top: 0 },
{ label: '2', keyval: Clutter.KEY_2, left: 1, top: 0 },
{ label: '3', keyval: Clutter.KEY_3, left: 2, top: 0 },
{ label: '4', keyval: Clutter.KEY_4, left: 0, top: 1 },
{ label: '5', keyval: Clutter.KEY_5, left: 1, top: 1 },
{ label: '6', keyval: Clutter.KEY_6, left: 2, top: 1 },
{ label: '7', keyval: Clutter.KEY_7, left: 0, top: 2 },
{ label: '8', keyval: Clutter.KEY_8, left: 1, top: 2 },
{ label: '9', keyval: Clutter.KEY_9, left: 2, top: 2 },
{ label: '0', keyval: Clutter.KEY_0, left: 1, top: 3 },
{ label: '⌫', keyval: Clutter.KEY_BackSpace, left: 3, top: 0 },
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
];
this.actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true });
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true,
row_homogeneous: true });
this._box = new St.Widget({ layout_manager: gridLayout, x_expand: true, y_expand: true });
this.actor.add_child(this._box);
for (let i = 0; i < keys.length; i++) {
let cur = keys[i];
let key = new Key(cur.label || "", []);
if (keys[i].extraClassName)
key.keyButton.add_style_class_name(cur.extraClassName);
let w, h;
w = cur.width || 1;
h = cur.height || 1;
gridLayout.attach(key.actor, cur.left, cur.top, w, h);
key.connect('released', () => {
this.emit('keyval', cur.keyval);
});
}
}
};
Signals.addSignalMethods(Keypad.prototype);
var Keyboard = class Keyboard {
constructor() {
this.actor = null;
this._focusInExtendedKeys = false;
this._emojiActive = false;
this._languagePopup = null;
this._currentFocusWindow = null;
@@ -1047,7 +568,6 @@ var Keyboard = class Keyboard {
this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
this._lastDeviceId = null;
this._suggestions = null;
this._emojiKeyVisible = true;
this._focusTracker = new FocusTracker();
this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
@@ -1136,10 +656,6 @@ var Keyboard = class Keyboard {
this._keyboardController.disconnect(this._keyboardGroupsChangedId);
if (this._keyboardStateId)
this._keyboardController.disconnect(this._keyboardStateId);
if (this._emojiKeyVisibleId)
this._keyboardController.disconnect(this._emojiKeyVisibleId);
if (this._keypadVisibleId)
this._keyboardController.disconnect(this._keypadVisibleId);
if (this._focusNotifyId)
global.stage.disconnect(this._focusNotifyId);
this._keyboard = null;
@@ -1163,32 +679,13 @@ var Keyboard = class Keyboard {
this._current_page = null;
this._suggestions = new Suggestions();
this._suggestions.connect('suggestion-clicked', (suggestions, str) => {
this._keyboardController.commitString(str);
});
this.actor.add(this._suggestions.actor,
{ x_align: St.Align.MIDDLE,
x_fill: false });
this._aspectContainer = new AspectContainer({ layout_manager: new Clutter.BinLayout() });
this.actor.add(this._aspectContainer, { expand: true });
this._emojiSelection = new EmojiSelection();
this._emojiSelection.connect('toggle', this._toggleEmoji.bind(this));
this._emojiSelection.connect('hide', (selection) => { this.hide(); });
this._emojiSelection.connect('emoji-selected', (selection, emoji) => {
this._keyboardController.commitString(emoji);
});
this._aspectContainer.add_child(this._emojiSelection.actor);
this._emojiSelection.actor.hide();
this._keypad = new Keypad();
this._keypad.connect('keyval', (keypad, keyval) => {
this._keyboardController.keyvalPress(keyval);
this._keyboardController.keyvalRelease(keyval);
});
this._aspectContainer.add_child(this._keypad.actor);
this._keypad.actor.hide();
this._keypadVisible = false;
this._ensureKeysForGroup(this._keyboardController.getCurrentGroup());
this._setActiveLayer(0);
@@ -1200,8 +697,6 @@ var Keyboard = class Keyboard {
this._keyboardNotifyId = this._keyboardController.connect('active-group', this._onGroupChanged.bind(this));
this._keyboardGroupsChangedId = this._keyboardController.connect('groups-changed', this._onKeyboardGroupsChanged.bind(this));
this._keyboardStateId = this._keyboardController.connect('panel-state', this._onKeyboardStateChanged.bind(this));
this._emojiKeyVisibleId = this._keyboardController.connect('emoji-visible', this._onEmojiKeyVisible.bind(this));
this._keypadVisibleId = this._keyboardController.connect('keypad-visible', this._onKeypadVisible.bind(this));
this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
this._relayout();
@@ -1248,12 +743,11 @@ var Keyboard = class Keyboard {
this._loadRows(currentLevel, level, levels.length, layout);
layers[level] = layout;
this._aspectContainer.add_child(layout);
layout.layoutButtons(this._aspectContainer);
this.actor.add(layout, { expand: true });
layout.layoutButtons();
layout.hide();
}
return layers;
}
@@ -1312,11 +806,7 @@ var Keyboard = class Keyboard {
let switchToLevel = key.level;
let action = key.action;
/* Skip emoji button if necessary */
if (!this._emojiKeyVisible && action == 'emoji')
continue;
extraButton = new Key(key.label || '', []);
extraButton = new Key(key.label, []);
extraButton.keyButton.add_style_class_name('default-key');
if (key.extraClassName != null)
@@ -1342,8 +832,6 @@ var Keyboard = class Keyboard {
this.hide();
else if (action == 'languageMenu')
this._popupLanguageMenu(actor);
else if (action == 'emoji')
this._toggleEmoji();
});
if (switchToLevel == 0) {
@@ -1369,31 +857,14 @@ var Keyboard = class Keyboard {
extraButton.setWidth(2);
} else if (keyval == Clutter.KEY_Return && numKeys > 9) {
extraButton.setWidth(1.5);
} else if (!this._emojiKeyVisible && (action == 'hide' || action == 'languageMenu')) {
extraButton.setWidth(1.5);
}
layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth);
}
}
_updateCurrentPageVisible() {
if (this._current_page)
this._current_page.visible = !this._emojiActive && !this._keypadVisible;
}
_setEmojiActive(active) {
this._emojiActive = active;
this._emojiSelection.actor.visible = this._emojiActive;
this._updateCurrentPageVisible();
}
_toggleEmoji() {
this._setEmojiActive(!this._emojiActive);
}
_setCurrentLevelLatched(layout, latched) {
for (let i = 0; i < layout.shiftKeys.length; i++) {
for (let i = 0; layout.shiftKeys[i]; i++) {
let key = layout.shiftKeys[i];
key.setLatched(latched);
}
@@ -1472,24 +943,6 @@ var Keyboard = class Keyboard {
this._onGroupChanged();
}
_onKeypadVisible(controller, visible) {
if (visible == this._keypadVisible)
return;
this._keypadVisible = visible;
this._keypad.actor.visible = this._keypadVisible;
this._updateCurrentPageVisible();
}
_onEmojiKeyVisible(controller, visible) {
if (visible == this._emojiKeyVisible)
return;
this._emojiKeyVisible = visible;
/* Rebuild keyboard widgetry to include emoji button */
this._onKeyboardGroupsChanged();
}
_onKeyboardStateChanged(controller, state) {
let enabled;
if (state == Clutter.InputPanelState.OFF)
@@ -1517,7 +970,7 @@ var Keyboard = class Keyboard {
}
this._current_page = layers[activeLevel];
this._updateCurrentPageVisible();
this._current_page.show();
}
shouldTakeEvent(event) {
@@ -1567,8 +1020,6 @@ var Keyboard = class Keyboard {
this._relayout();
Main.layoutManager.showKeyboard();
this._setEmojiActive(false);
if (this._delayedAnimFocusWindow) {
this._setAnimationWindow(this._delayedAnimFocusWindow);
this._delayedAnimFocusWindow = null;
@@ -1736,21 +1187,8 @@ var KeyboardController = class {
_onContentPurposeHintsChanged(method) {
let hints = method.content_hints;
let purpose = method.content_purpose;
let emojiVisible = false;
let keypadVisible = false;
if (purpose == Clutter.InputContentPurpose.NORMAL ||
purpose == Clutter.InputContentPurpose.ALPHA ||
purpose == Clutter.InputContentPurpose.PASSWORD ||
purpose == Clutter.InputContentPurpose.TERMINAL)
emojiVisible = true;
if (purpose == Clutter.InputContentPurpose.DIGITS ||
purpose == Clutter.InputContentPurpose.NUMBER ||
purpose == Clutter.InputContentPurpose.PHONE)
keypadVisible = true;
this.emit('emoji-visible', emojiVisible)
this.emit('keypad-visible', keypadVisible);
// XXX: hook numeric/emoji/etc special keyboards
}
getGroups() {

View File

@@ -5,6 +5,7 @@ const Cogl = imports.gi.Cogl;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
@@ -186,7 +187,7 @@ var Notebook = class Notebook {
// Focus the new tab before unmapping the old one
let tabData = this._tabs[index];
if (!tabData.scrollView.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
if (!tabData.scrollView.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
this.actor.grab_key_focus();
this._unselect();

View File

@@ -2,11 +2,9 @@
const Atspi = imports.gi.Atspi;
const Clutter = imports.gi.Clutter;
const Cogl = imports.gi.Cogl;
const GDesktopEnums = imports.gi.GDesktopEnums;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Mainloop = imports.mainloop;
@@ -54,51 +52,6 @@ const CROSS_HAIRS_CLIP_KEY = 'cross-hairs-clip';
let magDBusService = null;
var MouseSpriteContent = GObject.registerClass({
Implements: [ Clutter.Content ],
}, class MouseSpriteContent extends GObject.Object {
_init() {
super._init();
this._texture = null;
}
vfunc_get_preferred_size() {
if (!this._texture)
return [0, 0];
return [this._texture.get_width(), this._texture.get_height()];
}
vfunc_paint_content(actor, node) {
if (!this._texture)
return;
let color = new Cogl.Color();
color.init_from_4ub(0, 0, 0, 0);
let textureNode = new Clutter.TextureNode(this._texture,
color,
Clutter.ScalingFilter.NEAREST,
Clutter.ScalingFilter.NEAREST);
textureNode.set_name('MouseSpriteContent');
node.add_child(textureNode);
textureNode.add_rectangle(actor.get_content_box());
}
get texture() {
return this._texture;
}
set texture(coglTexture) {
if (this._texture == coglTexture)
return;
this._texture = coglTexture;
this.invalidate();
}
});
var Magnifier = class Magnifier {
constructor() {
// Magnifier is a manager of ZoomRegions.
@@ -106,12 +59,8 @@ var Magnifier = class Magnifier {
// Create small clutter tree for the magnified mouse.
let cursorTracker = Meta.CursorTracker.get_for_display(global.display);
this._cursorTracker = cursorTracker;
this._mouseSprite = new Clutter.Actor({ request_mode: Clutter.RequestMode.CONTENT_SIZE });
this._mouseSprite.content = new MouseSpriteContent();
this._updateSpriteTexture();
this._mouseSprite = new Clutter.Texture();
Shell.util_cursor_tracker_to_clutter(cursorTracker, this._mouseSprite);
this._cursorRoot = new Clutter.Actor();
this._cursorRoot.add_actor(this._mouseSprite);
@@ -127,6 +76,7 @@ var Magnifier = class Magnifier {
aZoomRegion.scrollContentsTo(this.xMouse, this.yMouse);
cursorTracker.connect('cursor-changed', this._updateMouseSprite.bind(this));
this._cursorTracker = cursorTracker;
// Export to dbus.
magDBusService = new MagnifierDBus.ShellMagnifier();
@@ -486,22 +436,11 @@ var Magnifier = class Magnifier {
//// Private methods ////
_updateMouseSprite() {
this._updateSpriteTexture();
Shell.util_cursor_tracker_to_clutter(this._cursorTracker, this._mouseSprite);
let [xHot, yHot] = this._cursorTracker.get_hot();
this._mouseSprite.set_anchor_point(xHot, yHot);
}
_updateSpriteTexture() {
let sprite = this._cursorTracker.get_sprite();
if (sprite) {
this._mouseSprite.content.texture = sprite;
this._mouseSprite.show();
} else {
this._mouseSprite.hide();
}
}
_settingsInit(zoomRegion) {
this._appSettings = new Gio.Settings({ schema_id: APPLICATIONS_SCHEMA });
this._settings = new Gio.Settings({ schema_id: MAGNIFIER_SCHEMA });

View File

@@ -1,8 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -126,8 +128,9 @@ function start() {
sessionMode = new SessionMode.SessionMode();
sessionMode.connect('updated', _sessionUpdated);
St.Settings.get().connect('notify::gtk-theme', _loadDefaultStylesheet);
Gtk.Settings.get_default().connect('notify::gtk-theme-name',
_loadDefaultStylesheet);
Gtk.IconTheme.get_default().add_resource_path('/org/gnome/shell/theme/icons');
_initializeUI();
shellAccessDialogDBusService = new AccessDialog.AccessDialogDBus();
@@ -277,7 +280,7 @@ function _getDefaultStylesheet() {
// Look for a high-contrast variant first when using GTK+'s HighContrast
// theme
if (St.Settings.get().gtk_theme == 'HighContrast')
if (Gtk.Settings.get_default().gtk_theme_name == 'HighContrast')
stylesheet = _getStylesheet(name.replace('.css', '-high-contrast.css'));
if (stylesheet == null)

View File

@@ -159,7 +159,7 @@ var URLHighlighter = class URLHighlighter {
}
};
var ScaleLayout = GObject.registerClass(
var ScaleLayout = new GObject.registerClass(
class ScaleLayout extends Clutter.BinLayout {
_init(params) {
this._container = null;

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Atk = imports.gi.Atk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@@ -70,17 +71,6 @@ var Urgency = {
CRITICAL: 3
};
// The privacy of the details of a notification. USER is for notifications which
// contain private information to the originating user account (for example,
// details of an e-mail theyve received). SYSTEM is for notifications which
// contain information private to the physical system (for example, battery
// status) and hence the same for every user. This affects whether the content
// of a notification is shown on the lock screen.
var PrivacyScope = {
USER: 0,
SYSTEM: 1,
};
var FocusGrabber = class FocusGrabber {
constructor(actor) {
this._actor = actor;
@@ -97,7 +87,7 @@ var FocusGrabber = class FocusGrabber {
this._focusActorChangedId = global.stage.connect('notify::key-focus', this._focusActorChanged.bind(this));
if (!this._actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
if (!this._actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
this._actor.grab_key_focus();
this._focused = true;
@@ -350,7 +340,6 @@ var Notification = class Notification {
this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false;
this.privacyScope = PrivacyScope.USER;
this.forFeedback = false;
this._acknowledged = false;
this.bannerBodyText = null;
@@ -447,10 +436,6 @@ var Notification = class Notification {
this.forFeedback = forFeedback;
}
setPrivacyScope(privacyScope) {
this.privacyScope = privacyScope;
}
playSound() {
if (this._soundPlayed)
return;
@@ -512,12 +497,9 @@ class NotificationBanner extends Calendar.NotificationMessage {
});
}
_disconnectNotificationSignals() {
super._disconnectNotificationSignals();
if (this._activatedId)
this.notification.disconnect(this._activatedId);
this._activatedId = 0;
_onDestroy() {
super._onDestroy();
this.notification.disconnect(this._activatedId);
}
_onUpdated(n, clear) {
@@ -737,11 +719,6 @@ var Source = class Source {
return new NotificationPolicy();
}
get narrowestPrivacyScope() {
return this.notifications.every(n => n.privacyScope == PrivacyScope.SYSTEM) ? PrivacyScope.SYSTEM
: PrivacyScope.USER;
}
setTitle(newTitle) {
this.title = newTitle;
this.emit('title-changed');

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Meta = imports.gi.Meta;
@@ -196,6 +197,7 @@ var ModalDialog = class {
else
this._savedKeyFocus = null;
Main.popModal(this._group, timestamp);
Gdk.Display.get_default().sync();
this._hasModal = false;
if (!this._shellReactive)

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Shell = imports.gi.Shell;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
@@ -351,10 +352,6 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
// of the 'transient' hint with hints['transient'] rather than hints.transient
notification.setTransient(!!hints['transient']);
let privacyScope = (hints['x-gnome-privacy-scope'] || 'user');
notification.setPrivacyScope(privacyScope == 'system' ? MessageTray.PrivacyScope.SYSTEM
: MessageTray.PrivacyScope.USER);
let sourceGIcon = source.useNotificationIcon ? gicon : null;
source.processNotification(notification, sourceGIcon);
}

View File

@@ -2,11 +2,13 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk;
const Background = imports.ui.background;
const DND = imports.ui.dnd;
@@ -156,6 +158,7 @@ var Overview = class {
this._windowSwitchTimestamp = 0;
this._lastActiveWorkspaceIndex = -1;
this._lastHoveredWindow = null;
this._needsFakePointerEvent = false;
if (this._initCalled)
this.init();
@@ -303,9 +306,19 @@ var Overview = class {
if (this._windowSwitchTimeoutId != 0) {
Mainloop.source_remove(this._windowSwitchTimeoutId);
this._windowSwitchTimeoutId = 0;
this._needsFakePointerEvent = false;
}
}
_fakePointerEvent() {
let display = Gdk.Display.get_default();
let deviceManager = display.get_device_manager();
let pointer = deviceManager.get_client_pointer();
let [gdkScreen, pointerX, pointerY] = pointer.get_position();
pointer.warp(gdkScreen, pointerX, pointerY);
}
_onDragMotion(dragEvent) {
let targetIsWindow = dragEvent.targetActor &&
dragEvent.targetActor._delegate &&
@@ -327,6 +340,7 @@ var Overview = class {
this._windowSwitchTimeoutId = Mainloop.timeout_add(DND_WINDOW_SWITCH_TIMEOUT,
() => {
this._windowSwitchTimeoutId = 0;
this._needsFakePointerEvent = true;
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
this._windowSwitchTimestamp);
this.hide();
@@ -373,6 +387,9 @@ var Overview = class {
// when it is next shown.
this.hide();
if (!Main.layoutManager.primaryMonitor)
return;
this._coverPane.set_position(0, 0);
this._coverPane.set_size(global.screen_width, global.screen_height);
@@ -629,6 +646,12 @@ var Overview = class {
Main.layoutManager.hideOverview();
this._syncGrab();
// Fake a pointer event if requested
if (this._needsFakePointerEvent) {
this._fakePointerEvent();
this._needsFakePointerEvent = false;
}
}
toggle() {

View File

@@ -1,142 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const St = imports.gi.St;
const Tweener = imports.ui.tweener;
const { ANIMATION_TIME_OUT, ANIMATION_MAX_DELAY_OUT_FOR_ITEM, AnimationDirection } = imports.ui.iconGrid;
var INDICATORS_BASE_TIME = 0.25;
var INDICATORS_BASE_TIME_OUT = 0.125;
var INDICATORS_ANIMATION_DELAY = 0.125;
var INDICATORS_ANIMATION_DELAY_OUT = 0.0625;
var INDICATORS_ANIMATION_MAX_TIME = 0.75;
var SWITCH_TIME = 0.4;
var INDICATORS_ANIMATION_MAX_TIME_OUT =
Math.min (SWITCH_TIME,
ANIMATION_TIME_OUT + ANIMATION_MAX_DELAY_OUT_FOR_ITEM);
var ANIMATION_DELAY = 0.1;
var PageIndicators = GObject.registerClass({
Signals: { 'page-activated': { param_types: [GObject.TYPE_INT] } }
}, class PageIndicators extends St.BoxLayout {
_init(vertical = true) {
super._init({ style_class: 'page-indicators',
vertical,
x_expand: true, y_expand: true,
x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER,
y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END,
reactive: true,
clip_to_allocation: true });
this._nPages = 0;
this._currentPage = undefined;
this._reactive = true;
this._reactive = true;
}
vfunc_get_preferred_height(forWidth) {
// We want to request the natural height of all our children as our
// natural height, so we chain up to St.BoxLayout, but we only request 0
// as minimum height, since it's not that important if some indicators
// are not shown
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
return [0, natHeight];
}
setReactive(reactive) {
let children = this.get_children();
for (let i = 0; i < children.length; i++)
children[i].reactive = reactive;
this._reactive = reactive;
}
setNPages(nPages) {
if (this._nPages == nPages)
return;
let diff = nPages - this._nPages;
if (diff > 0) {
for (let i = 0; i < diff; i++) {
let pageIndex = this._nPages + i;
let indicator = new St.Button({ style_class: 'page-indicator',
button_mask: St.ButtonMask.ONE |
St.ButtonMask.TWO |
St.ButtonMask.THREE,
toggle_mode: true,
reactive: this._reactive,
checked: pageIndex == this._currentPage });
indicator.child = new St.Widget({ style_class: 'page-indicator-icon' });
indicator.connect('clicked', () => {
this.emit('page-activated', pageIndex);
});
this.add_actor(indicator);
}
} else {
let children = this.get_children().splice(diff);
for (let i = 0; i < children.length; i++)
children[i].destroy();
}
this._nPages = nPages;
this.visible = (this._nPages > 1);
}
setCurrentPage(currentPage) {
this._currentPage = currentPage;
let children = this.get_children();
for (let i = 0; i < children.length; i++)
children[i].set_checked(i == this._currentPage);
}
});
var AnimatedPageIndicators = GObject.registerClass(
class AnimatedPageIndicators extends PageIndicators {
_init() {
super._init(true);
this.connect('notify::mapped', () => {
this.animateIndicators(AnimationDirection.IN);
});
}
animateIndicators(animationDirection) {
if (!this.mapped)
return;
let children = this.get_children();
if (children.length == 0)
return;
for (let i = 0; i < this._nPages; i++)
Tweener.removeTweens(children[i]);
let offset;
if (this.get_text_direction() == Clutter.TextDirection.RTL)
offset = -children[0].width;
else
offset = children[0].width;
let isAnimationIn = animationDirection == AnimationDirection.IN;
let delay = isAnimationIn ? INDICATORS_ANIMATION_DELAY :
INDICATORS_ANIMATION_DELAY_OUT;
let baseTime = isAnimationIn ? INDICATORS_BASE_TIME : INDICATORS_BASE_TIME_OUT;
let totalAnimationTime = baseTime + delay * this._nPages;
let maxTime = isAnimationIn ? INDICATORS_ANIMATION_MAX_TIME :
INDICATORS_ANIMATION_MAX_TIME_OUT;
if (totalAnimationTime > maxTime)
delay -= (totalAnimationTime - maxTime) / this._nPages;
for (let i = 0; i < this._nPages; i++) {
children[i].translation_x = isAnimationIn ? offset : 0;
Tweener.addTween(children[i], {
translation_x: isAnimationIn ? 0 : offset,
time: baseTime + delay * i,
transition: 'easeInOutQuad',
delay: isAnimationIn ? ANIMATION_DELAY : 0
});
}
}
});

View File

@@ -2,19 +2,15 @@
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const Animation = imports.ui.animation;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
@@ -22,15 +18,9 @@ const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
var PANEL_ICON_SIZE = 16;
var APP_MENU_ICON_MARGIN = 0;
var BUTTON_DND_ACTIVATION_TIMEOUT = 250;
var SPINNER_ANIMATION_TIME = 1.0;
// To make sure the panel corners blend nicely with the panel,
// we draw background and borders the same way, e.g. drawing
// them as filled shapes from the outside inwards instead of
@@ -74,395 +64,6 @@ function _unpremultiply(color) {
blue: blue, alpha: color.alpha });
};
class AppMenu extends PopupMenu.PopupMenu {
constructor(sourceActor) {
super(sourceActor, 0.0, St.Side.TOP);
this.actor.add_style_class_name('app-menu');
this._app = null;
this._appSystem = Shell.AppSystem.get_default();
this._windowsChangedId = 0;
this._windowSection = new PopupMenu.PopupMenuSection();
this.addMenuItem(this._windowSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._newWindowItem = this.addAction(_("New Window"), () => {
this._app.open_new_window(-1);
});
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._actionSection = new PopupMenu.PopupMenuSection();
this.addMenuItem(this._actionSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._detailsItem = this.addAction(_("Show Details"), () => {
let id = this._app.get_id();
let args = GLib.Variant.new('(ss)', [id, '']);
Gio.DBus.get(Gio.BusType.SESSION, null, (o, res) => {
let bus = Gio.DBus.get_finish(res);
bus.call('org.gnome.Software',
'/org/gnome/Software',
'org.gtk.Actions', 'Activate',
GLib.Variant.new('(sava{sv})',
['details', [args], null]),
null, 0, -1, null, null);
});
});
this.addAction(_("Quit"), () => {
this._app.request_quit();
});
this._appSystem.connect('installed-changed', () => {
let sw = this._appSystem.lookup_app('org.gnome.Software.desktop');
this._detailsItem.actor.visible = (sw != null);
});
}
isEmpty() {
if (!this._app)
return true;
return super.isEmpty();
}
setApp(app) {
if (this._app == app)
return;
if (this._windowsChangedId)
this._app.disconnect(this._windowsChangedId);
this._windowsChangedId = 0;
this._app = app;
if (app) {
this._windowsChangedId = app.connect('windows-changed', () => {
this._updateWindowsSection();
});
}
this._updateWindowsSection();
let appInfo = app ? app.app_info : null;
let actions = appInfo ? appInfo.list_actions() : [];
this._actionSection.removeAll();
actions.forEach(action => {
let label = appInfo.get_action_name(action);
this._actionSection.addAction(label, event => {
this._app.launch_action(action, event.get_time(), -1);
});
});
this._newWindowItem.actor.visible =
app && app.can_open_new_window() && !actions.includes('new-window');
}
_updateWindowsSection() {
this._windowSection.removeAll();
if (!this._app)
return;
let windows = this._app.get_windows();
windows.forEach(window => {
let title = window.title || this._app.get_name();
this._windowSection.addAction(title, event => {
Main.activateWindow(window, event.get_time());
});
});
// Add separator between windows of the current desktop and other windows.
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let pos = windows.findIndex(w => w.get_workspace() != activeWorkspace);
if (pos >= 0)
this._windowSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem(), pos);
}
}
/**
* AppMenuButton:
*
* This class manages the "application menu" component. It tracks the
* currently focused application. However, when an app is launched,
* this menu also handles startup notification for it. So when we
* have an active startup notification, we switch modes to display that.
*/
var AppMenuButton = GObject.registerClass({
Signals: {'changed': {}},
}, class AppMenuButton extends PanelMenu.Button {
_init(panel) {
super._init(0.0, null, true);
this.actor.accessible_role = Atk.Role.MENU;
this._startingApps = [];
this._menuManager = panel.menuManager;
this._gtkSettings = Gtk.Settings.get_default();
this._targetApp = null;
this._busyNotifyId = 0;
let bin = new St.Bin({ name: 'appMenu' });
bin.connect('style-changed', this._onStyleChanged.bind(this));
this.actor.add_actor(bin);
this.actor.bind_property("reactive", this.actor, "can-focus", 0);
this.actor.reactive = false;
this._container = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
bin.set_child(this._container);
let textureCache = St.TextureCache.get_default();
textureCache.connect('icon-theme-changed',
this._onIconThemeChanged.bind(this));
let iconEffect = new Clutter.DesaturateEffect();
this._iconBox = new St.Bin({ style_class: 'app-menu-icon' });
this._iconBox.add_effect(iconEffect);
this._container.add_actor(this._iconBox);
this._iconBox.connect('style-changed', () => {
let themeNode = this._iconBox.get_theme_node();
iconEffect.enabled = themeNode.get_icon_style() == St.IconStyle.SYMBOLIC;
});
this._label = new St.Label({ y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this._container.add_actor(this._label);
this._arrow = PopupMenu.arrowIcon(St.Side.BOTTOM);
this._container.add_actor(this._arrow);
this._visible = !Main.overview.visible;
if (!this._visible)
this.hide();
this._overviewHidingId = Main.overview.connect('hiding', this._sync.bind(this));
this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this));
this._stop = true;
this._spinner = null;
let menu = new AppMenu(this);
this.setMenu(menu);
this._menuManager.addMenu(menu);
let tracker = Shell.WindowTracker.get_default();
let appSys = Shell.AppSystem.get_default();
this._focusAppNotifyId =
tracker.connect('notify::focus-app', this._focusAppChanged.bind(this));
this._appStateChangedSignalId =
appSys.connect('app-state-changed', this._onAppStateChanged.bind(this));
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', this._sync.bind(this));
this._sync();
}
fadeIn() {
if (this._visible)
return;
this._visible = true;
this.actor.reactive = true;
this.show();
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor,
{ opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' });
}
fadeOut() {
if (!this._visible)
return;
this._visible = false;
this.actor.reactive = false;
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor,
{ opacity: 0,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete() {
this.hide();
},
onCompleteScope: this });
}
_onStyleChanged(actor) {
let node = actor.get_theme_node();
let [success, icon] = node.lookup_url('spinner-image', false);
if (!success || (this._spinnerIcon && this._spinnerIcon.equal(icon)))
return;
this._spinnerIcon = icon;
this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
}
_syncIcon() {
if (!this._targetApp)
return;
let icon = this._targetApp.create_icon_texture(PANEL_ICON_SIZE - APP_MENU_ICON_MARGIN);
this._iconBox.set_child(icon);
}
_onIconThemeChanged() {
if (this._iconBox.child == null)
return;
this._syncIcon();
}
stopAnimation() {
if (this._stop)
return;
this._stop = true;
if (this._spinner == null)
return;
Tweener.addTween(this._spinner.actor,
{ opacity: 0,
time: SPINNER_ANIMATION_TIME,
transition: "easeOutQuad",
onCompleteScope: this,
onComplete() {
this._spinner.stop();
this._spinner.actor.opacity = 255;
this._spinner.actor.hide();
}
});
}
startAnimation() {
this._stop = false;
if (this._spinner == null)
return;
this._spinner.play();
this._spinner.actor.show();
}
_onAppStateChanged(appSys, app) {
let state = app.state;
if (state != Shell.AppState.STARTING)
this._startingApps = this._startingApps.filter(a => a != app);
else if (state == Shell.AppState.STARTING)
this._startingApps.push(app);
// For now just resync on all running state changes; this is mainly to handle
// cases where the focused window's application changes without the focus
// changing. An example case is how we map OpenOffice.org based on the window
// title which is a dynamic property.
this._sync();
}
_focusAppChanged() {
let tracker = Shell.WindowTracker.get_default();
let focusedApp = tracker.focus_app;
if (!focusedApp) {
// If the app has just lost focus to the panel, pretend
// nothing happened; otherwise you can't keynav to the
// app menu.
if (global.stage.key_focus != null)
return;
}
this._sync();
}
_findTargetApp() {
let workspaceManager = global.workspace_manager;
let workspace = workspaceManager.get_active_workspace();
let tracker = Shell.WindowTracker.get_default();
let focusedApp = tracker.focus_app;
if (focusedApp && focusedApp.is_on_workspace(workspace))
return focusedApp;
for (let i = 0; i < this._startingApps.length; i++)
if (this._startingApps[i].is_on_workspace(workspace))
return this._startingApps[i];
return null;
}
_sync() {
let targetApp = this._findTargetApp();
if (this._targetApp != targetApp) {
if (this._busyNotifyId) {
this._targetApp.disconnect(this._busyNotifyId);
this._busyNotifyId = 0;
}
this._targetApp = targetApp;
if (this._targetApp) {
this._busyNotifyId = this._targetApp.connect('notify::busy', this._sync.bind(this));
this._label.set_text(this._targetApp.get_name());
this.actor.set_accessible_name(this._targetApp.get_name());
}
}
let visible = (this._targetApp != null && !Main.overview.visibleTarget);
if (visible)
this.fadeIn();
else
this.fadeOut();
let isBusy = (this._targetApp != null &&
(this._targetApp.get_state() == Shell.AppState.STARTING ||
this._targetApp.get_busy()));
if (isBusy)
this.startAnimation();
else
this.stopAnimation();
this.actor.reactive = (visible && !isBusy);
this._syncIcon();
this.menu.setApp(this._targetApp);
this.emit('changed');
}
_onDestroy() {
if (this._appStateChangedSignalId > 0) {
let appSys = Shell.AppSystem.get_default();
appSys.disconnect(this._appStateChangedSignalId);
this._appStateChangedSignalId = 0;
}
if (this._focusAppNotifyId > 0) {
let tracker = Shell.WindowTracker.get_default();
tracker.disconnect(this._focusAppNotifyId);
this._focusAppNotifyId = 0;
}
if (this._overviewHidingId > 0) {
Main.overview.disconnect(this._overviewHidingId);
this._overviewHidingId = 0;
}
if (this._overviewShowingId > 0) {
Main.overview.disconnect(this._overviewShowingId);
this._overviewShowingId = 0;
}
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
}
super._onDestroy();
}
});
var ActivitiesButton = GObject.registerClass(
class ActivitiesButton extends PanelMenu.Button {
_init() {
@@ -821,7 +422,6 @@ class AggregateMenu extends PanelMenu.Button {
const PANEL_ITEM_IMPLEMENTATIONS = {
'activities': ActivitiesButton,
'aggregateMenu': AggregateMenu,
'appMenu': AppMenuButton,
'dateMenu': imports.ui.dateMenu.DateMenuButton,
'a11y': imports.ui.status.accessibility.ATIndicator,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
@@ -840,6 +440,8 @@ class Panel extends St.Widget {
this._sessionStyle = null;
Meta.prefs_set_show_fallback_app_menu(true);
this.statusArea = {};
this.menuManager = new PopupMenu.PopupMenuManager(this);
@@ -863,9 +465,11 @@ class Panel extends St.Widget {
Main.overview.connect('showing', () => {
this.add_style_pseudo_class('overview');
this._updateSolidStyle();
});
Main.overview.connect('hiding', () => {
this.remove_style_pseudo_class('overview');
this._updateSolidStyle();
});
Main.layoutManager.panelBox.add(this);
@@ -874,11 +478,32 @@ class Panel extends St.Widget {
Main.sessionMode.connect('updated', this._updatePanel.bind(this));
this._trackedWindows = new Map();
global.window_group.connect('actor-added', this._onWindowActorAdded.bind(this));
global.window_group.connect('actor-removed', this._onWindowActorRemoved.bind(this));
global.window_manager.connect('switch-workspace', this._updateSolidStyle.bind(this));
global.display.connect('workareas-changed', () => { this.queue_relayout(); });
this._updatePanel();
}
vfunc_get_preferred_width(forHeight) {
_onWindowActorAdded(container, metaWindowActor) {
let signalIds = [];
['allocation-changed', 'notify::visible'].forEach(s => {
signalIds.push(metaWindowActor.connect(s, this._updateSolidStyle.bind(this)));
});
this._trackedWindows.set(metaWindowActor, signalIds);
}
_onWindowActorRemoved(container, metaWindowActor) {
this._trackedWindows.get(metaWindowActor).forEach(id => {
metaWindowActor.disconnect(id);
});
this._trackedWindows.delete(metaWindowActor);
this._updateSolidStyle();
}
vfunc_get_preferred_width(actor, forHeight) {
let primaryMonitor = Main.layoutManager.primaryMonitor;
if (primaryMonitor)
@@ -1023,8 +648,8 @@ class Panel extends St.Widget {
}
_toggleMenu(indicator) {
if (!indicator || !indicator.container.visible)
return; // menu not supported by current session mode
if (!indicator) // menu not supported by current session mode
return;
let menu = indicator.menu;
if (!indicator.actor.reactive)
@@ -1032,11 +657,7 @@ class Panel extends St.Widget {
menu.toggle();
if (menu.isOpen)
menu.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
}
toggleAppMenu() {
this._toggleMenu(this.statusArea.appMenu);
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
toggleCalendar() {
@@ -1085,6 +706,8 @@ class Panel extends St.Widget {
else
Main.messageTray.bannerAlignment = Clutter.ActorAlign.CENTER;
this._updateSolidStyle();
if (this._sessionStyle)
this._removeStyleClassName(this._sessionStyle);
@@ -1101,6 +724,41 @@ class Panel extends St.Widget {
}
}
_updateSolidStyle() {
if (this.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
this._removeStyleClassName('solid');
return;
}
if (!Main.layoutManager.primaryMonitor)
return;
/* Get all the windows in the active workspace that are in the primary monitor and visible */
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
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;
});
/* Check if at least one window is near enough to the panel */
let [, panelTop] = this.get_transformed_position();
let panelBottom = panelTop + this.get_height();
let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let isNearEnough = windows.some(metaWindow => {
let verticalPosition = metaWindow.get_frame_rect().y;
return verticalPosition < panelBottom + 5 * scale;
});
if (isNearEnough)
this._addStyleClassName('solid');
else
this._removeStyleClassName('solid');
}
_hideIndicators() {
for (let role in PANEL_ITEM_IMPLEMENTATIONS) {
let indicator = this.statusArea[role];

View File

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -162,7 +163,7 @@ var Button = GObject.registerClass({
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
let group = global.focus_manager.get_group(this.actor);
if (group) {
let direction = (symbol == Clutter.KEY_Left) ? St.DirectionType.LEFT : St.DirectionType.RIGHT;
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
group.navigate_focus(this.actor, direction, false);
return Clutter.EVENT_STOP;
}

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Shell = imports.gi.Shell;
@@ -542,7 +543,7 @@ var PopupMenuBase = class {
let sensitive = menuItem.getSensitive();
if (!sensitive && this._activeMenuItem == menuItem) {
if (!this.actor.navigate_focus(menuItem.actor,
St.DirectionType.TAB_FORWARD,
Gtk.DirectionType.TAB_FORWARD,
true))
this.actor.grab_key_focus();
} else if (sensitive && this._activeMenuItem == null) {
@@ -828,7 +829,7 @@ var PopupMenu = class extends PopupMenuBase {
} else if (symbol == navKey) {
if (!this.isOpen)
this.toggle();
this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return Clutter.EVENT_STOP;
} else
return Clutter.EVENT_PROPAGATE;
@@ -913,8 +914,8 @@ var PopupSubMenu = class extends PopupMenuBase {
// with long content, we make it scrollable - the scrollbar will only take
// effect if a CSS max-height is set on the top menu.
this.actor = new St.ScrollView({ style_class: 'popup-sub-menu',
hscrollbar_policy: St.PolicyType.NEVER,
vscrollbar_policy: St.PolicyType.NEVER });
hscrollbar_policy: Gtk.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.NEVER });
this.actor.add_actor(this.box);
this.actor._delegate = this;
@@ -956,7 +957,7 @@ var PopupSubMenu = class extends PopupMenuBase {
// when we *don't* need it, so turn off the scrollbar when that's true.
// Dynamic changes in whether we need it aren't handled properly.
this.actor.vscrollbar_policy =
needsScrollbar ? St.PolicyType.AUTOMATIC : St.PolicyType.NEVER;
needsScrollbar ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
if (needsScrollbar)
this.actor.add_style_pseudo_class('scrolled');
@@ -1149,7 +1150,7 @@ var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
if (symbol == Clutter.KEY_Right) {
this._setOpenState(true);
this.menu.actor.navigate_focus(null, St.DirectionType.DOWN, false);
this.menu.actor.navigate_focus(null, Gtk.DirectionType.DOWN, false);
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.KEY_Left && this._getOpenState()) {
this._setOpenState(false);

View File

@@ -2,12 +2,12 @@
const AccountsService = imports.gi.AccountsService;
const Cairo = imports.cairo;
const Cogl = imports.gi.Cogl;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -100,7 +100,7 @@ var NotificationsBox = class {
style_class: 'screen-shield-notifications-container' });
this._scrollView = new St.ScrollView({ x_fill: false, x_align: St.Align.START,
hscrollbar_policy: St.PolicyType.NEVER });
hscrollbar_policy: Gtk.PolicyType.NEVER });
this._notificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-container' });
this._scrollView.add_actor(this._notificationBox);
@@ -202,11 +202,6 @@ var NotificationsBox = class {
return [title, null];
}
_shouldShowDetails(source) {
return source.policy.detailsInLockScreen ||
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
}
_showSource(source, obj, box) {
if (obj.detailed) {
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
@@ -220,7 +215,7 @@ var NotificationsBox = class {
_sourceAdded(tray, source, initial) {
let obj = {
visible: source.policy.showInLockScreen,
detailed: this._shouldShowDetails(source),
detailed: source.policy.detailsInLockScreen,
sourceDestroyId: 0,
sourceCountChangedId: 0,
sourceTitleChangedId: 0,
@@ -257,7 +252,7 @@ var NotificationsBox = class {
// block scrollbars while animating, if they're not needed now
let boxHeight = this._notificationBox.height;
if (this._scrollView.height >= boxHeight)
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
this._scrollView.vscrollbar_policy = Gtk.PolicyType.NEVER;
let widget = obj.sourceBox;
let [, natHeight] = widget.get_preferred_height(-1);
@@ -267,7 +262,7 @@ var NotificationsBox = class {
transition: 'easeOutQuad',
time: 0.25,
onComplete() {
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
this._scrollView.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
widget.set_height(-1);
},
onCompleteScope: this
@@ -284,14 +279,7 @@ var NotificationsBox = class {
}
_countChanged(source, obj) {
// A change in the number of notifications may change whether we show
// details.
let newDetailed = this._shouldShowDetails(source);
let oldDetailed = obj.detailed;
obj.detailed = newDetailed;
if (obj.detailed || oldDetailed != newDetailed) {
if (obj.detailed) {
// A new notification was pushed, or a previous notification was destroyed.
// Give up, and build the list again.
@@ -323,11 +311,10 @@ var NotificationsBox = class {
}
_detailedChanged(source, obj) {
let newDetailed = this._shouldShowDetails(source);
if (obj.detailed == newDetailed)
if (obj.detailed == source.policy.detailsInLockScreen)
return;
obj.detailed = newDetailed;
obj.detailed = source.policy.detailsInLockScreen;
obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null;
@@ -418,9 +405,7 @@ class ScreenShieldArrow extends St.Bin {
let allocation = this._drawingArea.get_allocation_box();
let paintOpacity = this._drawingArea.get_paint_opacity();
let framebuffer = Cogl.get_draw_framebuffer();
this._shadowHelper.paint(framebuffer, allocation, paintOpacity);
this._shadowHelper.paint(allocation, paintOpacity);
}
this._drawingArea.paint();
@@ -933,7 +918,7 @@ var ScreenShield = class {
if (this._dialog) {
this._dialog.actor.grab_key_focus();
this._dialog.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
this._dialog.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
}

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
@@ -106,7 +107,7 @@ var ScreenshotService = class {
}
ScreenshotAreaAsync(params, invocation) {
let [x, y, width, height, flash, filename] = params;
let [x, y, width, height, flash, filename, callback] = params;
[x, y, width, height] = this._scaleArea(x, y, width, height);
if (!this._checkArea(x, y, width, height)) {
invocation.return_error_literal(Gio.IOErrorEnum,

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
@@ -401,7 +402,7 @@ var SearchResults = class {
y_fill: false,
overlay_scrollbars: true,
style_class: 'search-display vfade' });
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this._scrollView.add_actor(scrollChild);
let action = new Clutter.PanAction({ interpolate: true });
action.connect('pan', this._onPan.bind(this));
@@ -685,10 +686,10 @@ var SearchResults = class {
navigateFocus(direction) {
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
if (direction == St.DirectionType.TAB_BACKWARD ||
direction == (rtl ? St.DirectionType.RIGHT
: St.DirectionType.LEFT) ||
direction == St.DirectionType.UP) {
if (direction == Gtk.DirectionType.TAB_BACKWARD ||
direction == (rtl ? Gtk.DirectionType.RIGHT
: Gtk.DirectionType.LEFT) ||
direction == Gtk.DirectionType.UP) {
this.actor.navigate_focus(null, direction, false);
return;
}

View File

@@ -98,7 +98,7 @@ const _modes = {
'keyring', 'autorunManager', 'automountManager'],
panel: {
left: ['activities', 'appMenu'],
left: ['activities'],
center: ['dateMenu'],
right: ['a11y', 'keyboard', 'aggregateMenu']
}

View File

@@ -1,13 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const St = imports.gi.St;
const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
const Shell = imports.gi.Shell;
var EntryMenu = class extends PopupMenu.PopupMenu {
constructor(entry) {
@@ -68,7 +68,7 @@ var EntryMenu = class extends PopupMenu.PopupMenu {
super.open(animate);
this._entry.add_style_pseudo_class('focus');
let direction = St.DirectionType.TAB_FORWARD;
let direction = Gtk.DirectionType.TAB_FORWARD;
if (!this.actor.navigate_focus(null, direction, false))
this.actor.grab_key_focus();
}
@@ -146,12 +146,11 @@ function addContextMenu(entry, params) {
if (entry.menu)
return;
params = Params.parse (params, { isPassword: false, actionMode: Shell.ActionMode.POPUP });
params = Params.parse (params, { isPassword: false });
entry.menu = new EntryMenu(entry);
entry.menu.isPassword = params.isPassword;
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry },
{ actionMode: params.actionMode });
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
entry._menuManager.addMenu(entry.menu);
// Add an event handler to both the entry and its clutter_text; the former

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@@ -370,8 +371,8 @@ var ShellProcessesDialog = class extends ModalDialog.ModalDialog {
this.contentLayout.add(this._content, { x_fill: true, y_fill: false });
let scrollView = new St.ScrollView({ style_class: 'mount-dialog-app-list'});
scrollView.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
scrollView.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
this.contentLayout.add(scrollView,
{ x_fill: true,
y_fill: true });

View File

@@ -29,6 +29,7 @@ const KEY_VISUAL_BELL = 'visual-bell';
const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
const KEY_GTK_THEME = 'gtk-theme';
const KEY_ICON_THEME = 'icon-theme';
const KEY_WM_THEME = 'theme';
const KEY_TEXT_SCALING_FACTOR = 'text-scaling-factor';
const HIGH_CONTRAST_THEME = 'HighContrast';
@@ -131,6 +132,7 @@ class ATIndicator extends PanelMenu.Button {
_buildHCItem() {
let interfaceSettings = new Gio.Settings({ schema_id: DESKTOP_INTERFACE_SCHEMA });
let wmSettings = new Gio.Settings({ schema_id: WM_SCHEMA });
interfaceSettings.connect('changed::' + KEY_GTK_THEME, () => {
let value = interfaceSettings.get_string(KEY_GTK_THEME);
if (value == HIGH_CONTRAST_THEME) {
@@ -147,25 +149,35 @@ class ATIndicator extends PanelMenu.Button {
if (value != HIGH_CONTRAST_THEME)
iconTheme = value;
});
wmSettings.connect('changed::' + KEY_WM_THEME, () => {
let value = wmSettings.get_string(KEY_WM_THEME);
if (value != HIGH_CONTRAST_THEME)
wmTheme = value;
});
let gtkTheme = interfaceSettings.get_string(KEY_GTK_THEME);
let iconTheme = interfaceSettings.get_string(KEY_ICON_THEME);
let wmTheme = wmSettings.get_string(KEY_WM_THEME);
let hasHC = (gtkTheme == HIGH_CONTRAST_THEME);
let highContrast = this._buildItemExtended(
_("High Contrast"),
hasHC,
interfaceSettings.is_writable(KEY_GTK_THEME) &&
interfaceSettings.is_writable(KEY_ICON_THEME),
interfaceSettings.is_writable(KEY_ICON_THEME) &&
wmSettings.is_writable(KEY_WM_THEME),
enabled => {
if (enabled) {
interfaceSettings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME);
interfaceSettings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME);
wmSettings.set_string(KEY_WM_THEME, HIGH_CONTRAST_THEME);
} else if(!hasHC) {
interfaceSettings.set_string(KEY_GTK_THEME, gtkTheme);
interfaceSettings.set_string(KEY_ICON_THEME, iconTheme);
wmSettings.set_string(KEY_WM_THEME, wmTheme);
} else {
interfaceSettings.reset(KEY_GTK_THEME);
interfaceSettings.reset(KEY_ICON_THEME);
wmSettings.reset(KEY_WM_THEME);
}
});
return highContrast;

View File

@@ -969,8 +969,7 @@ class InputSourceIndicator extends PanelMenu.Button {
}
let item;
let type = prop.get_prop_type();
switch (type) {
switch (prop.get_prop_type()) {
case IBus.PropType.MENU:
item = new PopupMenu.PopupSubMenuMenuItem(prop.get_label().get_text());
this._buildPropSubMenu(item.menu, prop.get_sub_props());

View File

@@ -3,6 +3,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const NM = imports.gi.NM;
const Signals = imports.signals;
@@ -845,8 +846,8 @@ var NMWirelessDialog = class extends ModalDialog.ModalDialog {
this._scrollView = new St.ScrollView({ style_class: 'nm-dialog-scroll-view' });
this._scrollView.set_x_expand(true);
this._scrollView.set_y_expand(true);
this._scrollView.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
this._scrollView.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
this._scrollView.add_actor(this._itemBox);
this._stack.add_child(this._scrollView);

View File

@@ -4,7 +4,6 @@ const AccountsService = imports.gi.AccountsService;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const GObject = imports.gi.GObject;
@@ -164,15 +163,18 @@ var Indicator = class extends PanelMenu.SystemIndicator {
}
_updateSwitchUserSubMenu() {
let realName = this._user.get_real_name();
this._switchUserSubMenu.label.text = this._user.get_real_name();
let clutterText = this._switchUserSubMenu.label.clutter_text;
// In theory, GNOME allows creating users with names up to 255
// characters, but such long names look terribly bad, so limit
// to 100 and it should fit the vast majority of screen sizes.
if (realName.length > 100)
// XXX -- for some reason, the ClutterText's width changes
// rapidly unless we force a relayout of the actor. Probably
// a size cache issue or something. Moving this to be a layout
// manager would be a much better idea.
clutterText.get_allocation_box();
let layout = clutterText.get_layout();
if (layout.is_ellipsized())
this._switchUserSubMenu.label.text = this._user.get_user_name();
else
this._switchUserSubMenu.label.text = realName;
let iconFile = this._user.get_icon_file();
if (iconFile && !GLib.file_test(iconFile, GLib.FileTest.EXISTS))
@@ -209,7 +211,6 @@ var Indicator = class extends PanelMenu.SystemIndicator {
this._switchUserSubMenu = new PopupMenu.PopupSubMenuMenuItem('', true);
this._switchUserSubMenu.icon.style_class = 'system-switch-user-submenu-icon';
this._switchUserSubMenu.label.clutter_text.ellipsize = Pango.EllipsizeMode.END;
// Since the label of the switch user submenu depends on the width of
// the popup menu, and we can't easily connect on allocation-changed

View File

@@ -334,7 +334,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
_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

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -364,7 +365,7 @@ var SwitcherList = GObject.registerClass({
this._scrollView = new St.ScrollView({ style_class: 'hfade',
enable_mouse_scrolling: false });
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.NEVER);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
this._scrollView.add_actor(this._list);
this.add_actor(this._scrollView);

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -51,7 +52,7 @@ function _wrapTweening(target, tweeningParameters) {
}
}
if (!St.Settings.get().enable_animations) {
if (!Gtk.Settings.get_default().gtk_enable_animations) {
tweeningParameters['time'] = 0.000001;
tweeningParameters['delay'] = 0.000001;
}

View File

@@ -7,6 +7,7 @@ const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const Shell = imports.gi.Shell;

View File

@@ -7,7 +7,6 @@ const AccountsService = imports.gi.AccountsService;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Params = imports.misc.params;
@@ -73,7 +72,6 @@ class UserWidgetLabel extends St.Widget {
this._realNameLabel = new St.Label({ style_class: 'user-widget-label',
y_align: Clutter.ActorAlign.CENTER });
this._realNameLabel.clutter_text.ellipsize = Pango.EllipsizeMode.END;
this.add_child(this._realNameLabel);
this._userNameLabel = new St.Label({ style_class: 'user-widget-label',

View File

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
@@ -33,8 +34,8 @@ var ViewPage = {
var FocusTrap = GObject.registerClass(
class FocusTrap extends St.Widget {
vfunc_navigate_focus(from, direction) {
if (direction == St.DirectionType.TAB_FORWARD ||
direction == St.DirectionType.TAB_BACKWARD)
if (direction == Gtk.DirectionType.TAB_FORWARD ||
direction == Gtk.DirectionType.TAB_BACKWARD)
return super.vfunc_navigate_focus(from, direction);
return false;
}
@@ -81,7 +82,7 @@ var ShowOverviewAction = GObject.registerClass({
});
}
vfunc_gesture_prepare(actor) {
vfunc_gesture_prepare(action, actor) {
return Main.actionMode == Shell.ActionMode.NORMAL &&
this.get_n_current_points() == this.get_n_touch_points();
}
@@ -115,12 +116,12 @@ var ShowOverviewAction = GObject.registerClass({
height: maxY - minY });
}
vfunc_gesture_begin(actor) {
vfunc_gesture_begin(action, actor) {
this._initialRect = this._getBoundingRect(false);
return true;
}
vfunc_gesture_end(actor) {
vfunc_gesture_end(action, actor) {
let rect = this._getBoundingRect(true);
let oldArea = this._initialRect.width * this._initialRect.height;
let newArea = rect.width * rect.height;
@@ -396,7 +397,7 @@ var ViewSelector = class {
_a11yFocusPage(page) {
this._showAppsButton.checked = page == this._appsPage;
page.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
_onShowAppsButtonToggled() {
@@ -425,10 +426,10 @@ var ViewSelector = class {
this.startSearch(event);
} else if (!this._searchActive && !global.stage.key_focus) {
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
this._activePage.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._activePage.navigate_focus(null, St.DirectionType.TAB_BACKWARD, false);
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false);
return Clutter.EVENT_STOP;
}
}
@@ -556,22 +557,22 @@ var ViewSelector = class {
let arrowNext, nextDirection;
if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
arrowNext = Clutter.Left;
nextDirection = St.DirectionType.LEFT;
nextDirection = Gtk.DirectionType.LEFT;
} else {
arrowNext = Clutter.Right;
nextDirection = St.DirectionType.RIGHT;
nextDirection = Gtk.DirectionType.RIGHT;
}
if (symbol == Clutter.Tab) {
this._searchResults.navigateFocus(St.DirectionType.TAB_FORWARD);
this._searchResults.navigateFocus(Gtk.DirectionType.TAB_FORWARD);
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._focusTrap.can_focus = false;
this._searchResults.navigateFocus(St.DirectionType.TAB_BACKWARD);
this._searchResults.navigateFocus(Gtk.DirectionType.TAB_BACKWARD);
this._focusTrap.can_focus = true;
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.Down) {
this._searchResults.navigateFocus(St.DirectionType.DOWN);
this._searchResults.navigateFocus(Gtk.DirectionType.DOWN);
return Clutter.EVENT_STOP;
} else if (symbol == arrowNext && this._text.position == -1) {
this._searchResults.navigateFocus(nextDirection);

View File

@@ -12,7 +12,6 @@ const Shell = imports.gi.Shell;
const Signals = imports.signals;
const AltTab = imports.ui.altTab;
const AppFavorites = imports.ui.appFavorites;
const Dialog = imports.ui.dialog;
const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
const InhibitShortcutsDialog = imports.ui.inhibitShortcutsDialog;
@@ -600,7 +599,7 @@ var AppSwitchAction = GObject.registerClass({
});
}
vfunc_gesture_prepare(actor) {
vfunc_gesture_prepare(action, actor) {
if (Main.actionMode != Shell.ActionMode.NORMAL) {
this.cancel();
return false;
@@ -609,7 +608,7 @@ var AppSwitchAction = GObject.registerClass({
return this.get_n_current_points() <= 4;
}
vfunc_gesture_begin(actor) {
vfunc_gesture_begin(action, actor) {
// in milliseconds
const LONG_PRESS_TIMEOUT = 250;
@@ -633,7 +632,7 @@ var AppSwitchAction = GObject.registerClass({
return this.get_n_current_points() <= 4;
}
vfunc_gesture_progress(actor) {
vfunc_gesture_progress(action, actor) {
const MOTION_THRESHOLD = 30;
if (this.get_n_current_points() == 3) {
@@ -924,13 +923,6 @@ var WindowManager = class {
Shell.ActionMode.ALL,
this._toggleTweens.bind(this));
this.addKeybinding('open-application-menu',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.POPUP,
this._toggleAppMenu.bind(this));
this.addKeybinding('toggle-message-tray',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
@@ -939,69 +931,6 @@ var WindowManager = class {
Shell.ActionMode.POPUP,
this._toggleCalendar.bind(this));
this.addKeybinding('switch-to-application-1',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-2',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-3',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-4',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-5',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-6',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-7',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-8',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
this.addKeybinding('switch-to-application-9',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._switchToApplication.bind(this));
global.display.connect('show-resize-popup', this._showResizePopup.bind(this));
global.display.connect('show-pad-osd', this._showPadOsd.bind(this));
global.display.connect('show-osd', (display, monitorIndex, iconName, label) => {
@@ -1071,10 +1000,6 @@ var WindowManager = class {
gesture.connect('activated', () => {
Main.keyboard.show(Main.layoutManager.bottomIndex);
});
Main.layoutManager.connect('keyboard-visible-changed', (manager, visible) => {
gesture.cancel();
gesture.set_enabled(!visible);
});
global.stage.add_action(gesture);
gesture = new EdgeDragAction.EdgeDragAction(St.Side.TOP, mode);
@@ -2080,18 +2005,6 @@ var WindowManager = class {
Main.ctrlAltTabManager.popup(binding.is_reversed(), binding.get_name(), binding.get_mask());
}
_switchToApplication(display, window, binding) {
let [,,,target] = binding.get_name().split('-');
let apps = AppFavorites.getAppFavorites().getFavorites();
let app = apps[target - 1];
if (app)
app.activate();
}
_toggleAppMenu(display, window, event, binding) {
Main.panel.toggleAppMenu();
}
_toggleCalendar(display, window, event, binding) {
Main.panel.toggleCalendar();
}

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
@@ -202,7 +203,7 @@ var WindowMenuManager = class {
this._sourceActor.show();
menu.open(BoxPointer.PopupAnimation.NONE);
menu.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
menu.connect('open-state-changed', (menu_, isOpen) => {
if (isOpen)
return;

View File

@@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Atk = imports.gi.Atk;
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
@@ -8,8 +7,10 @@ const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Atk = imports.gi.Atk;
const Signals = imports.signals;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
@@ -21,10 +22,7 @@ var WINDOW_DND_SIZE = 256;
var WINDOW_CLONE_MAXIMUM_SCALE = 1.0;
var WINDOW_OVERLAY_IDLE_HIDE_TIMEOUT = 750;
var WINDOW_OVERLAY_FADE_TIME = 0.1;
var WINDOW_REPOSITIONING_DELAY = 750;
var CLOSE_BUTTON_FADE_TIME = 0.1;
var DRAGGING_WINDOW_OPACITY = 100;
@@ -291,7 +289,8 @@ var WindowClone = class {
this.actor.layout_manager.boundingBox = rect;
}
// Find the actor just below us, respecting reparenting done by DND code
// Find the actor just below us, respecting reparenting done
// by DND code
getActualStackAbove() {
if (this._stackAbove == null)
return null;
@@ -442,7 +441,7 @@ Signals.addSignalMethods(WindowClone.prototype);
/**
* @windowClone: Corresponding window clone
* @parentActor: The actor which will be the parent of all overlay items
* such as the close button and window caption
* such as app icon and window caption
*/
var WindowOverlay = class {
constructor(windowClone, parentActor) {
@@ -452,15 +451,13 @@ var WindowOverlay = class {
this._parentActor = parentActor;
this._hidden = false;
this._idleHideOverlayId = 0;
this.borderSize = 0;
this.border = new St.Bin({ style_class: 'window-clone-border' });
this.title = new St.Label({ style_class: 'window-caption',
text: this._getCaption() });
this.title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
windowClone.actor.label_actor = this.title;
let title = new St.Label({ style_class: 'window-caption',
text: this._getCaption() });
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
windowClone.actor.label_actor = title;
this._maxTitleWidth = -1;
@@ -469,18 +466,22 @@ var WindowOverlay = class {
this.relayout(false);
});
this.closeButton = new St.Button({ style_class: 'window-close' });
this.closeButton.add_actor(new St.Icon({ icon_name: 'window-close-symbolic' }));
this.closeButton._overlap = 0;
let button = new St.Button({ style_class: 'window-close' });
button.add_actor(new St.Icon({ icon_name: 'window-close-symbolic' }));
button._overlap = 0;
this.closeButton.connect('clicked', () => this._windowClone.deleteAll());
this._idleToggleCloseId = 0;
button.connect('clicked', () => this._windowClone.deleteAll());
windowClone.actor.connect('destroy', this._onDestroy.bind(this));
windowClone.connect('show-chrome', this._onShowChrome.bind(this));
windowClone.connect('hide-chrome', this._onHideChrome.bind(this));
this.title.hide();
this.closeButton.hide();
button.hide();
title.hide();
this.title = title;
this.closeButton = button;
// Don't block drop targets
Shell.util_set_hidden_from_pick(this.title, true);
@@ -489,14 +490,12 @@ var WindowOverlay = class {
parentActor.add_actor(this.border);
parentActor.add_actor(this.title);
parentActor.add_actor(this.closeButton);
this.title.connect('style-changed',
this._onStyleChanged.bind(this));
this.closeButton.connect('style-changed',
this._onStyleChanged.bind(this));
this.border.connect('style-changed',
this._onStyleChanged.bind(this));
// Force a style change if we are already on a stage - otherwise
title.connect('style-changed',
this._onStyleChanged.bind(this));
button.connect('style-changed',
this._onStyleChanged.bind(this));
this.border.connect('style-changed', this._onStyleChanged.bind(this));
// force a style change if we are already on a stage - otherwise
// the signal will be emitted normally when we are added
if (parentActor.get_stage())
this._onStyleChanged();
@@ -505,7 +504,7 @@ var WindowOverlay = class {
hide() {
this._hidden = true;
this.hideOverlay();
this.hideCloseButton();
}
show() {
@@ -624,9 +623,9 @@ var WindowOverlay = class {
}
_onDestroy() {
if (this._idleHideOverlayId > 0) {
Mainloop.source_remove(this._idleHideOverlayId);
this._idleHideOverlayId = 0;
if (this._idleToggleCloseId > 0) {
Mainloop.source_remove(this._idleToggleCloseId);
this._idleToggleCloseId = 0;
}
this._windowClone.metaWindow.disconnect(this._updateCaptionId);
this.title.destroy();
@@ -646,7 +645,7 @@ var WindowOverlay = class {
a.opacity = 0;
Tweener.addTween(a,
{ opacity: 255,
time: WINDOW_OVERLAY_FADE_TIME,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeOutQuad' });
});
}
@@ -656,7 +655,7 @@ var WindowOverlay = class {
a.opacity = 255;
Tweener.addTween(a,
{ opacity: 0,
time: WINDOW_OVERLAY_FADE_TIME,
time: CLOSE_BUTTON_FADE_TIME,
transition: 'easeInQuad' });
});
}
@@ -670,18 +669,18 @@ var WindowOverlay = class {
return;
this._animateVisible();
this.emit('chrome-visible');
this.emit('show-close-button');
}
_onHideChrome() {
if (this._idleHideOverlayId == 0) {
this._idleHideOverlayId = Mainloop.timeout_add(WINDOW_OVERLAY_IDLE_HIDE_TIMEOUT, this._idleHideOverlay.bind(this));
GLib.Source.set_name_by_id(this._idleHideOverlayId, '[gnome-shell] this._idleHideOverlay');
if (this._idleToggleCloseId == 0) {
this._idleToggleCloseId = Mainloop.timeout_add(750, this._idleToggleCloseButton.bind(this));
GLib.Source.set_name_by_id(this._idleToggleCloseId, '[gnome-shell] this._idleToggleCloseButton');
}
}
_idleHideOverlay() {
this._idleHideOverlayId = 0;
_idleToggleCloseButton() {
this._idleToggleCloseId = 0;
if (!this._windowClone.actor['has-pointer'] &&
!this.closeButton['has-pointer'])
@@ -690,10 +689,10 @@ var WindowOverlay = class {
return GLib.SOURCE_REMOVE;
}
hideOverlay() {
if (this._idleHideOverlayId > 0) {
Mainloop.source_remove(this._idleHideOverlayId);
this._idleHideOverlayId = 0;
hideCloseButton() {
if (this._idleToggleCloseId > 0) {
Mainloop.source_remove(this._idleToggleCloseId);
this._idleToggleCloseId = 0;
}
this.closeButton.hide();
this.border.hide();
@@ -1135,8 +1134,9 @@ var Workspace = class {
this._windows = [];
this._windowOverlays = [];
for (let i = 0; i < windows.length; i++) {
if (this._isOverviewWindow(windows[i]))
if (this._isOverviewWindow(windows[i])) {
this._addWindowClone(windows[i], true);
}
}
// Track window changes
@@ -1206,7 +1206,12 @@ var Workspace = class {
}
_lookupIndex(metaWindow) {
return this._windows.findIndex(w => w.metaWindow == metaWindow);
for (let i = 0; i < this._windows.length; i++) {
if (this._windows[i].metaWindow == metaWindow) {
return i;
}
}
return -1;
}
containsMetaWindow(metaWindow) {
@@ -1297,7 +1302,8 @@ var Workspace = class {
for (let i = 0; i < slots.length; i++) {
let slot = slots[i];
let [x, y, scale, clone] = slot;
let metaWindow = clone.metaWindow;
let overlay = clone.overlay;
clone.slotId = i;
// Positioning a window currently being dragged must be avoided;
@@ -1313,10 +1319,10 @@ var Workspace = class {
let maxChromeWidth = 2 * Math.min(
cloneCenter - area.x,
area.x + area.width - cloneCenter);
clone.overlay.setMaxChromeWidth(Math.round(maxChromeWidth));
overlay.setMaxChromeWidth(Math.round(maxChromeWidth));
if (clone.overlay && (initialPositioning || !clone.positioned))
clone.overlay.hide();
if (overlay && (initialPositioning || !clone.positioned))
overlay.hide();
if (!clone.positioned) {
// This window appeared after the overview was already up
@@ -1329,7 +1335,7 @@ var Workspace = class {
}
if (animate && isOnCurrentWorkspace) {
if (!clone.metaWindow.showing_on_its_workspace()) {
if (!metaWindow.showing_on_its_workspace()) {
/* Hidden windows should fade in and grow
* therefore we need to resize them now so they
* can be scaled up later */
@@ -1348,7 +1354,7 @@ var Workspace = class {
});
}
this._animateClone(clone, clone.overlay, x, y, scale);
this._animateClone(clone, overlay, x, y, scale);
} else {
// cancel any active tweens (otherwise they might override our changes)
Tweener.removeTweens(clone.actor);
@@ -1356,7 +1362,7 @@ var Workspace = class {
clone.actor.set_scale(scale, scale);
clone.actor.set_opacity(255);
clone.overlay.relayout(false);
this._showWindowOverlay(clone, clone.overlay);
this._showWindowOverlay(clone, overlay);
}
}
}
@@ -1471,7 +1477,7 @@ var Workspace = class {
this._cursorY = y;
this._currentLayout = null;
this._repositionWindowsId = Mainloop.timeout_add(WINDOW_REPOSITIONING_DELAY,
this._repositionWindowsId = Mainloop.timeout_add(750,
this._delayedWindowRepositioning.bind(this));
GLib.Source.set_name_by_id(this._repositionWindowsId, '[gnome-shell] this._delayedWindowRepositioning');
}
@@ -1498,7 +1504,7 @@ var Workspace = class {
// We might have the window in our list already if it was on all workspaces and
// now was moved to this workspace
if (this._lookupIndex(metaWin) != -1)
if (this._lookupIndex (metaWin) != -1)
return;
if (!this._isMyWindow(win))
@@ -1530,9 +1536,8 @@ var Workspace = class {
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
clone.positioned = true;
clone.actor.set_position(x, y);
clone.actor.set_scale(scale, scale);
clone.actor.set_position (x, y);
clone.actor.set_scale (scale, scale);
clone.overlay.relayout(false);
}
@@ -1850,15 +1855,11 @@ var Workspace = class {
this.actor.add_actor(clone.actor);
overlay.connect('chrome-visible', () => {
overlay.connect('show-close-button', () => {
let focus = global.stage.key_focus;
if (focus == null || this.actor.contains(focus))
clone.actor.grab_key_focus();
this._windowOverlays.forEach(o => {
if (o != overlay)
o.hideOverlay();
});
this._onShowOverlayClose(overlay);
});
if (this._windows.length == 0)
@@ -1874,7 +1875,7 @@ var Workspace = class {
_removeWindowClone(metaWin) {
// find the position of the window in our list
let index = this._lookupIndex(metaWin);
let index = this._lookupIndex (metaWin);
if (index == -1)
return null;
@@ -1883,6 +1884,15 @@ var Workspace = class {
return this._windows.splice(index, 1).pop();
}
_onShowOverlayClose(windowOverlay) {
for (let i = 0; i < this._windowOverlays.length; i++) {
let overlay = this._windowOverlays[i];
if (overlay == windowOverlay)
continue;
overlay.hideCloseButton();
}
}
_isBetterLayout(oldLayout, newLayout) {
if (oldLayout.scale === undefined)
return true;

View File

@@ -319,7 +319,12 @@ var WorkspaceThumbnail = class {
}
_lookupIndex(metaWindow) {
return this._windows.findIndex(w => w.metaWindow == metaWindow);
for (let i = 0; i < this._windows.length; i++) {
if (this._windows[i].metaWindow == metaWindow) {
return i;
}
}
return -1;
}
syncStacking(stackIndices) {
@@ -394,7 +399,7 @@ var WorkspaceThumbnail = class {
// We might have the window in our list already if it was on all workspaces and
// now was moved to this workspace
if (this._lookupIndex(metaWin) != -1)
if (this._lookupIndex (metaWin) != -1)
return;
if (!this._isMyWindow(win))
@@ -407,7 +412,7 @@ var WorkspaceThumbnail = class {
while (parent.is_attached_dialog())
parent = parent.get_transient_for();
let idx = this._lookupIndex(parent);
let idx = this._lookupIndex (parent);
if (idx < 0) {
// parent was not created yet, it will take care
// of the dialog when created
@@ -531,7 +536,7 @@ var WorkspaceThumbnail = class {
_removeWindowClone(metaWin) {
// find the position of the window in our list
let index = this._lookupIndex(metaWin);
let index = this._lookupIndex (metaWin);
if (index == -1)
return null;
@@ -619,10 +624,6 @@ class ThumbnailsBox extends St.Widget {
this._indicator = indicator;
this.add_actor(indicator);
// The porthole is the part of the screen we're showing in the thumbnails
this._porthole = { width: global.stage.width, height: global.stage.height,
x: global.stage.x, y: global.stage.y };
this._dropWorkspace = -1;
this._dropPlaceholderPos = -1;
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
@@ -674,9 +675,6 @@ class ThumbnailsBox extends St.Widget {
this._createThumbnails();
});
global.display.connect('workareas-changed',
this._updatePorthole.bind(this));
this._switchWorkspaceNotifyId = 0;
this._nWorkspacesNotifyId = 0;
this._syncStackingId = 0;
@@ -914,6 +912,7 @@ class ThumbnailsBox extends St.Widget {
for (let w = 0; w < this._thumbnails.length; w++)
this._thumbnails[w].destroy();
this._thumbnails = [];
this._porthole = null;
}
_workspacesChanged() {
@@ -946,6 +945,8 @@ class ThumbnailsBox extends St.Widget {
addThumbnails(start, count) {
let workspaceManager = global.workspace_manager;
if (!this._ensurePorthole())
return;
for (let k = start; k < start + count; k++) {
let metaWorkspace = workspaceManager.get_workspace_by_index(k);
let thumbnail = new WorkspaceThumbnail(metaWorkspace);
@@ -1125,6 +1126,10 @@ class ThumbnailsBox extends St.Widget {
// Note that for getPreferredWidth/Height we cheat a bit and skip propagating
// the size request to our children because we know how big they are and know
// that the actors aren't depending on the virtual functions being called.
if (!this._ensurePorthole())
return [0, 0];
let workspaceManager = global.workspace_manager;
let themeNode = this.get_theme_node();
@@ -1138,6 +1143,9 @@ class ThumbnailsBox extends St.Widget {
}
vfunc_get_preferred_width(forHeight) {
if (!this._ensurePorthole())
return [0, 0];
let workspaceManager = global.workspace_manager;
let themeNode = this.get_theme_node();
@@ -1157,14 +1165,16 @@ class ThumbnailsBox extends St.Widget {
return themeNode.adjust_preferred_width(width, width);
}
_updatePorthole() {
if (!Main.layoutManager.primaryMonitor)
this._porthole = { width: global.stage.width, height: global.stage.height,
x: global.stage.x, y: global.stage.y };
else
// The "porthole" is the portion of the screen that we show in the
// workspaces
_ensurePorthole() {
if (!Main.layoutManager.primaryMonitor || !Main.overview.visible)
return false;
if (!this._porthole)
this._porthole = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
this.queue_relayout();
return true;
}
vfunc_allocate(box, flags) {

View File

@@ -1,5 +1,5 @@
project('gnome-shell', 'c',
version: '3.31.90',
version: '3.31.4',
meson_version: '>= 0.47.0',
license: 'GPLv2+'
)
@@ -23,7 +23,7 @@ gi_req = '>= 1.49.1'
gjs_req = '>= 1.47.0'
gtk_req = '>= 3.15.0'
json_glib_req = '>= 0.13.2'
mutter_req = '>= 3.31.90'
mutter_req = '>= 3.31.4'
polkit_req = '>= 0.100'
schemas_req = '>= 3.27.90'
startup_req = '>= 0.11'

905
po/ca.po

File diff suppressed because it is too large Load Diff

919
po/cs.po

File diff suppressed because it is too large Load Diff

912
po/es.po

File diff suppressed because it is too large Load Diff

931
po/fur.po

File diff suppressed because it is too large Load Diff

814
po/gl.po

File diff suppressed because it is too large Load Diff

962
po/hu.po

File diff suppressed because it is too large Load Diff

964
po/ja.po

File diff suppressed because it is too large Load Diff

868
po/lt.po

File diff suppressed because it is too large Load Diff

894
po/pa.po

File diff suppressed because it is too large Load Diff

928
po/pl.po

File diff suppressed because it is too large Load Diff

785
po/sl.po

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,8 @@
#include <cogl-pango/cogl-pango.h>
#include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
#include <girepository.h>

View File

@@ -50,7 +50,6 @@ struct _ShellAppSystemPrivate {
GHashTable *running_apps;
GHashTable *id_to_app;
GHashTable *startup_wm_class_to_id;
GList *installed_apps;
};
static void shell_app_system_finalize (GObject *object);
@@ -83,14 +82,12 @@ static void
scan_startup_wm_class_to_id (ShellAppSystem *self)
{
ShellAppSystemPrivate *priv = self->priv;
GList *l;
GList *apps, *l;
g_hash_table_remove_all (priv->startup_wm_class_to_id);
g_list_free_full (priv->installed_apps, g_object_unref);
priv->installed_apps = g_app_info_get_all ();
for (l = priv->installed_apps; l != NULL; l = l->next)
apps = g_app_info_get_all ();
for (l = apps; l != NULL; l = l->next)
{
GAppInfo *info = l->data;
const char *startup_wm_class, *id, *old_id;
@@ -108,6 +105,8 @@ scan_startup_wm_class_to_id (ShellAppSystem *self)
g_hash_table_insert (priv->startup_wm_class_to_id,
g_strdup (startup_wm_class), g_strdup (id));
}
g_list_free_full (apps, g_object_unref);
}
static gboolean
@@ -199,7 +198,6 @@ shell_app_system_finalize (GObject *object)
g_hash_table_destroy (priv->running_apps);
g_hash_table_destroy (priv->id_to_app);
g_hash_table_destroy (priv->startup_wm_class_to_id);
g_list_free_full (priv->installed_apps, g_object_unref);
G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
}
@@ -438,21 +436,3 @@ shell_app_system_search (const char *search_string)
return results;
}
/**
* shell_app_system_get_installed:
* @self: the #ShellAppSystem
*
* Returns all installed apps, as a list of #GAppInfo
*
* Returns: (transfer none) (element-type GAppInfo): a list of #GAppInfo
* describing all known applications. This memory is owned by the
* #ShellAppSystem and should not be freed.
**/
GList *
shell_app_system_get_installed (ShellAppSystem *self)
{
ShellAppSystemPrivate *priv = self->priv;
return priv->installed_apps;
}

View File

@@ -27,6 +27,4 @@ ShellApp *shell_app_system_lookup_desktop_wmclass (ShellAppSystem *s
GSList *shell_app_system_get_running (ShellAppSystem *self);
char ***shell_app_system_search (const char *search_string);
GList *shell_app_system_get_installed (ShellAppSystem *self);
#endif /* __SHELL_APP_SYSTEM_H__ */

View File

@@ -26,6 +26,12 @@
#include <unistd.h>
#endif
typedef enum {
MATCH_NONE,
MATCH_SUBSTRING, /* Not prefix, substring */
MATCH_PREFIX, /* Strict prefix */
} ShellAppSearchMatch;
/* This is mainly a memory usage optimization - the user is going to
* be running far fewer of the applications at one time than they have
* installed. But it also just helps keep the code more logically
@@ -204,7 +210,7 @@ window_backed_app_get_icon (ShellApp *app,
if (window == NULL)
{
actor = clutter_actor_new ();
actor = clutter_texture_new ();
g_object_set (actor, "opacity", 0, "width", (float) size, "height", (float) size, NULL);
return actor;
}
@@ -631,7 +637,7 @@ shell_app_can_open_new_window (ShellApp *app)
new window.
*/
window = state->windows->data;
window = g_slist_nth_data (state->windows, 0);
if (state->unique_bus_name != NULL &&
meta_window_get_gtk_application_object_path (window) != NULL)

View File

@@ -85,8 +85,6 @@ struct _ShellGlobal {
GSList *leisure_closures;
guint leisure_function_id;
GHashTable *save_ops;
gboolean has_modal;
gboolean frame_timestamps;
gboolean frame_finish_timestamp;
@@ -313,10 +311,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
@@ -336,8 +330,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);
}
@@ -1382,26 +1374,24 @@ shell_global_create_app_launch_context (ShellGlobal *global,
guint32 timestamp,
int workspace)
{
MetaWorkspaceManager *workspace_manager = global->workspace_manager;
MetaStartupNotification *sn;
MetaLaunchContext *context;
MetaWorkspace *ws = NULL;
GdkAppLaunchContext *context;
sn = meta_display_get_startup_notification (global->meta_display);
context = meta_startup_notification_create_launcher (sn);
context = gdk_display_get_app_launch_context (global->gdk_display);
if (timestamp == 0)
timestamp = shell_global_get_current_time (global);
meta_launch_context_set_timestamp (context, timestamp);
gdk_app_launch_context_set_timestamp (context, timestamp);
if (workspace < 0)
ws = meta_workspace_manager_get_active_workspace (workspace_manager);
else
ws = meta_workspace_manager_get_workspace_by_index (workspace_manager, workspace);
{
MetaWorkspaceManager *workspace_manager = global->workspace_manager;
meta_launch_context_set_workspace (context, ws);
workspace =
meta_workspace_manager_get_active_workspace_index (workspace_manager);
}
gdk_app_launch_context_set_desktop (context, workspace);
return (GAppLaunchContext *) context;
return (GAppLaunchContext *)context;
}
typedef struct
@@ -1551,77 +1541,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);
@@ -1675,7 +1608,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);
}
/**
@@ -1710,7 +1643,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

@@ -12,6 +12,7 @@
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <cogl/cogl.h>
#include <meta/meta-cursor-tracker.h>
@@ -51,6 +52,8 @@ struct _ShellRecorder {
int stage_width;
int stage_height;
GdkScreen *gdk_screen;
int pointer_x;
int pointer_y;
@@ -207,6 +210,8 @@ shell_recorder_init (ShellRecorder *recorder)
shell_recorder_src_register ();
recorder->gdk_screen = gdk_screen_get_default ();
recorder->memory_target = get_memory_target();
recorder->a11y_settings = g_settings_new (A11Y_APPS_SCHEMA);

View File

@@ -146,7 +146,7 @@ shell_stack_get_preferred_width (ClutterActor *actor,
static gboolean
shell_stack_navigate_focus (StWidget *widget,
ClutterActor *from,
StDirectionType direction)
GtkDirectionType direction)
{
ClutterActor *top_actor;

View File

@@ -19,6 +19,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkx.h>
#include <meta/meta-shaped-texture.h>
#include <locale.h>
@@ -234,21 +235,14 @@ shell_util_translate_time_string (const char *str)
const char *locale = g_getenv ("LC_TIME");
const char *res;
char *sep;
locale_t old_loc;
locale_t loc = (locale_t) 0;
if (locale)
loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
old_loc = uselocale (loc);
setlocale (LC_MESSAGES, locale);
sep = strchr (str, '\004');
res = g_dpgettext (NULL, str, sep ? sep - str + 1 : 0);
uselocale (old_loc);
if (loc != (locale_t) 0)
freelocale (loc);
setlocale (LC_MESSAGES, "");
return res;
}
@@ -373,6 +367,24 @@ shell_util_create_pixbuf_from_data (const guchar *data,
(GdkPixbufDestroyNotify) g_free, NULL);
}
void
shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
ClutterTexture *texture)
{
CoglTexture *sprite;
sprite = meta_cursor_tracker_get_sprite (tracker);
if (sprite)
{
clutter_actor_show (CLUTTER_ACTOR (texture));
clutter_texture_set_cogl_texture (texture, sprite);
}
else
{
clutter_actor_hide (CLUTTER_ACTOR (texture));
}
}
typedef const gchar *(*ShellGLGetString) (GLenum);
static const gchar *

View File

@@ -44,6 +44,9 @@ GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar *data,
int height,
int rowstride);
void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
ClutterTexture *texture);
gboolean shell_util_need_background_refresh (void);
ClutterContent * shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,

View File

@@ -5,6 +5,10 @@
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <meta/display.h>
#include <meta/group.h>
#include <meta/util.h>

View File

@@ -17,7 +17,6 @@ st_headers = [
'st-scrollable.h',
'st-scroll-bar.h',
'st-scroll-view.h',
'st-settings.h',
'st-shadow.h',
'st-texture-cache.h',
'st-theme.h',
@@ -71,7 +70,6 @@ st_sources = [
'st-scrollable.c',
'st-scroll-bar.c',
'st-scroll-view.c',
'st-settings.c',
'st-shadow.c',
'st-texture-cache.c',
'st-theme.c',

View File

@@ -200,7 +200,7 @@ st_bin_popup_menu (StWidget *widget)
static gboolean
st_bin_navigate_focus (StWidget *widget,
ClutterActor *from,
StDirectionType direction)
GtkDirectionType direction)
{
StBinPrivate *priv = st_bin_get_instance_private (ST_BIN (widget));
ClutterActor *bin_actor = CLUTTER_ACTOR (widget);

View File

@@ -241,8 +241,6 @@ st_button_touch_event (ClutterActor *actor,
if (priv->pressed != 0)
return CLUTTER_EVENT_PROPAGATE;
if ((priv->button_mask & mask) == 0)
return CLUTTER_EVENT_PROPAGATE;
device = clutter_event_get_device ((ClutterEvent*) event);
sequence = clutter_event_get_event_sequence ((ClutterEvent*) event);

View File

@@ -56,7 +56,6 @@
#include "st-icon.h"
#include "st-label.h"
#include "st-settings.h"
#include "st-widget.h"
#include "st-texture-cache.h"
#include "st-clipboard.h"
@@ -240,15 +239,15 @@ remove_capslock_feedback (StEntry *entry)
}
static void
keymap_state_changed (ClutterKeymap *keymap,
gpointer user_data)
keymap_state_changed (GdkKeymap *keymap,
gpointer user_data)
{
StEntry *entry = ST_ENTRY (user_data);
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
if (clutter_text_get_password_char (CLUTTER_TEXT (priv->entry)) != 0)
{
if (clutter_keymap_get_caps_lock_state (keymap))
if (gdk_keymap_get_caps_lock_state (keymap))
show_capslock_feedback (entry);
else
remove_capslock_feedback (entry);
@@ -260,11 +259,11 @@ st_entry_dispose (GObject *object)
{
StEntry *entry = ST_ENTRY (object);
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
ClutterKeymap *keymap;
GdkKeymap *keymap;
cogl_clear_object (&priv->text_shadow_material);
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry);
G_OBJECT_CLASS (st_entry_parent_class)->dispose (object);
@@ -331,7 +330,7 @@ st_entry_style_changed (StWidget *self)
static gboolean
st_entry_navigate_focus (StWidget *widget,
ClutterActor *from,
StDirectionType direction)
GtkDirectionType direction)
{
StEntryPrivate *priv = ST_ENTRY_PRIV (widget);
@@ -564,11 +563,11 @@ clutter_text_focus_in_cb (ClutterText *text,
ClutterActor *actor)
{
StEntry *entry = ST_ENTRY (actor);
ClutterKeymap *keymap;
GdkKeymap *keymap;
st_entry_update_hint_visibility (entry);
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
keymap_state_changed (keymap, entry);
g_signal_connect (keymap, "state-changed",
G_CALLBACK (keymap_state_changed), entry);
@@ -582,7 +581,7 @@ clutter_text_focus_out_cb (ClutterText *text,
ClutterActor *actor)
{
StEntry *entry = ST_ENTRY (actor);
ClutterKeymap *keymap;
GdkKeymap *keymap;
st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "focus");
@@ -591,7 +590,7 @@ clutter_text_focus_out_cb (ClutterText *text,
clutter_text_set_cursor_visible (text, FALSE);
remove_capslock_feedback (entry);
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry);
}
@@ -645,32 +644,29 @@ clutter_text_button_press_event (ClutterActor *actor,
gpointer user_data)
{
StEntryPrivate *priv = ST_ENTRY_PRIV (user_data);
GtkSettings *settings = gtk_settings_get_default ();
gboolean primary_paste_enabled;
if (event->button == 2 &&
clutter_text_get_editable (CLUTTER_TEXT (priv->entry)))
g_object_get (settings,
"gtk-enable-primary-paste", &primary_paste_enabled,
NULL);
if (primary_paste_enabled && event->button == 2
&& clutter_text_get_editable (CLUTTER_TEXT (priv->entry)))
{
StSettings *settings;
gboolean primary_paste_enabled;
StClipboard *clipboard;
settings = st_settings_get ();
g_object_get (settings, "primary-paste", &primary_paste_enabled, NULL);
clipboard = st_clipboard_get_default ();
if (primary_paste_enabled)
{
StClipboard *clipboard;
clipboard = st_clipboard_get_default ();
/* By the time the clipboard callback is called,
* the rest of the signal handlers will have
* run, making the text cursor to be in the correct
* place.
*/
st_clipboard_get_text (clipboard,
ST_CLIPBOARD_TYPE_PRIMARY,
st_entry_clipboard_callback,
user_data);
}
/* By the time the clipboard callback is called,
* the rest of the signal handlers will have
* run, making the text cursor to be in the correct
* place.
*/
st_clipboard_get_text (clipboard,
ST_CLIPBOARD_TYPE_PRIMARY,
st_entry_clipboard_callback,
user_data);
}
return FALSE;
@@ -873,7 +869,6 @@ st_entry_paint (ClutterActor *actor)
if (priv->text_shadow_material != NULL)
_st_paint_shadow_with_opacity (shadow_spec,
cogl_get_draw_framebuffer (),
priv->text_shadow_material,
&allocation,
clutter_actor_get_paint_opacity (priv->entry));

View File

@@ -75,7 +75,7 @@ st_focus_manager_stage_event (ClutterActor *stage,
gpointer user_data)
{
StFocusManager *manager = user_data;
StDirectionType direction;
GtkDirectionType direction;
gboolean wrap_around = FALSE;
ClutterActor *focused, *group;
@@ -85,26 +85,26 @@ st_focus_manager_stage_event (ClutterActor *stage,
switch (event->key.keyval)
{
case CLUTTER_KEY_Up:
direction = ST_DIR_UP;
direction = GTK_DIR_UP;
break;
case CLUTTER_KEY_Down:
direction = ST_DIR_DOWN;
direction = GTK_DIR_DOWN;
break;
case CLUTTER_KEY_Left:
direction = ST_DIR_LEFT;
direction = GTK_DIR_LEFT;
break;
case CLUTTER_KEY_Right:
direction = ST_DIR_RIGHT;
direction = GTK_DIR_RIGHT;
break;
case CLUTTER_KEY_Tab:
if (event->key.modifier_state & CLUTTER_SHIFT_MASK)
direction = ST_DIR_TAB_BACKWARD;
direction = GTK_DIR_TAB_BACKWARD;
else
direction = ST_DIR_TAB_FORWARD;
direction = GTK_DIR_TAB_FORWARD;
wrap_around = TRUE;
break;
case CLUTTER_KEY_ISO_Left_Tab:
direction = ST_DIR_TAB_BACKWARD;
direction = GTK_DIR_TAB_BACKWARD;
wrap_around = TRUE;
break;

View File

@@ -176,7 +176,6 @@ st_icon_paint (ClutterActor *actor)
clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
_st_paint_shadow_with_opacity (priv->shadow_spec,
cogl_get_draw_framebuffer (),
priv->shadow_pipeline,
&allocation,
clutter_actor_get_paint_opacity (priv->icon_texture));

View File

@@ -216,7 +216,6 @@ st_label_paint (ClutterActor *actor)
if (priv->text_shadow_pipeline != NULL)
_st_paint_shadow_with_opacity (shadow_spec,
cogl_get_draw_framebuffer (),
priv->text_shadow_pipeline,
&allocation,
clutter_actor_get_paint_opacity (priv->label));

View File

@@ -429,7 +429,6 @@ CoglPipeline *
_st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
ClutterActor *actor)
{
ClutterContent *image = NULL;
CoglPipeline *shadow_pipeline = NULL;
float width, height;
@@ -440,12 +439,11 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
if (width == 0 || height == 0)
return NULL;
image = clutter_actor_get_content (actor);
if (image && CLUTTER_IS_IMAGE (image))
if (CLUTTER_IS_TEXTURE (actor))
{
CoglTexture *texture;
texture = clutter_image_get_texture (CLUTTER_IMAGE (image));
texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));
if (texture &&
cogl_texture_get_width (texture) == width &&
cogl_texture_get_height (texture) == height)
@@ -660,11 +658,11 @@ _st_create_shadow_cairo_pattern (StShadow *shadow_spec,
void
_st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglFramebuffer *framebuffer,
CoglPipeline *shadow_pipeline,
ClutterActorBox *box,
guint8 paint_opacity)
{
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
ClutterActorBox shadow_box;
CoglColor color;
@@ -680,8 +678,7 @@ _st_paint_shadow_with_opacity (StShadow *shadow_spec,
shadow_spec->color.alpha * paint_opacity / 255);
cogl_color_premultiply (&color);
cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color);
cogl_framebuffer_draw_rectangle (framebuffer,
shadow_pipeline,
cogl_framebuffer_draw_rectangle (fb, shadow_pipeline,
shadow_box.x1, shadow_box.y1,
shadow_box.x2, shadow_box.y2);
}

View File

@@ -70,7 +70,6 @@ cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec,
cairo_pattern_t *src_pattern);
void _st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglFramebuffer *framebuffer,
CoglPipeline *shadow_pipeline,
ClutterActorBox *box,
guint8 paint_opacity);

View File

@@ -58,7 +58,6 @@
* detailed description of the considerations involved.
*/
#include "st-enum-types.h"
#include "st-scroll-view.h"
#include "st-scroll-bar.h"
#include "st-scrollable.h"
@@ -83,8 +82,8 @@ struct _StScrollViewPrivate
StAdjustment *vadjustment;
ClutterActor *vscroll;
StPolicyType hscrollbar_policy;
StPolicyType vscrollbar_policy;
GtkPolicyType hscrollbar_policy;
GtkPolicyType vscrollbar_policy;
gfloat row_size;
gfloat column_size;
@@ -373,12 +372,12 @@ st_scroll_view_get_preferred_width (ClutterActor *actor,
switch (priv->hscrollbar_policy)
{
case ST_POLICY_NEVER:
case GTK_POLICY_NEVER:
min_width = child_min_width;
break;
case ST_POLICY_ALWAYS:
case ST_POLICY_AUTOMATIC:
case ST_POLICY_EXTERNAL:
case GTK_POLICY_ALWAYS:
case GTK_POLICY_AUTOMATIC:
case GTK_POLICY_EXTERNAL:
/* Should theoretically use the min width of the hscrollbar,
* but that's not cleanly defined at the moment */
min_width = 0;
@@ -390,14 +389,14 @@ st_scroll_view_get_preferred_width (ClutterActor *actor,
switch (priv->vscrollbar_policy)
{
case ST_POLICY_NEVER:
case ST_POLICY_EXTERNAL:
case GTK_POLICY_NEVER:
case GTK_POLICY_EXTERNAL:
account_for_vscrollbar = FALSE;
break;
case ST_POLICY_ALWAYS:
case GTK_POLICY_ALWAYS:
account_for_vscrollbar = !priv->overlay_scrollbars;
break;
case ST_POLICY_AUTOMATIC:
case GTK_POLICY_AUTOMATIC:
/* For automatic scrollbars, we always request space for the vertical
* scrollbar; we won't know whether we actually need one until our
* height is assigned in allocate().
@@ -455,11 +454,11 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
switch (priv->vscrollbar_policy)
{
case ST_POLICY_NEVER:
case ST_POLICY_EXTERNAL:
case GTK_POLICY_NEVER:
case GTK_POLICY_EXTERNAL:
break;
case ST_POLICY_ALWAYS:
case ST_POLICY_AUTOMATIC:
case GTK_POLICY_ALWAYS:
case GTK_POLICY_AUTOMATIC:
/* We've requested space for the scrollbar, subtract it back out */
for_width -= sb_width;
break;
@@ -470,14 +469,14 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
switch (priv->hscrollbar_policy)
{
case ST_POLICY_NEVER:
case ST_POLICY_EXTERNAL:
case GTK_POLICY_NEVER:
case GTK_POLICY_EXTERNAL:
account_for_hscrollbar = FALSE;
break;
case ST_POLICY_ALWAYS:
case GTK_POLICY_ALWAYS:
account_for_hscrollbar = !priv->overlay_scrollbars;
break;
case ST_POLICY_AUTOMATIC:
case GTK_POLICY_AUTOMATIC:
/* For automatic scrollbars, we always request space for the horizontal
* scrollbar; we won't know whether we actually need one until our
* width is assigned in allocate().
@@ -496,12 +495,12 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
switch (priv->vscrollbar_policy)
{
case ST_POLICY_NEVER:
case GTK_POLICY_NEVER:
min_height = child_min_height;
break;
case ST_POLICY_ALWAYS:
case ST_POLICY_AUTOMATIC:
case ST_POLICY_EXTERNAL:
case GTK_POLICY_ALWAYS:
case GTK_POLICY_AUTOMATIC:
case GTK_POLICY_EXTERNAL:
/* Should theoretically use the min height of the vscrollbar,
* but that's not cleanly defined at the moment */
min_height = 0;
@@ -572,9 +571,9 @@ st_scroll_view_allocate (ClutterActor *actor,
clutter_actor_get_preferred_width (priv->child, -1,
&child_min_width, NULL);
if (priv->vscrollbar_policy == ST_POLICY_AUTOMATIC)
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
{
if (priv->hscrollbar_policy == ST_POLICY_AUTOMATIC)
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
{
/* Pass one, try without a vertical scrollbar */
clutter_actor_get_preferred_height (priv->child, avail_width, &child_min_height, NULL);
@@ -592,7 +591,7 @@ st_scroll_view_allocate (ClutterActor *actor,
}
else
{
hscrollbar_visible = priv->hscrollbar_policy == ST_POLICY_ALWAYS;
hscrollbar_visible = priv->hscrollbar_policy == GTK_POLICY_ALWAYS;
/* try without a vertical scrollbar */
clutter_actor_get_preferred_height (priv->child, avail_width, &child_min_height, NULL);
@@ -601,20 +600,20 @@ st_scroll_view_allocate (ClutterActor *actor,
}
else
{
vscrollbar_visible = priv->vscrollbar_policy == ST_POLICY_ALWAYS;
vscrollbar_visible = priv->vscrollbar_policy == GTK_POLICY_ALWAYS;
if (priv->hscrollbar_policy == ST_POLICY_AUTOMATIC)
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
hscrollbar_visible = child_min_width > avail_height - (vscrollbar_visible ? 0 : sb_width);
else
hscrollbar_visible = priv->hscrollbar_policy == ST_POLICY_ALWAYS;
hscrollbar_visible = priv->hscrollbar_policy == GTK_POLICY_ALWAYS;
}
}
else
{
hscrollbar_visible = priv->hscrollbar_policy != ST_POLICY_NEVER &&
priv->hscrollbar_policy != ST_POLICY_EXTERNAL;
vscrollbar_visible = priv->vscrollbar_policy != ST_POLICY_NEVER &&
priv->vscrollbar_policy != ST_POLICY_EXTERNAL;
hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER &&
priv->hscrollbar_policy != GTK_POLICY_EXTERNAL;
vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER &&
priv->vscrollbar_policy != GTK_POLICY_EXTERNAL;
}
/* Whether or not we show the scrollbars, if the scrollbars are visible
@@ -662,12 +661,12 @@ st_scroll_view_allocate (ClutterActor *actor,
* Fold this into the scrollbar sizes to simplify the rest of the
* computations.
*/
if (priv->hscrollbar_policy == ST_POLICY_NEVER ||
priv->hscrollbar_policy == ST_POLICY_EXTERNAL ||
if (priv->hscrollbar_policy == GTK_POLICY_NEVER ||
priv->hscrollbar_policy == GTK_POLICY_EXTERNAL ||
priv->overlay_scrollbars)
sb_height = 0;
if (priv->vscrollbar_policy == ST_POLICY_NEVER ||
priv->vscrollbar_policy == ST_POLICY_EXTERNAL ||
if (priv->vscrollbar_policy == GTK_POLICY_NEVER ||
priv->vscrollbar_policy == GTK_POLICY_EXTERNAL ||
priv->overlay_scrollbars)
sb_width = 0;
@@ -829,16 +828,16 @@ st_scroll_view_class_init (StScrollViewClass *klass)
pspec = g_param_spec_enum ("vscrollbar-policy",
"Vertical Scrollbar Policy",
"When the vertical scrollbar is displayed",
ST_TYPE_POLICY_TYPE,
ST_POLICY_AUTOMATIC,
GTK_TYPE_POLICY_TYPE,
GTK_POLICY_AUTOMATIC,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_VSCROLLBAR_POLICY, pspec);
pspec = g_param_spec_enum ("hscrollbar-policy",
"Horizontal Scrollbar Policy",
"When the horizontal scrollbar is displayed",
ST_TYPE_POLICY_TYPE,
ST_POLICY_AUTOMATIC,
GTK_TYPE_POLICY_TYPE,
GTK_POLICY_AUTOMATIC,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_HSCROLLBAR_POLICY, pspec);
@@ -880,8 +879,8 @@ st_scroll_view_init (StScrollView *self)
{
StScrollViewPrivate *priv = self->priv = st_scroll_view_get_instance_private (self);
priv->hscrollbar_policy = ST_POLICY_AUTOMATIC;
priv->vscrollbar_policy = ST_POLICY_AUTOMATIC;
priv->hscrollbar_policy = GTK_POLICY_AUTOMATIC;
priv->vscrollbar_policy = GTK_POLICY_AUTOMATIC;
priv->hadjustment = g_object_new (ST_TYPE_ADJUSTMENT, NULL);
priv->hscroll = g_object_new (ST_TYPE_SCROLL_BAR,
@@ -1188,8 +1187,8 @@ st_scroll_view_get_overlay_scrollbars (StScrollView *scroll)
*/
void
st_scroll_view_set_policy (StScrollView *scroll,
StPolicyType hscroll,
StPolicyType vscroll)
GtkPolicyType hscroll,
GtkPolicyType vscroll)
{
StScrollViewPrivate *priv;

View File

@@ -34,14 +34,6 @@ G_BEGIN_DECLS
#define ST_TYPE_SCROLL_VIEW (st_scroll_view_get_type())
G_DECLARE_FINAL_TYPE (StScrollView, st_scroll_view, ST, SCROLL_VIEW, StBin)
typedef enum
{
ST_POLICY_ALWAYS,
ST_POLICY_AUTOMATIC,
ST_POLICY_NEVER,
ST_POLICY_EXTERNAL,
} StPolicyType;
typedef struct _StScrollViewPrivate StScrollViewPrivate;
/**
@@ -80,8 +72,8 @@ void st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
gboolean st_scroll_view_get_overlay_scrollbars (StScrollView *scroll);
void st_scroll_view_set_policy (StScrollView *scroll,
StPolicyType hscroll,
StPolicyType vscroll);
GtkPolicyType hscroll,
GtkPolicyType vscroll);
void st_scroll_view_update_fade_effect (StScrollView *scroll,
float vfade_offset,
float hfade_offset);

View File

@@ -1,232 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* st-settings.c: Global settings
*
* Copyright 2019 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gio/gio.h>
#include "st-settings.h"
#define KEY_ENABLE_ANIMATIONS "enable-animations"
#define KEY_PRIMARY_PASTE "gtk-enable-primary-paste"
#define KEY_DRAG_THRESHOLD "drag-threshold"
#define KEY_GTK_THEME "gtk-theme"
#define KEY_GTK_ICON_THEME "icon-theme"
enum {
PROP_0,
PROP_ENABLE_ANIMATIONS,
PROP_PRIMARY_PASTE,
PROP_DRAG_THRESHOLD,
PROP_GTK_THEME,
PROP_GTK_ICON_THEME,
N_PROPS
};
GParamSpec *props[N_PROPS] = { 0 };
struct _StSettings
{
GObject parent_object;
GSettings *interface_settings;
GSettings *mouse_settings;
gchar *gtk_theme;
gchar *gtk_icon_theme;
gboolean enable_animations;
gboolean primary_paste;
gint drag_threshold;
};
G_DEFINE_TYPE (StSettings, st_settings, G_TYPE_OBJECT)
static void
st_settings_finalize (GObject *object)
{
StSettings *settings = ST_SETTINGS (object);
g_object_unref (settings->interface_settings);
g_object_unref (settings->mouse_settings);
g_free (settings->gtk_theme);
g_free (settings->gtk_icon_theme);
G_OBJECT_CLASS (st_settings_parent_class)->finalize (object);
}
static void
st_settings_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
st_settings_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
StSettings *settings = ST_SETTINGS (object);
switch (prop_id)
{
case PROP_ENABLE_ANIMATIONS:
g_value_set_boolean (value, settings->enable_animations);
break;
case PROP_PRIMARY_PASTE:
g_value_set_boolean (value, settings->primary_paste);
break;
case PROP_DRAG_THRESHOLD:
g_value_set_int (value, settings->drag_threshold);
break;
case PROP_GTK_THEME:
g_value_set_string (value, settings->gtk_theme);
break;
case PROP_GTK_ICON_THEME:
g_value_set_string (value, settings->gtk_icon_theme);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
st_settings_class_init (StSettingsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = st_settings_finalize;
object_class->set_property = st_settings_set_property;
object_class->get_property = st_settings_get_property;
props[PROP_ENABLE_ANIMATIONS] = g_param_spec_boolean ("enable-animations",
"Enable animations",
"Enable animations",
TRUE,
G_PARAM_READABLE);
props[PROP_PRIMARY_PASTE] = g_param_spec_boolean ("primary-paste",
"Primary paste",
"Primary paste",
TRUE,
G_PARAM_READABLE);
props[PROP_DRAG_THRESHOLD] = g_param_spec_int ("drag-threshold",
"Drag threshold",
"Drag threshold",
0, G_MAXINT, 8,
G_PARAM_READABLE);
props[PROP_GTK_THEME] = g_param_spec_string ("gtk-theme",
"GTK+ Theme",
"GTK+ Theme",
"",
G_PARAM_READABLE);
props[PROP_GTK_ICON_THEME] = g_param_spec_string ("gtk-icon-theme",
"GTK+ Icon Theme",
"GTK+ Icon Theme",
"",
G_PARAM_READABLE);
g_object_class_install_properties (object_class, N_PROPS, props);
}
static void
on_interface_settings_changed (GSettings *g_settings,
const gchar *key,
StSettings *settings)
{
if (g_str_equal (key, KEY_ENABLE_ANIMATIONS))
{
settings->enable_animations = g_settings_get_boolean (g_settings, key);
g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_ENABLE_ANIMATIONS]);
}
else if (g_str_equal (key, KEY_PRIMARY_PASTE))
{
settings->primary_paste = g_settings_get_boolean (g_settings, key);
g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_PRIMARY_PASTE]);
}
else if (g_str_equal (key, KEY_GTK_THEME))
{
g_free (settings->gtk_theme);
settings->gtk_theme = g_settings_get_string (g_settings, key);
g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_GTK_THEME]);
}
else if (g_str_equal (key, KEY_GTK_ICON_THEME))
{
g_free (settings->gtk_icon_theme);
settings->gtk_icon_theme = g_settings_get_string (g_settings, key);
g_object_notify_by_pspec (G_OBJECT (settings),
props[PROP_GTK_ICON_THEME]);
}
}
static void
on_mouse_settings_changed (GSettings *g_settings,
const gchar *key,
StSettings *settings)
{
if (g_str_equal (key, KEY_DRAG_THRESHOLD))
{
settings->drag_threshold = g_settings_get_int (g_settings, key);
g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_DRAG_THRESHOLD]);
}
}
static void
st_settings_init (StSettings *settings)
{
settings->interface_settings = g_settings_new ("org.gnome.desktop.interface");
g_signal_connect (settings->interface_settings, "changed",
G_CALLBACK (on_interface_settings_changed), settings);
settings->mouse_settings = g_settings_new ("org.gnome.settings-daemon.peripherals.mouse");
g_signal_connect (settings->interface_settings, "changed",
G_CALLBACK (on_mouse_settings_changed), settings);
settings->enable_animations = g_settings_get_boolean (settings->interface_settings,
KEY_ENABLE_ANIMATIONS);
settings->primary_paste = g_settings_get_boolean (settings->interface_settings,
KEY_PRIMARY_PASTE);
settings->gtk_theme = g_settings_get_string (settings->interface_settings,
KEY_GTK_THEME);
settings->gtk_icon_theme = g_settings_get_string (settings->interface_settings,
KEY_GTK_ICON_THEME);
settings->drag_threshold = g_settings_get_int (settings->mouse_settings,
KEY_DRAG_THRESHOLD);
}
/**
* st_settings_get:
*
* Gets the #StSettings
*
* Returns: (transfer none): a settings object
**/
StSettings *
st_settings_get (void)
{
static StSettings *settings = NULL;
if (!settings)
settings = g_object_new (ST_TYPE_SETTINGS, NULL);
return settings;
}

View File

@@ -1,34 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* st-settings.h: Global settings
*
* Copyright 2019 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(ST_H_INSIDE) && !defined(ST_COMPILATION)
#error "Only <st/st.h> can be included directly.h"
#endif
#ifndef __ST_SETTINGS_H__
#define __ST_SETTINGS_H__
G_BEGIN_DECLS
#define ST_TYPE_SETTINGS (st_settings_get_type ())
G_DECLARE_FINAL_TYPE (StSettings, st_settings, ST, SETTINGS, GObject)
StSettings * st_settings_get (void);
#endif /* __ST_SETTINGS_H__ */

Some files were not shown because too many files have changed in this diff Show More