Compare commits

...

22 Commits

Author SHA1 Message Date
Jakub Steiner
6393e90a5a theme: sync OSD colors with gtk 2019-04-16 16:47:59 +02:00
Florian Müllner
4e5ca6d376 dash: Fix messed up icon height
When determining the biggest icon size that fits the available height,
we first subtract the additional space requirements of icons (spacing,
padding, running indicator etc.) and then divide the result by the
number of icons to get the maximum size available to each icon texture.

In the above, the additional space requirement of each icon is taken
from the first icon (as all icons are assumed to be the same), and
calculated as the difference between the icon button's preferred height
and the currently used icon size.

To make sure that the icon is actually using the dash's current icon
size (even while animating to a new icon size), we enforce its height
during the size request and restore its original height afterwards.

However after some recent changes, that step is causing troubles:
For some reason, the original height may be 0, and when we restore it,
we end up forcing a fixed non-height that bypasses the regular size
request machinery.

While it is unclear where exactly the zero height comes from (maybe
waiting for a valid resource scale?), it is clear that it's best
to avoid forcing a fixed height. So instead of making the icon
texture comply with the assumed icon size, adjust the calculations
to use its current height request.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1053
2019-04-13 14:17:07 +00:00
Florian Müllner
2fab75f448 dateMenu: Make clock offsets relative to local time
We recently added offsets to world clocks that represent the location's
timezone as UTC offset. However for most users, that representation is
overly technical and less helpful than the difference to their local time.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1157
2019-04-13 12:11:14 +00:00
Florian Müllner
22883f2fa2 dateMenu: Make sure we always display a clock name
We currently use the city name for all location except named timezones.
However locations only have a city name if they are of level CITY or
DETACHED, or if they are of level WEATHER_STATION with a parent of level
CITY.

So when libgweather commit d7682676ac9 moved weather station locations from
cities to countries, it broke their names in the world clocks section.

To fix this, stop making assumptions about when we can use the city name
and simply try it first for all locations and fall back to the plain name
if its not available.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1150
2019-04-12 03:17:35 +02:00
Florian Müllner
5d9f80bc73 extensionPrefs: Fix pref button appearance
After the Adwaita refresh, the button shows up oval rather than
circular. To address this, make sure that the "image-button" class
is applied as well by using the dedicated setter function.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/482
2019-04-12 00:51:44 +02:00
AsciiWolf
f7d117488b appFavorites: Update RENAMED_DESKTOP_IDS
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1160
2019-04-11 23:28:49 +02:00
Marco Trevisan (Treviño)
244a329ee7 boxpointer: Compute source allocation and work area just once
Compute the source actor workarea and allocation when repositioning and keep it
cached so that we've not to calculating it again in _calculateArrowSide.

Since _calculateArrowSide only is called inside _updateFlip that is always
called just after reposition, we can be sure that the computed values are still
correct.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/435
2019-04-11 19:38:17 +00:00
Marco Trevisan (Treviño)
044572cb60 boxpointer: Use X/Y actor positioning instead of an anchor point
Currently all the widgets using BoxPointer and so popup actors are always drawn
at screen origin and then shifted at paint time in the proper position.

This doesn't work when using resource scale, since the widgets need to know
in which monitor they currently are in order to use properly scaled resources.

So, basically revert commit 22c22e0d7 and go back using the actual actor
coordinates for positioning and the actor translation for animating it, as the
relayouting issues of the past seem to be gone now.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1008
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/435
2019-04-11 19:38:17 +00:00
Marco Trevisan (Treviño)
746875258d layout: Use an invisible but mapped actor as dummy cursor
Since this could be used as boxpointer source, it should be marked as mapped,
or it will be ignored.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/435
2019-04-11 19:38:17 +00:00
Marco Trevisan (Treviño)
4892a87dfe boxpointer: Compute arrowStride using sourceActor monitor as reference
I suppose this was also the goal of commit 96e14dc, but because it was checking
the value of the always-undefined this.sourceActor, it really never worked as
expected.

So, now since we assume that this._sourceActor is always defined just use it
as reference to compute the monitor menu position.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1029
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/435
2019-04-11 19:38:17 +00:00
Florian Müllner
8b9c8ddb1e windowManager: Don't move sticky windows when inserting workspace
Inserting a workspace is implemented by appending a new workspace, then
shifting all windows after the "new" workspace up. This has an unintended
side effect on sticky windows, as changing its workspace will unstick it.

Fix this by excluding sticky windows - there's little point in moving them
anyway, given that they should be on all workspaces (including the original
workspace and the target one).

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1151
2019-04-11 19:00:52 +00:00
Benjamin Berg
eb9000576c shellDBus: Accept connector to restrict OSD to one monitor
The monitor index is not something that gnome-shell and
gnome-settings-daemon seem to be agreeing about. Using the connector
string is a much more reliable method of identifying a specific screen
and we are indeed using this already for monitor labling.

So switch over to use the connector rather than the monitor index. If a
user tries to use the old API, then the OSD will simply show up on all
monitors (which is the status quo currently anyway).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/489
2019-04-11 18:53:53 +00:00
Benjamin Berg
862aaf341e shellDBus: Remove ShowMonitorLabels API
This API has been broken for quite some time now as the corresponding
mutter function meta_monitor_manager_get_monitor_for_output was removed.
If anyone tries to use it, we would just run into a backtrace.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/490
2019-04-11 17:49:40 +00:00
Florian Müllner
a5c75ff58b screenshot: Don't pick up rubberband style from GTK
Selecting a screen area for a screenshot isn't the same as selecting
items in an icon view, so there's no strong rationale for picking
up the style from GTK. We stopped doing that for other elements like
tile previews long ago, so just use our own style here too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/481
2019-04-11 17:27:50 +00:00
Florian Müllner
4541fb9819 perf: Stop using GTK
Instead of going through GtkSettings, we can just as well use the
underlying GSettings directly.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/481
2019-04-11 17:27:50 +00:00
Florian Müllner
9f8edd980c panel: Remove left-over Gtk.Settings
It has been unused since commit c334aa2a4c.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/481
2019-04-11 17:27:50 +00:00
Florian Müllner
e5b9043435 workspacesView: Support touch/touchpad gestures to switch workspaces
Now that the existing touch/touchpad gestures in windowManager only
handle normal mode, add corresponding gestures for the overview and
hook them up to the existing workspace scroll animations.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/516
2019-04-11 17:00:17 +00:00
Florian Müllner
c0012c2ea4 windowManager: Limit switch gestures to normal mode
The window group is hidden while in overview, so the stick-to-content
animation isn't visible either. Worse, the gestures messes up the
position of window actors in that case. Just limit the gesture to
normal mode for now, we will soon add it back in the overview with
its own animation handling.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/516
2019-04-11 17:00:17 +00:00
Florian Müllner
b77e4975f0 switchGestures: Do not hard-code allowed modes
The touch/touchpad gestures to switch workspace currently hard-code
the modes in which we want the gestures to work. While these modes
are correct, the existing switch animation only works in NORMAL mode,
not in the overview where the window group is hidden. The easiest way
to address this is to handle both cases completely separately, namely
use separate actions in- and outside the overview.

Make the existing usable in that way by making the list of allowed
modes a constructor parameter.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/516
2019-04-11 17:00:17 +00:00
Florian Müllner
e83f2344f6 windowManager: Allow disabling touchpad workspace switch action
Just like actual ClutterActions, it can make sense to temporarily
disable the touchpad action, so add an appropriate property.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/516
2019-04-11 17:00:17 +00:00
Florian Müllner
de6512be1a st: Add missing include
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/485
2019-04-08 18:17:46 +02:00
Florian Müllner
0b72ff1896 st: Add missing END_DECLS marker
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/485
2019-04-08 18:17:33 +02:00
18 changed files with 215 additions and 183 deletions

View File

@@ -9,9 +9,6 @@
<method name="ShowOSD">
<arg type="a{sv}" direction="in" name="params"/>
</method>
<method name="ShowMonitorLabels">
<arg type="a{uv}" direction="in" name="params"/>
</method>
<method name="ShowMonitorLabels2">
<arg type="a{sv}" direction="in" name="params"/>
</method>

View File

@@ -21,7 +21,7 @@ $success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$osd_fg_color: #eeeeec;
$osd_bg_color: #2e3436;
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 15%),0.3);
$osd_borders_color: transparentize(black, 0.3);
$osd_outer_borders_color: transparentize(white, 0.9);

View File

@@ -29,7 +29,7 @@ $panel-corner-radius: 6px;
/* GLOBALS */
$font-size: 11;
$font-family: Cantarell, Sans-Serif;
$_bubble_bg_color: opacify($osd_bg_color,0.25);
$_bubble_bg_color: $osd_bg_color;
$_bubble_fg_color: $osd_fg_color;
$_bubble_borders_color: transparentize($osd_fg_color,0.8);
@@ -184,7 +184,7 @@ StScrollBar {
.modal-dialog {
border-radius: 9px;
color: $osd_fg_color;
background-color: transparentize(darken($osd_bg_color,10%),0.05);
background-color: $osd_bg_color;
border: 1px solid $_bubble_borders_color;
.modal-dialog-content-box {
padding: 24px;
@@ -1142,6 +1142,12 @@ StScrollBar {
.ripple-box:rtl { border-radius: 0 0 0 52px; } // just a simple change to the border radius position
// Rubberband for select-area screenshots
.select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color;
}
// not really top bar only
.popup-menu-arrow { icon-size: 1.09em; }
.popup-menu-icon { icon-size: 1.09em; }

View File

@@ -111,7 +111,7 @@
}
}
@mixin button($t, $c:$osd_bg_color, $tc:$fg_color, $edge: $borders_edge) {
@mixin button($t, $c:opacify(lighten($osd_bg_color, 5%),1.0), $tc:$fg_color, $edge: $borders_edge) {
//
// Button drawing function
//
@@ -136,8 +136,7 @@
//
// normal button
//
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.5),
$osd_bg_color);
$_bg: $c;
color: $osd_fg_color;
background-color: $_bg;
@@ -150,8 +149,7 @@
//
// focused button
//
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.3),
lighten($osd_bg_color,3%));
$_bg: lighten($c,3%);
color: $osd_fg_color;
text-shadow: 0 1px black;
@@ -163,8 +161,7 @@
//
// active osd button
//
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.3),
lighten($osd_bg_color,3%));
$_bg: lighten($c,3%);
color: white;
border-color: $osd_borders_color;

View File

@@ -551,9 +551,9 @@ class ExtensionRow extends Gtk.ListBoxRow {
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
no_show_all: true });
button.add(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.get_style_context().add_class('circular');
hbox.add(button);

View File

@@ -1,4 +1,4 @@
const { Clutter, Gio, Gtk, Shell } = imports.gi;
const { Clutter, Gio, Shell } = imports.gi;
const Main = imports.ui.main;
const Scripting = imports.ui.scripting;
@@ -104,7 +104,10 @@ function *run() {
yield Scripting.waitLeisure();
Scripting.scriptEvent('desktopShown');
Gtk.Settings.get_default().gtk_enable_animations = false;
let interfaceSettings = new Gio.Settings({
schema_id: 'org.gnome.desktop.interface'
});
interfaceSettings.set_boolean('enable-animations', false);
Scripting.scriptEvent('overviewShowStart');
Main.overview.show();
@@ -200,7 +203,7 @@ function *run() {
yield Scripting.sleep(1000);
Gtk.Settings.get_default().gtk_enable_animations = true;
interfaceSettings.set_boolean('enable-animations', true);
}
let overviewShowStart;

View File

@@ -14,39 +14,47 @@ const RENAMED_DESKTOP_IDS = {
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
'evolution.desktop': 'org.gnome.Evolution.desktop',
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
'five-or-more.desktop': 'org.gnome.five-or-more.desktop',
'four-in-a-row.desktop': 'org.gnome.Four-in-a-row.desktop',
'gcalctool.desktop': 'org.gnome.Calculator.desktop',
'geary.desktop': 'org.gnome.Geary.desktop',
'gedit.desktop': 'org.gnome.gedit.desktop',
'glchess.desktop': 'gnome-chess.desktop',
'glines.desktop': 'five-or-more.desktop',
'gnect.desktop': 'four-in-a-row.desktop',
'glchess.desktop': 'org.gnome.Chess.desktop',
'glines.desktop': 'org.gnome.five-or-more.desktop',
'gnect.desktop': 'org.gnome.Four-in-a-row.desktop',
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnobots2.desktop': 'gnome-robots.desktop',
'gnobots2.desktop': 'org.gnome.Robots.desktop',
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
'gnome-calculator.desktop': 'org.gnome.Calculator.desktop',
'gnome-chess.desktop': 'org.gnome.Chess.desktop',
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
'gnome-klotski.desktop': 'org.gnome.Klotski.desktop',
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnome-mahjongg.desktop': 'org.gnome.Mahjongg.desktop',
'gnome-mines.desktop': 'org.gnome.Mines.desktop',
'gnome-music.desktop': 'org.gnome.Music.desktop',
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
'gnome-robots.desktop': 'org.gnome.Robots.desktop',
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
'gnome-software.desktop': 'org.gnome.Software.desktop',
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
'gnome-tetravex.desktop': 'org.gnome.Tetravex.desktop',
'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.desktop',
'gnomine.desktop': 'gnome-mines.desktop',
'gnotravex.desktop': 'gnome-tetravex.desktop',
'gnotski.desktop': 'gnome-klotski.desktop',
'gtali.desktop': 'tali.desktop',
'gnomine.desktop': 'org.gnome.Mines.desktop',
'gnotravex.desktop': 'org.gnome.Tetravex.desktop',
'gnotski.desktop': 'org.gnome.Klotski.desktop',
'gtali.desktop': 'org.gnome.Tali.desktop',
'iagno.desktop': 'org.gnome.Reversi.desktop',
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
'org.gnome.gnome-2048.desktop': 'org.gnome.TwentyFortyEight.desktop',
'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop',
'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
'polari.desktop': 'org.gnome.Polari.desktop',
'tali.desktop': 'org.gnome.Tali.desktop',
'totem.desktop': 'org.gnome.Totem.desktop',
'evince.desktop': 'org.gnome.Evince.desktop',
};

View File

@@ -47,10 +47,6 @@ var BoxPointer = GObject.registerClass({
this._border.connect('repaint', this._drawBorder.bind(this));
this.add_actor(this._border);
this.bin.raise(this._border);
this._xOffset = 0;
this._yOffset = 0;
this._xPosition = 0;
this._yPosition = 0;
this._sourceAlignment = 0.5;
this._capturedEventId = 0;
this._muteInput();
@@ -118,23 +114,23 @@ var BoxPointer = GObject.registerClass({
if (animate & PopupAnimation.SLIDE) {
switch (this._arrowSide) {
case St.Side.TOP:
this.yOffset = -rise;
this.translation_y = -rise;
break;
case St.Side.BOTTOM:
this.yOffset = rise;
this.translation_y = rise;
break;
case St.Side.LEFT:
this.xOffset = -rise;
this.translation_x = -rise;
break;
case St.Side.RIGHT:
this.xOffset = rise;
this.translation_x = rise;
break;
}
}
Tweener.addTween(this, { opacity: 255,
xOffset: 0,
yOffset: 0,
translation_x: 0,
translation_y: 0,
transition: 'linear',
onComplete: () => {
this._unmuteInput();
@@ -148,8 +144,8 @@ var BoxPointer = GObject.registerClass({
if (!this.visible)
return;
let xOffset = 0;
let yOffset = 0;
let translationX = 0;
let translationY = 0;
let themeNode = this.get_theme_node();
let rise = themeNode.get_length('-arrow-rise');
let fade = (animate & PopupAnimation.FADE);
@@ -158,16 +154,16 @@ var BoxPointer = GObject.registerClass({
if (animate & PopupAnimation.SLIDE) {
switch (this._arrowSide) {
case St.Side.TOP:
yOffset = rise;
translationY = rise;
break;
case St.Side.BOTTOM:
yOffset = -rise;
translationY = -rise;
break;
case St.Side.LEFT:
xOffset = rise;
translationX = rise;
break;
case St.Side.RIGHT:
xOffset = -rise;
translationX = -rise;
break;
}
}
@@ -176,15 +172,15 @@ var BoxPointer = GObject.registerClass({
Tweener.removeTweens(this);
Tweener.addTween(this, { opacity: fade ? 0 : 255,
xOffset: xOffset,
yOffset: yOffset,
translation_x: translationX,
translation_y: translationY,
transition: 'linear',
time: animationTime,
onComplete: () => {
this.hide();
this.opacity = 0;
this.xOffset = 0;
this.yOffset = 0;
this.translation_x = 0;
this.translation_y = 0;
if (onComplete)
onComplete();
}
@@ -477,11 +473,15 @@ var BoxPointer = GObject.registerClass({
_reposition() {
let sourceActor = this._sourceActor;
let alignment = this._arrowAlignment;
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
// Position correctly relative to the sourceActor
let sourceNode = sourceActor.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
let sourceAllocation = this._sourceAllocation;
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let [minWidth, minHeight, natWidth, natHeight] = this.get_preferred_size();
@@ -489,8 +489,7 @@ var BoxPointer = GObject.registerClass({
// We also want to keep it onscreen, and separated from the
// edge by the same distance as the main part of the box is
// separated from its sourceActor
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
let workarea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
let workarea = this._workArea;
let themeNode = this.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let arrowBase = themeNode.get_length('-arrow-base');
@@ -584,9 +583,9 @@ var BoxPointer = GObject.registerClass({
parent = parent.get_parent();
}
this._xPosition = Math.floor(x);
this._yPosition = Math.floor(y);
this._shiftActor();
// Actually set the position
this.x = Math.floor(x);
this.y = Math.floor(y);
}
// @origin: Coordinate specifying middle of the arrow, along
@@ -609,25 +608,10 @@ var BoxPointer = GObject.registerClass({
}
}
_shiftActor() {
// Since the position of the BoxPointer depends on the allocated size
// of the BoxPointer and the position of the source actor, trying
// to position the BoxPointer via the x/y properties will result in
// allocation loops and warnings. Instead we do the positioning via
// the anchor point, which is independent of allocation, and leave
// x == y == 0.
this.set_anchor_point(-(this._xPosition + this._xOffset),
-(this._yPosition + this._yOffset));
}
_calculateArrowSide(arrowSide) {
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
let sourceAllocation = this._sourceAllocation;
let [minWidth, minHeight, boxWidth, boxHeight] = this.get_preferred_size();
let monitorActor = this.sourceActor;
if (!monitorActor)
monitorActor = this;
let monitorIndex = Main.layoutManager.findIndexForActor(monitorActor);
let workarea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
let workarea = this._workArea;
switch (arrowSide) {
case St.Side.TOP:
@@ -669,24 +653,6 @@ var BoxPointer = GObject.registerClass({
}
}
set xOffset(offset) {
this._xOffset = offset;
this._shiftActor();
}
get xOffset() {
return this._xOffset;
}
set yOffset(offset) {
this._yOffset = offset;
this._shiftActor();
}
get yOffset() {
return this._yOffset;
}
updateArrowSide(side) {
this._arrowSide = side;
this._border.queue_repaint();

View File

@@ -584,22 +584,18 @@ var Dash = class Dash {
let firstButton = iconChildren[0].child;
let firstIcon = firstButton._delegate.icon;
let minHeight, natHeight;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
// Enforce the current icon size during the size request
// Enforce valid spacings during the size request
firstIcon.icon.ensure_style();
let [, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_height(this.iconSize * scaleFactor);
[minHeight, natHeight] = firstButton.get_preferred_height(-1);
firstIcon.icon.set_height(currentHeight);
let [, iconHeight] = firstIcon.icon.get_preferred_height(-1);
let [, buttonHeight] = firstButton.get_preferred_height(-1);
// Subtract icon padding and box spacing from the available height
availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) +
availHeight -= iconChildren.length * (buttonHeight - iconHeight) +
(iconChildren.length - 1) * spacing;
let availSize = availHeight / iconChildren.length;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let iconSizes = baseIconSizes.map(s => s * scaleFactor);
let newIconSize = baseIconSizes[0];

View File

@@ -136,11 +136,12 @@ var WorldClocksSection = class WorldClocksSection {
layout.attach(header, 0, 0, 2, 1);
this.actor.label_actor = header;
let localOffset = GLib.DateTime.new_now_local().get_utc_offset();
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i].location;
let name = l.get_level() == GWeather.LocationLevel.NAMED_TIMEZONE ? l.get_name()
: l.get_city_name();
let name = l.get_city_name() || l.get_name();
let label = new St.Label({ style_class: 'world-clocks-city',
text: name,
x_align: Clutter.ActorAlign.START,
@@ -149,7 +150,8 @@ var WorldClocksSection = class WorldClocksSection {
let time = new St.Label({ style_class: 'world-clocks-time' });
let offset = l.get_timezone().get_offset() / 60.;
let otherOffset = this._getTimeAtLocation(l).get_utc_offset();
let offset = (otherOffset - localOffset) / GLib.TIME_SPAN_HOUR;
let fmt = (Math.trunc(offset) == offset) ? '%s%.0f' : '%s%.1f';
let prefix = (offset >= 0) ? '+' : '-';
let tz = new St.Label({ style_class: 'world-clocks-timezone',
@@ -182,11 +184,15 @@ var WorldClocksSection = class WorldClocksSection {
}
}
_getTimeAtLocation(location) {
let tz = GLib.TimeZone.new(location.get_timezone().get_tzid());
return GLib.DateTime.new_now(tz);
}
_updateLabels() {
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i];
let tz = GLib.TimeZone.new(l.location.get_timezone().get_tzid());
let now = GLib.DateTime.new_now(tz);
let now = this._getTimeAtLocation(l.location);
l.actor.text = Util.formatTime(now, { timeOnly: true });
}
}

View File

@@ -252,7 +252,7 @@ var LayoutManager = GObject.registerClass({
// A dummy actor that tracks the mouse or text cursor, based on the
// position and size set in setDummyCursorGeometry.
this.dummyCursor = new St.Widget({ width: 0, height: 0, visible: false });
this.dummyCursor = new St.Widget({ width: 0, height: 0, opacity: 0 });
this.uiGroup.add_actor(this.dummyCursor);
global.stage.remove_actor(global.top_window_group);

View File

@@ -95,28 +95,6 @@ var OsdMonitorLabeler = class {
this._reset();
for (let id in params) {
let monitor = this._monitorManager.get_monitor_for_output(id);
if (monitor == -1)
continue;
this._monitorLabels.get(monitor).push(params[id].deep_unpack());
}
// In mirrored display setups, more than one physical outputs
// might be showing the same logical monitor. In that case, we
// join each output's labels on the same OSD widget.
for (let [monitor, labels] of this._monitorLabels.entries()) {
labels.sort();
this._osdLabels.push(new OsdMonitorLabel(monitor, labels.join(' ')));
}
}
show2(client, params) {
if (!this._trackClient(client))
return;
this._reset();
for (let connector in params) {
let monitor = this._monitorManager.get_monitor_for_connector(connector);
if (monitor == -1)

View File

@@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Atk, Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi;
const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Cairo = imports.cairo;
const Mainloop = imports.mainloop;
@@ -201,7 +201,6 @@ var AppMenuButton = GObject.registerClass({
this._startingApps = [];
this._menuManager = panel.menuManager;
this._gtkSettings = Gtk.Settings.get_default();
this._targetApp = null;
this._busyNotifyId = 0;

View File

@@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, Gtk, Meta, Shell, St } = imports.gi;
const { Clutter, Gio, GLib, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const GrabHelper = imports.ui.grabHelper;
@@ -227,8 +227,6 @@ var SelectArea = class {
this._lastY = 0;
this._result = null;
this._initRubberbandColors();
this._group = new St.Widget({ visible: false,
reactive: true,
x: 0,
@@ -248,10 +246,10 @@ var SelectArea = class {
coordinate: Clutter.BindCoordinate.ALL });
this._group.add_constraint(constraint);
this._rubberband = new Clutter.Rectangle({ color: this._background,
has_border: true,
border_width: 1,
border_color: this._border });
this._rubberband = new St.Widget({
style_class: 'select-area-rubberband',
visible: false
});
this._group.add_actor(this._rubberband);
}
@@ -265,25 +263,6 @@ var SelectArea = class {
this._group.visible = true;
}
_initRubberbandColors() {
function colorFromRGBA(rgba) {
return new Clutter.Color({ red: rgba.red * 255,
green: rgba.green * 255,
blue: rgba.blue * 255,
alpha: rgba.alpha * 255 });
}
let path = new Gtk.WidgetPath();
path.append_type(Gtk.IconView);
let context = new Gtk.StyleContext();
context.set_path(path);
context.add_class('rubberband');
this._background = colorFromRGBA(context.get_background_color(Gtk.StateFlags.NORMAL));
this._border = colorFromRGBA(context.get_border_color(Gtk.StateFlags.NORMAL));
}
_getGeometry() {
return { x: Math.min(this._startX, this._lastX),
y: Math.min(this._startY, this._lastY),
@@ -302,6 +281,7 @@ var SelectArea = class {
this._rubberband.set_position(geometry.x, geometry.y);
this._rubberband.set_size(geometry.width, geometry.height);
this._rubberband.show();
return Clutter.EVENT_PROPAGATE;
}

View File

@@ -79,14 +79,17 @@ var GnomeShell = class {
for (let param in params)
params[param] = params[param].deep_unpack();
let { monitor: monitorIndex,
let { connector,
label,
level,
max_level: maxLevel,
icon: serializedIcon } = params;
if (monitorIndex === undefined)
monitorIndex = -1;
let monitorIndex = -1;
if (connector) {
let monitorManager = Meta.MonitorManager.get();
monitorIndex = monitorManager.get_monitor_for_connector(connector);
}
let icon = null;
if (serializedIcon)
@@ -203,16 +206,10 @@ var GnomeShell = class {
this._grabbers.delete(name);
}
ShowMonitorLabelsAsync(params, invocation) {
let sender = invocation.get_sender();
let [dict] = params;
Main.osdMonitorLabeler.show(sender, dict);
}
ShowMonitorLabels2Async(params, invocation) {
let sender = invocation.get_sender();
let [dict] = params;
Main.osdMonitorLabeler.show2(sender, dict);
Main.osdMonitorLabeler.show(sender, dict);
}
HideMonitorLabelsAsync(params, invocation) {

View File

@@ -456,13 +456,28 @@ var TilePreview = class {
};
var TouchpadWorkspaceSwitchAction = class {
constructor(actor) {
constructor(actor, allowedModes) {
this._allowedModes = allowedModes;
this._dx = 0;
this._dy = 0;
this._enabled = true;
actor.connect('captured-event', this._handleEvent.bind(this));
this._touchpadSettings = new Gio.Settings({schema_id: 'org.gnome.desktop.peripherals.touchpad'});
}
get enabled() {
return this._enabled;
}
set enabled(enabled) {
if (this._enabled == enabled)
return;
this._enabled = enabled;
if (!enabled)
this.emit('cancel');
}
_checkActivated() {
let dir;
@@ -482,15 +497,16 @@ var TouchpadWorkspaceSwitchAction = class {
}
_handleEvent(actor, event) {
let allowedModes = Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW;
if (event.type() != Clutter.EventType.TOUCHPAD_SWIPE)
return Clutter.EVENT_PROPAGATE;
if (event.get_touchpad_gesture_finger_count() != 4)
return Clutter.EVENT_PROPAGATE;
if ((allowedModes & Main.actionMode) == 0)
if ((this._allowedModes & Main.actionMode) == 0)
return Clutter.EVENT_PROPAGATE;
if (!this._enabled)
return Clutter.EVENT_PROPAGATE;
if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.UPDATE) {
@@ -523,10 +539,11 @@ var WorkspaceSwitchAction = GObject.registerClass({
'motion': { param_types: [GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] },
'cancel': { param_types: [] }},
}, class WorkspaceSwitchAction extends Clutter.SwipeAction {
_init() {
_init(allowedModes) {
super._init();
this.set_n_touch_points(4);
this._swept = false;
this._allowedModes = allowedModes;
global.display.connect('grab-op-begin', () => {
this.cancel();
@@ -534,14 +551,12 @@ var WorkspaceSwitchAction = GObject.registerClass({
}
vfunc_gesture_prepare(actor) {
let allowedModes = Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW;
this._swept = false;
if (!super.vfunc_gesture_prepare(actor))
return false;
return (allowedModes & Main.actionMode);
return (this._allowedModes & Main.actionMode);
}
vfunc_gesture_progress(actor) {
@@ -1043,14 +1058,15 @@ var WindowManager = class {
global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT,
false, -1, 1);
let gesture = new WorkspaceSwitchAction();
let allowedModes = Shell.ActionMode.NORMAL;
let gesture = new WorkspaceSwitchAction(allowedModes);
gesture.connect('motion', this._switchWorkspaceMotion.bind(this));
gesture.connect('activated', this._actionSwitchWorkspace.bind(this));
gesture.connect('cancel', this._switchWorkspaceCancel.bind(this));
global.stage.add_action(gesture);
// This is not a normal Clutter.GestureAction, doesn't need add_action()
gesture = new TouchpadWorkspaceSwitchAction(global.stage);
gesture = new TouchpadWorkspaceSwitchAction(global.stage, allowedModes);
gesture.connect('motion', this._switchWorkspaceMotion.bind(this));
gesture.connect('activated', this._actionSwitchWorkspace.bind(this));
gesture.connect('cancel', this._switchWorkspaceCancel.bind(this));
@@ -1202,6 +1218,10 @@ var WindowManager = class {
// Same for OR windows
if (window.is_override_redirect())
return;
// Sticky windows don't need moving, in fact moving would
// unstick them
if (window.on_all_workspaces)
return;
// Windows on workspaces below pos don't need moving
let index = window.get_workspace().index();
if (index < pos)

View File

@@ -1,10 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GObject, Meta, St } = imports.gi;
const { Clutter, Gio, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const WindowManager = imports.ui.windowManager;
const Workspace = imports.ui.workspace;
var WORKSPACE_SWITCH_TIME = 0.25;
@@ -82,6 +83,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling
this._gestureActive = false; // touch(pad) gestures
this._animatingScroll = false; // programatically updating the adjustment
let activeWorkspaceIndex = workspaceManager.get_active_workspace_index();
@@ -211,7 +213,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
if (this._animating || this._scrolling) {
if (this._animating || this._scrolling || this._gestureActive) {
workspace.actor.show();
} else {
if (this._inDrag)
@@ -223,7 +225,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
}
_updateScrollAdjustment(index) {
if (this._scrolling)
if (this._scrolling || this._gestureActive)
return;
this._animatingScroll = true;
@@ -300,6 +302,18 @@ var WorkspacesView = class extends WorkspacesViewBase {
this._updateVisibility();
}
startTouchGesture() {
this._gestureActive = true;
}
endTouchGesture() {
this._gestureActive = false;
// Make sure title captions etc are shown as necessary
this._scrollToActive();
this._updateVisibility();
}
// sync the workspaces' positions to the value of the scroll adjustment
// and change the active workspace if appropriate
_onScroll(adj) {
@@ -310,7 +324,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
let active = workspaceManager.get_active_workspace_index();
let current = Math.round(adj.value);
if (active != current) {
if (active != current && !this._gestureActive) {
if (!this._workspaces[current]) {
// The current workspace was destroyed. This could happen
// when you are on the last empty workspace, and consolidate
@@ -391,6 +405,12 @@ var ExtraWorkspaceView = class extends WorkspacesViewBase {
endSwipeScroll() {
}
startTouchGesture() {
}
endTouchGesture() {
}
};
var DelegateFocusNavigator = GObject.registerClass(
@@ -430,23 +450,37 @@ var WorkspacesDisplay = class {
return false;
}
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startSwipeScroll();
this._startSwipeScroll();
return true;
});
panAction.connect('gesture-cancel', () => {
clickAction.release();
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endSwipeScroll();
this._endSwipeScroll();
});
panAction.connect('gesture-end', () => {
clickAction.release();
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endSwipeScroll();
this._endSwipeScroll();
});
Main.overview.addAction(panAction);
this.actor.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
let allowedModes = Shell.ActionMode.OVERVIEW;
let switchGesture = new WindowManager.WorkspaceSwitchAction(allowedModes);
switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this));
switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
switchGesture.connect('cancel', this._endTouchGesture.bind(this));
Main.overview.addAction(switchGesture);
this.actor.bind_property('mapped', switchGesture, 'enabled', GObject.BindingFlags.SYNC_CREATE);
switchGesture = new WindowManager.TouchpadWorkspaceSwitchAction(global.stage, allowedModes);
switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this));
switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
switchGesture.connect('cancel', this._endTouchGesture.bind(this));
this.actor.connect('notify::mapped', () => {
switchGesture.enabled = this.actor.mapped;
});
switchGesture.enabled = this.actor.mapped;
this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = [];
@@ -474,6 +508,47 @@ var WorkspacesDisplay = class {
return false;
}
_startSwipeScroll() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startSwipeScroll();
}
_endSwipeScroll() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endSwipeScroll();
}
_startTouchGesture() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startTouchGesture();
}
_endTouchGesture() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endTouchGesture();
}
_onSwitchWorkspaceMotion(action, xRel, yRel) {
// We don't have a way to hook into start of touchpad actions,
// luckily this is safe to call repeatedly.
this._startTouchGesture();
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
let adjustment = this._scrollAdjustment;
adjustment.value = (active - yRel / this.actor.height) * adjustment.page_size;
}
_onSwitchWorkspaceActivated(action, direction) {
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let newWs = activeWorkspace.get_neighbor(direction);
if (newWs != activeWorkspace)
newWs.activate(global.get_current_time());
this._endTouchGesture();
}
navigateFocus(from, direction) {
return this._getPrimaryView().actor.navigate_focus(from, direction, false);
}

View File

@@ -24,6 +24,8 @@
#ifndef __ST_SETTINGS_H__
#define __ST_SETTINGS_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define ST_TYPE_SETTINGS (st_settings_get_type ())
@@ -31,4 +33,6 @@ G_DECLARE_FINAL_TYPE (StSettings, st_settings, ST, SETTINGS, GObject)
StSettings * st_settings_get (void);
G_END_DECLS
#endif /* __ST_SETTINGS_H__ */