Compare commits

...

438 Commits

Author SHA1 Message Date
Marco Trevisan (Treviño)
d9ae9a023a New upstream version 40.1 2021-05-30 17:53:15 +02:00
Florian Müllner
605dd02217 Tag release 40.1
Update NEWS.
2021-05-13 16:51:52 +02:00
Florian Müllner
b33a62f2dc Update sass submodule 2021-05-13 16:50:34 +02:00
Quentin PAGÈS
8a320eb0a1 Update Occitan translation 2021-05-10 20:04:48 +00:00
Pawan Chitrakar
83c4ced407 Update Nepali translation 2021-05-01 05:49:03 +00:00
Florian Müllner
e094dead91 windowsNavigator: Adjust to gnome-shell change
Parts of WindowPreview were moved to C for performance reasons, which
turned a formerly private JS property into a GObject property.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/302

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/170>
2021-04-08 16:38:40 +02:00
Carmen Bianca BAKKER
6cdf86b6b3 Update Esperanto translation 2021-04-07 12:05:20 +00:00
Florian Müllner
3e8bbb07ea classic: Disable welcome dialog
The Tour focuses on new overview features, which aren't relevant
for gnome-classic where the overview is disabled altogether.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4026

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/169>
2021-04-05 20:32:19 +02:00
Anders Jonsson
e3ddd8e7d0 Update Swedish translation 2021-03-27 20:14:29 +00:00
Ngọc Quân Trần
aa67982129 Update Vietnamese translation 2021-03-27 07:54:17 +00:00
Florian Müllner
8aa645ae5d build: Adjust shell-version
With the new version scheme, only the major version is relevant as
far as gnome-shell is concerned. However the extension website does
not handle that at the moment, so always append a ".0".
2021-03-20 13:39:25 +01:00
Florian Müllner
20540cb843 Post-release version bump 2021-03-20 13:39:25 +01:00
Florian Müllner
d338930d69 Tag release 40.0
Update NEWS.
2021-03-20 13:10:47 +01:00
Jiri Grönroos
35c1763792 Update Finnish translation 2021-03-16 10:15:46 +00:00
Florian Müllner
7a87bdcb1b Post-release version bump 2021-03-16 00:00:31 +01:00
Florian Müllner
50b6bd1884 Tag release 40.rc
Update NEWS.
2021-03-15 16:32:30 +01:00
Florian Müllner
db853d9023 Update sass submodule 2021-03-15 16:29:55 +01:00
Florian Müllner
5be44705f7 window-list: Improve preview styling
The current styling doesn't indicate the active workspace very well, and
makes it difficult to differentiate empty workspaces from workspaces with
maximized windows.

Tweak the styling to address those issues.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/283

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/166>
2021-03-11 12:08:38 +00:00
Florian Müllner
fdfa46099b workspace-indicator: Improve preview styling
The current styling doesn't indicate the active workspace very well, and
makes it difficult to differentiate empty workspaces from workspaces with
maximized windows.

Tweak the styling to address those issues.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/283

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/166>
2021-03-11 12:08:38 +00:00
Florian Müllner
f987e5f13d workspace-indicator: Reindent stylesheet
For some reason the CSS here uses a different indentation than
gnome-shell or the other extensions, fix that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/283

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/166>
2021-03-11 12:08:38 +00:00
Florian Müllner
c766230118 window-list: Only show previews for up to six workspaces
On request of GNOME Classic users, we add GNOME2-like workspace previews
when using a horizontal workspace layout. The previews scale a lot worse
than the menu though, with the risk that they take up all the available
width in extreme cases.

Address this by also taking the number of workspaces into account, and
switch to the menu when we have more than six.

This is particularly important now that we switched to a horizontal
layout by default.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/165>
2021-03-10 20:11:18 +01:00
Florian Müllner
bb2b1204b4 workspace-indicator: Only show previews for up to six workspaces
On request of GNOME Classic users, we add GNOME2-like workspace previews
when using a horizontal workspace layout. The previews scale a lot worse
than the menu though, with the risk that they take up all the available
width in extreme cases.

Address this by also taking the number of workspaces into account, and
switch to the menu when we have more than six.

This is particularly important now that we switched to a horizontal
layout by default.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/165>
2021-03-10 20:11:18 +01:00
Florian Müllner
cf3690a434 windowsNavigator: Adjust to gnome-shell changes
Unsurprisingly, the big overview changes in gnome-shell broke the
extension. Make the necessary adjustments to get it working again:
 - changed constructor parameters for Workspace/WorkspacesView
 - overall state handling done by adjustment
 - window preview layout changes

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/296

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/163>
2021-03-10 15:28:37 +00:00
Florian Müllner
7062acf10f native-window-placement: Adjust to gnome-shell changes
More unsurprising breakage:
 - the workspace layout/strategy relation has been cleaned up
 - window previews now include an icon that influences the
   title position
 - window previews scale up on hover, which again influences
   the title position

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/164>
2021-03-10 15:26:26 +00:00
Fran Dieguez
7ace9c4d51 Update Galician translation 2021-02-24 21:14:57 +00:00
Florian Müllner
23887ce2a3 Post-release version bump 2021-02-24 01:57:00 +01:00
Florian Müllner
e8b8677bfe Tag release 40.beta
Update NEWS.
2021-02-24 01:50:31 +01:00
Florian Müllner
3603bc7c6a Update sass submodule 2021-02-24 01:50:31 +01:00
Florian Müllner
1e44941db6 drive-menu: Remove unused style class
The .single-indicator class was added to add extra spacing to
lone top bar items when removing the arrows, but dropped again
after solving the extra spacing differently.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/161>
2021-02-24 00:45:58 +00:00
Florian Müllner
f71da9e843 window-list: Replace WorkspaceBackground as well
The shell now scales down the backgrounds and adds a rounded corner
clip. Undo both those changes with another override.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/160>
2021-02-24 01:24:11 +01:00
Florian Müllner
1b4a20a8af window-list: Replace Workspace prototype
This is arguably more elegant than injecting into individual methods, and
will be consistent with an upcoming override that cannot be implemented
as method injection.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/160>
2021-02-24 01:24:11 +01:00
Florian Müllner
d8e179ed09 window-list: Adjust to OSK changes
Visibility changes are now handled internally, without an easy way
for us to hook into. We can resort to a hack though, as the gesture
action to bring up the keyboard is only enabled while the keyboard
is hidden.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/160>
2021-02-24 01:24:11 +01:00
A S Alam
8016cf7ae9 Update Punjabi translation 2021-02-14 00:58:36 +00:00
Аляксей
7774426eb9 Update Belarusian translation 2021-02-12 16:18:20 +00:00
Florian Müllner
9fa522c29a window-list: Adjust to overview changes
The overview code changed significantly, including the bits we re-use
to implement the window picker in the classic session. Adjust to those
changes to unbreak the extension.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/159>
2021-02-12 02:20:20 +01:00
Florian Müllner
b92295ad2c Update sass submodule
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/159>
2021-02-12 02:20:20 +01:00
Florian Müllner
d7c8a5d193 extensions: Remove horizontal-workspaces extension
Workspaces are now horizontal by default, so we don't need to change
the layout for classic mode anymore.

That was the only reason why the extension was added, so it has now
outlived its usefulness.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/158>
2021-01-29 16:09:59 +00:00
Michael Lawton
0d8d6dceb0 places-menu: Mark mounts that can be unmounted as removable
While the eject() code falls back to unmount() for mounts that
don't support ejecting, it's not possible to actually do so
because we hide the eject button.

Fix this by treating all mounts as removable that can either be
ejected or unmounted.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/161

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/152>
2021-01-28 12:25:26 +01:00
Daniel van Vugt
8a5e793b3d auto-move-windows: Don't move windows already on all workspaces
This fixes a particular case of mutter#992.

Although gnome-shell will also be softened to not crash in future, it's
also a good idea for the extension to explicitly decide how it wants to
handle windows that are already on all workspaces.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/157>
2021-01-28 16:33:50 +08:00
Florian Müllner
8fcbed6481 classic: Remove arrow-override
No need to hide what is no longer there.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3567

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/156>
2021-01-26 17:00:24 +01:00
Florian Müllner
ac2ed286e1 extensions: Remove arrows from top bar menus
... following the corresponding gnome-shell change.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3567

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/156>
2021-01-26 16:59:43 +01:00
Florian Müllner
3c3c1f702d window-list: Add tooltips to workspace thumbnails
When showing previews instead of the menu, the workspace names
don't appear anywhere. Some users care strongly about those, so
expose them as tooltip on hover.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/155>
2021-01-20 23:58:13 +01:00
Florian Müllner
c33be29f56 workspace-indicator: Add tooltips to workspace thumbnails
When showing previews instead of the menu, the workspace names from
our preferences don't appear anywhere. Some users care strongly about
those, so expose them as tooltip on hover.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/155>
2021-01-20 23:58:13 +01:00
Florian Müllner
d8ae2dcba2 window-list: Drop height override
gnome-shell's top bar got taller, and is now just 1px smaller than
our size override. We don't need that additional pixel to fit our
UI, so remove the override to make the sizes of both bars consistent.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/271

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/154>
2021-01-18 22:43:52 +01:00
Florian Müllner
3b14c0a04e Post-release version bump 2021-01-14 19:04:45 +01:00
Florian Müllner
0e3d6465eb Tag release 40.alpha.1
Update NEWS.
2021-01-14 19:02:07 +01:00
Florian Müllner
d381a0b89b auto-move-windows: Use Gtk.Button.icon_name property
Image buttons are a very common pattern, so GTK4 added some
convenience API we can use to construct them.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
5df0fa145b workspace-indicator: Use Gtk.Button.icon_name property
Image buttons are a very common pattern, so GTK4 added some
convenience API we can use to construct them.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
f0ff0e1400 workspace-indicator: Stop using header func for separators
GTK4 added built-in support for this common pattern, so use that
instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
53f5a92dc8 user-theme: Stop using header func for separators
GTK4 provides built-in support for this common pattern, so use
that instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
d5c31273ee auto-move-windows: Stop using header func for separators
GTK4 added built-in support for this common pattern, so use that
instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
22ea58a849 workspace-indicator: Port to GTK4
With this port, all extensions now use GTK4 for their preferences.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
67d96993ce auto-move-windows: Port to GTK4
Just like the previous ports, this consists mostly of
replacing the old Gtk.Container methods.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
96dd4f9835 window-list: Port to GTK4
Another easy port:
 - replace Gtk.Container methods
 - stop using show_all()
 - Gtk.CheckButton now provides the
   Gtk.RadioButton functionality as well

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
3bef6be7c1 user-theme: Port to GTK4
With the previous preparations in place, the actual GTK4 port is
now trivial:
 - replace Gtk.Container methods with widget-specific methods
 - stop using show_all()

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:55 +01:00
Florian Müllner
b83d38a72e user-theme: Track GSettings to sync checkmark
GTK4 removes the generic GtkWidget API for accessing an inserted
action group, so we need an alternative for tracking the currently
selected theme.

Using the underlying GSettings object looks like the easiest option,
so do that.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:54 +01:00
Florian Müllner
5b73960f34 extensions: Stop using :margin shortcut
The property has been removed in GTK4, so prepare for a port by
setting the four individual margin properties instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/148>
2021-01-14 14:40:54 +01:00
Jonas Dreßler
505a7f4ac9 classic: Fixup panel styling after gnome-shell changes
We don't want a transparent panel in the classic session (this is
already taken care of by the existing panel background-color overrides),
and we want to avoid the new pill-shaped hover/focus indicators in the
classic session.

For the gnome-shell changes, see
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1397.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/153>
2021-01-14 00:25:47 +01:00
Florian Müllner
e8acfb2b51 Update sass submodule
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/153>
2021-01-14 00:25:47 +01:00
Florian Müllner
dcd5dc4c7f ci: Add back commit-rules file
Somehow git-mv ended up as git-rm without me noticing, whoops.
2021-01-11 14:17:04 +01:00
Florian Müllner
2702cdf889 ci: Update ci-fairy image
The default rules file name has changed from commitrules.yml to
commit-rules.yml, adjust to that change.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/151>
2021-01-11 14:03:44 +01:00
Florian Müllner
669e7c32a2 classic: Pre-generate stylesheet
We follow the rule of not putting generated files under version
control, but that means drawing in additional build-time dependencies.
We can reduce those when building from a released tarball by
generating the stylesheets at dist time though, so do that.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/150>
2020-12-29 00:27:07 +01:00
Florian Müllner
294eb0feb5 data: Update list of theme dependencies
The scss sources were split up in gnome-shell last cycle, catch
up with that change.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/150>
2020-12-29 00:16:16 +01:00
Florian Müllner
a7ddbd0d53 Change upcoming version (again)
The extension website doesn't handle the chosen scheme correctly,
so use 40.alpha.1 instead.
2020-12-25 23:29:06 +01:00
Florian Müllner
c745dd6362 build: Change upcoming version to 40.alpha2
I messed up and released 40.alpha at the same time as 3.38.2, when it's
supposed to be in January. In order to re-align with the schedule, change
the upcoming version to 40.alpha2 so we don't have to skip a release and
will be back on track in time of 40.beta.
2020-12-22 01:33:44 +01:00
Florian Müllner
a4cf9f956e ci: Add some more commit message rules
Now that we have the ability to easily define custom rules, add some
more to enforce the existing commit message style.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/149>
2020-12-18 19:26:50 +01:00
Florian Müllner
02aa68b24a ci: Replace custom commit-log script with ci-fairy
ci-fairy now supports checking commit messages for required/disallowed
patterns. Use that to replace our custom commit-log script.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/149>
2020-12-18 19:26:42 +01:00
Simon McVittie
9f25047e24 New upstream version 3.38.2 2020-12-03 10:11:14 +00:00
Florian Müllner
fb66afbf71 Bump version to 3.38.2
Update NEWS.
2020-12-03 00:14:49 +01:00
Florian Müllner
365fa6abc9 Update sass submodule 2020-12-03 00:14:49 +01:00
Florian Müllner
d7a824f35f workspace-indicator: Use overlap to determine preview visibility
In order to better reflect the actual workspace, show any preview
that is at least partially located on the monitor, not only those
that have the major part on that monitor.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>

(cherry picked from commit 50d3ee5703)
2020-12-03 00:09:21 +01:00
Florian Müllner
0d8e412220 window-list: Use overlap to determine preview visibility
In order to better reflect the actual workspace, show any preview
that is at least partially located on the monitor, not only those
that have the major part on that monitor.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>

(cherry picked from commit 08dfb78815)
2020-12-03 00:09:19 +01:00
Florian Müllner
991f6ef508 workspace-indicator: Account for monitor offset in window previews
Windows' frame rects are in screen coordinates, while the workspace
thumbnails are based on the monitor work area. Unless we account
for the difference, previews end up mispositioned in multi-monitor
setups.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>

(cherry picked from commit 6949a5d075)
2020-12-03 00:09:16 +01:00
Florian Müllner
37f03f5e2e window-list: Account for monitor offset in window previews
Windows' frame rects are in screen coordinates, while the workspace
thumbnails are based on the monitor work area. Unless we account
for the difference, previews end up mispositioned in multi-monitor
setups.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>

(cherry picked from commit 893d3b0473)
2020-12-03 00:09:12 +01:00
Florian Müllner
b4a4ff0a06 workspace-indicator: Round calculated preview sizes
While not strictly necessary, there's no reason to differ from the
copy in the window-list extension ...

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>

(cherry picked from commit f5128e13f2)
2020-12-03 00:09:09 +01:00
Ray Strode
de8876bd5e window-list: Stop monitoring drag operation if window list is destroyed
If a user is in the middle of a drag in the window list and the
window list associated with the drag gets destroyed, the drag
monitor gets leaked.

Later when the drag motion is processed, spew goes to the log:

clutter_actor_contains: assertion 'CLUTTER_IS_ACTOR (self)' failed

Examples of triggers for this bug:

- The monitor topology changes
- The screen gets locked during the drag

This commit fixes the spew and the leak by ensuring any pending
drag monitoring is disabled when the window lists are destroyed.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/145>

(cherry picked from commit 8318ea919f)
2020-12-03 00:08:57 +01:00
Thun Pin
5ad272e628 window-navigator: Adjust to 3.38 overview changes
gnome-shell's overview code changed significantly in 3.38,
adjust the extension to work without the separate overlay.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/259

(cherry picked from commit 737c897624)
2020-12-03 00:08:30 +01:00
Florian Müllner
3b22582752 auto-move-windows: Exclude sticky windows from empty-check
We modify gnome-shell's workspace tracker to only remove empty
workspaces from the end. However we currently don't take into
account that sticky windows appear on all workspaces, so those
are preventing any workspace from getting removed at the moment.

Exclude them when determining whether a workspace is empty to
get the expected behavior.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/135

(cherry picked from commit 61cf679b8c)
2020-12-03 00:08:07 +01:00
Florian Müllner
4e731e1dce Post-release version bump 2020-12-02 20:40:19 +01:00
Florian Müllner
eee341e907 Tag release 40.alpha
Update NEWS.
2020-12-02 20:33:56 +01:00
Florian Müllner
aad96bb1c4 Update sass submodule 2020-12-02 20:33:56 +01:00
Florian Müllner
50d3ee5703 workspace-indicator: Use overlap to determine preview visibility
In order to better reflect the actual workspace, show any preview
that is at least partially located on the monitor, not only those
that have the major part on that monitor.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>
2020-12-02 19:27:44 +01:00
Florian Müllner
08dfb78815 window-list: Use overlap to determine preview visibility
In order to better reflect the actual workspace, show any preview
that is at least partially located on the monitor, not only those
that have the major part on that monitor.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>
2020-12-02 19:22:51 +01:00
Florian Müllner
6949a5d075 workspace-indicator: Account for monitor offset in window previews
Windows' frame rects are in screen coordinates, while the workspace
thumbnails are based on the monitor work area. Unless we account
for the difference, previews end up mispositioned in multi-monitor
setups.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>
2020-12-02 19:22:12 +01:00
Florian Müllner
893d3b0473 window-list: Account for monitor offset in window previews
Windows' frame rects are in screen coordinates, while the workspace
thumbnails are based on the monitor work area. Unless we account
for the difference, previews end up mispositioned in multi-monitor
setups.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>
2020-12-02 19:20:08 +01:00
Florian Müllner
f5128e13f2 workspace-indicator: Round calculated preview sizes
While not strictly necessary, there's no reason to differ from the
copy in the window-list extension ...

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/142>
2020-12-02 19:17:36 +01:00
Ray Strode
8318ea919f window-list: Stop monitoring drag operation if window list is destroyed
If a user is in the middle of a drag in the window list and the
window list associated with the drag gets destroyed, the drag
monitor gets leaked.

Later when the drag motion is processed, spew goes to the log:

clutter_actor_contains: assertion 'CLUTTER_IS_ACTOR (self)' failed

Examples of triggers for this bug:

- The monitor topology changes
- The screen gets locked during the drag

This commit fixes the spew and the leak by ensuring any pending
drag monitoring is disabled when the window lists are destroyed.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/145>
2020-11-25 17:48:21 +00:00
Florian Müllner
bde20e78f0 ci: Bump ci-fairy template include
This fixes the check-merge-request job when MR branch and target branch are
on the same repo.

See
https://gitlab.freedesktop.org/freedesktop/ci-templates/-/merge_requests/66

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/146>
2020-11-24 16:28:40 +01:00
Jordan Petridis
02db9525e7 ci: Replace only/except with rules
only/except keywords where deperecated in favor of rules.

Since we started using GNOME/gnome-shell!1492 it introduced
a second pipeline being run for each commit.

Detached pipelines are the only way to access CI_MERGE_REQUEST_*
variables, and if we disable normal pipelines you will need to
create wip/spam MRs in order to run the tests.

This reworked rules makes it so, the normal pipeline needs manual
interaction to be started, and the detached/MR pipleines is always
run.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/144>
2020-11-21 01:14:39 +01:00
Jordan Petridis
8d4586bd57 ci: Set some sensible defaults
* Allow for all jobs to be cancelled if a newer commit is pushed
* Automatically retry jobs if they fail due to some infrastructure issue

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/144>
2020-11-21 01:14:39 +01:00
Jonas Ådahl
8872659621 ci: Check that merge requests have the right settings
This will catch the missing "allow write access for maintainers" check
box being checked.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/144>
2020-11-21 01:14:39 +01:00
Florian Müllner
46c7677643 ci: Use ci-fairy image for commit log check
This is in line with what mutter/gnome-shell are using, and should
be smaller (read: faster) than the gjs image.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/144>
2020-11-21 01:14:39 +01:00
Florian Müllner
e734fcbd21 window-list: Adjust to overview changes
Window DND in the overview is now based on the metaWindow,
not the window actor (misnamed as "real window").

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/133
2020-11-19 04:54:07 +01:00
Florian Müllner
435879c121 workspace-indicator: Adjust to overview changes
Window DND in the overview is now based on the metaWindow,
not the window actor (misnamed as "real window").

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/133
2020-11-19 04:54:07 +01:00
Jonas Ådahl
4b9f4b1b63 doap: Make marge-bot a maintainer
This is so that the merge button can be restricted to maintainers, thus
decreasing the risk of merging using the merge button.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/141>
2020-11-19 01:32:23 +01:00
Jonas Ådahl
b64c93897b ci: Wait for 'check-commit-log' before continuing
The check-commit-log is quick, and to get a result early is helpful as
one can then more quickly check for failures via the report provided via
the JUnit report.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/141>
2020-11-19 01:32:23 +01:00
Jonas Ådahl
a7939f18d1 ci/check-commit-log: Generate JUnit report
This means the merge request will see the commit log review issues
causing the pipeline to fail without having to dig through CI log files.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/141>
2020-11-19 01:13:11 +01:00
Jonas Ådahl
15efbc29be ci/check-commit-log: Reverse the merge request URL check
Instead of making sure there is a reference to a bug or merge request,
make sure there isn't. The reason for this is that marge-bot will always
append a merge request URL in the end of the commit message.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/141>
2020-11-19 01:13:11 +01:00
Florian Müllner
6e5466a4ec ci: Explicitly specify job dependencies
We can speed up CI a bit by allowing build jobs to run in parallel
with review jobs.

See https://gitlab.gnome.org/help/ci/yaml/README.md#needs for details.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/141>
2020-11-19 01:12:29 +01:00
Thun Pin
737c897624 window-navigator: Adjust to 3.38 overview changes
gnome-shell's overview code changed significantly in 3.38,
adjust the extension to work without the separate overlay.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/259
2020-11-18 23:54:18 +00:00
Florian Müllner
c317a876dd ci: Switch to updated gnome-shell image
gnome-shell now produces a CI image as part of its pipeline. Use that
instead of the old, manually-updated image.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/140
2020-11-19 00:22:01 +01:00
Florian Müllner
72c67aacc4 lint: Sync configuration with gjs
gjs updated its eslint configuration, so sync our copy.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/137
2020-11-14 00:58:52 +01:00
Florian Müllner
ba7e3fc0b5 cleanup: Remove empty leading/trailing lines in blocks
gjs added a new rule to its eslint ruleset that forbids "block padding",
so make sure we conform to that rule before syncing up the configuration.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/137
2020-11-14 00:58:52 +01:00
Florian Müllner
61cf679b8c auto-move-windows: Exclude sticky windows from empty-check
We modify gnome-shell's workspace tracker to only remove empty
workspaces from the end. However we currently don't take into
account that sticky windows appear on all workspaces, so those
are preventing any workspace from getting removed at the moment.

Exclude them when determining whether a workspace is empty to
get the expected behavior.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/135
2020-11-13 23:53:49 +00:00
Florian Müllner
ba55bacab4 ci: Use junit output format
Gitlab has built-in support for junit reports, so switch eslint's
output to that format.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/136
2020-11-07 01:55:02 +01:00
Jordi Mas
9445bd2205 Update Catalan translation 2020-10-23 21:10:23 +02:00
Florian Müllner
ed81650f55 window-list: Use custom layout manager for thumbnails
The current code positions window previews explicitly using a fixed
layout manager. For that it relies on a valid parent allocation,
which is error-prone and frequently results in warnings.

Address this by moving the positioning code into a custom layout
manager, and only update the visibility from the window preview.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/260
2020-10-21 13:44:44 +02:00
Florian Müllner
1276a880de workspace-indicator: Use custom layout manager for thumbnails
The current code positions window previews explicitly using a fixed
layout manager. For that it relies on a valid parent allocation,
which is error-prone and frequently results in warnings.

Address this by moving the positioning code into a custom layout
manager, and only update the visibility from the window preview.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/260
2020-10-21 13:44:44 +02:00
Florian Müllner
6ed1f45ffd window-list: Use custom layout manager for thumbnails
The current code positions window previews explicitly using a fixed
layout manager. For that it relies on a valid parent allocation,
which is error-prone and frequently results in warnings.

Address this by moving the positioning code into a custom layout
manager, and only update the visibility from the window preview.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/260
2020-10-21 03:09:45 +02:00
Florian Müllner
81be1d2e2f workspace-indicator: Use custom layout manager for thumbnails
The current code positions window previews explicitly using a fixed
layout manager. For that it relies on a valid parent allocation,
which is error-prone and frequently results in warnings.

Address this by moving the positioning code into a custom layout
manager, and only update the visibility from the window preview.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/260
2020-10-21 03:09:40 +02:00
Florian Müllner
52abf74088 window-list: Adjust to overview changes
Window DND in the overview is now based on the metaWindow,
not the window actor (misnamed as "real window").

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/133
2020-10-21 01:05:07 +00:00
Florian Müllner
623bc6dbf3 workspace-indicator: Adjust to overview changes
Window DND in the overview is now based on the metaWindow,
not the window actor (misnamed as "real window").

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/133
2020-10-21 01:05:07 +00:00
Fabio Tomat
04b23ec68f Update Friulian translation 2020-10-17 20:14:41 +00:00
Sergio Costas
584016c291 window-list: Honor changes in skip-taskbar property
Although window-list checks the 'skip-taskbar' property when a
window is added to the desktop to decide wether it should be
shown in the bar or not, it doesn't honor that when the property
is changed after a window has already been added. Since the new
WaylandClient API allows to change this property for already
mapped windows, supporting this is a good idea.

This patch fixes this.

Fix https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/130


(cherry picked from commit b65f362f0d)
2020-10-08 21:50:07 +00:00
Sergio Costas
b65f362f0d window-list: Honor changes in skip-taskbar property
Although window-list checks the 'skip-taskbar' property when a
window is added to the desktop to decide wether it should be
shown in the bar or not, it doesn't honor that when the property
is changed after a window has already been added. Since the new
WaylandClient API allows to change this property for already
mapped windows, supporting this is a good idea.

This patch fixes this.

Fix https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/130
2020-10-08 23:42:21 +02:00
Jeremy Bicha
41664b152c New upstream version 3.38.1 2020-10-06 17:36:33 -04:00
Florian Müllner
7c30f35b12 Bump version to 40.alpha
The GNOME project has adopted a new versioning scheme[0], and
GNOME 3.38 will be followed by GNOME 40.

Open the new development cycle by switching to the new scheme, as
well as to post-release bumps as recommended.

[0] https://discourse.gnome.org/t/new-gnome-versioning-scheme/4235

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/131
2020-10-06 15:07:54 +02:00
Florian Müllner
9e976f06b4 Bump version to 3.38.1
Update NEWS.
2020-10-05 20:43:21 +02:00
Florian Müllner
369801dbeb Update sass submodule 2020-10-05 20:42:16 +02:00
Yosef Or Boczko
2c3c7e8a73 Update Hebrew translation 2020-09-28 19:05:19 +00:00
Stas Solovey
bb8f34de83 Update Russian translation 2020-09-22 19:52:00 +00:00
Cheng-Chia Tseng
6c98658fe1 Update Chinese (Taiwan) translation 2020-09-22 15:07:44 +00:00
Simon McVittie
8957c277a1 New upstream version 3.38.0 2020-09-22 09:16:27 +01:00
Yacine Bouklif
3f06c2bc04 Add Kabyle translation 2020-09-19 11:51:36 +00:00
Florian Müllner
9e38b091a9 Bump version to 3.38.0
Update NEWS.
2020-09-14 22:52:43 +02:00
Rūdolfs Mazurs
62d7b883f0 Update Latvian translation 2020-09-12 09:06:28 +00:00
Milo Casagrande
e56a9c5681 Update Italian translation 2020-09-10 08:12:04 +00:00
Tim Sabsch
03aa180472 Update German translation 2020-09-09 06:04:41 +00:00
Juliano Camargo
bbb0775e1a Update Portuguese translation 2020-09-08 20:08:29 +00:00
Alan Mortensen
c41d285131 Updated Danish translation 2020-09-07 19:58:09 +02:00
Balázs Meskó
cc63876b7e Update Hungarian translation 2020-09-06 21:06:21 +00:00
Florian Müllner
08769ec0b6 Bump version to 3.37.92
Update NEWS.
2020-09-06 01:06:49 +02:00
Dušan Kazik
5615c21797 Update Slovak translation 2020-09-02 12:02:31 +00:00
Changwoo Ryu
48d2b4c902 Update Korean translation 2020-08-30 07:46:02 +00:00
Marek Černocký
a43db7233d Updated Czech translation 2020-08-28 22:21:25 +02:00
Marco Trevisan (Treviño)
8b9be8f120 New upstream version 3.37.91 2020-08-27 08:18:07 +02:00
Aurimas Černius
25143c92f4 Updated Lithuanian translation 2020-08-26 22:34:38 +03:00
Zander Brown
c4ab7e9bbf Update British English translation 2020-08-26 12:25:53 +00:00
Nathan Follens
1d082fc026 Update Dutch translation 2020-08-25 15:38:07 +00:00
Florian Müllner
75919911f5 Bump version to 3.37.91
Update NEWS.
2020-08-24 18:09:27 +02:00
Florian Müllner
bf1f129854 Update sass submodule 2020-08-24 18:07:44 +02:00
Goran Vidović
59bcc0a6a7 Update Croatian translation 2020-08-19 22:39:08 +00:00
Goran Vidović
61a54add2e Update Croatian translation 2020-08-19 22:38:38 +00:00
Марко Костић
17d07239c1 Update Serbian translation 2020-08-19 05:21:54 +00:00
Jiri Grönroos
bf8a31a6c8 Update Finnish translation 2020-08-16 15:17:57 +00:00
Rafael Fontenelle
1d2fdf5c19 Update Brazilian Portuguese translation 2020-08-16 10:30:03 +00:00
Piotr Drąg
f6ada58f5f Update Polish translation 2020-08-15 11:39:47 +02:00
Kukuh Syafaat
ebfbc397be Update Indonesian translation 2020-08-13 12:19:05 +00:00
Akarshan Biswas
02290e8bba Update Bengali (India) translation 2020-08-13 04:36:03 +00:00
Fran Dieguez
1537ac39d4 Update Galician translation 2020-08-12 23:02:45 +00:00
Florian Müllner
e39c3b4561 Bump version to 3.37.90
Update NEWS.
2020-08-11 17:32:17 +02:00
Florian Müllner
80030687d9 Update sass submodule 2020-08-11 17:30:02 +02:00
Alexandre Franke
3859c09318 Update French translation 2020-08-10 10:50:40 +00:00
Asier Sarasua Garmendia
a41cd3c19a Update Basque translation 2020-08-10 07:06:33 +00:00
Anders Jonsson
fcbdeba8c5 Update Swedish translation 2020-08-01 23:10:54 +00:00
Piotr Drąg
116f074e3b Update POTFILES.in
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/128
2020-08-01 14:38:05 +02:00
Florian Müllner
9a78c7e4f4 classic: Drop separate gnome-session definition
Originally the classic session replaced `gnome-shell.desktop` with
`gnome-shell-classic.desktop` (to add the --mode=classic parameter)
and added `nautilus-classic.desktop` (to force on desktop icons).

Neither is the case anymore (and hasn't been for years): Nowadays the
only expected difference is the GNOME_SHELL_SESSION_MODE variable and
the DesktopNames field, which are both set from the session .desktop
file rather than the gnome-session session definition.

Any difference in the latter - like not starting the USBProtection
plugin and missing systemd user session support - are bugs. The
easiest way to avoid those in the future is by removing the obsolete
duplication that enables them, so do just that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/126
2020-07-31 08:52:51 +00:00
Efstathios Iosifidis
9a2d6d68ff Update Greek translation 2020-07-13 21:42:11 +00:00
Fabio Tomat
bc49778100 Update Friulian translation 2020-07-12 16:10:38 +00:00
Florian Müllner
67d2e2f623 Bump version to 3.37.3
Update NEWS.
2020-07-07 18:47:17 +02:00
Florian Müllner
eff625fcb8 native-window-placement: Adjust to gnome-shell changes
The extension was affected pretty badly by the window picker overhaul;
adjust to all(?) the major and minor changes to get it to work again.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/124
2020-07-07 17:39:36 +02:00
Florian Müllner
3742f79d4b window-list: Adjust to gnome-shell changes
The window picker saw a significant overhaul. Amazingly the adjustments
necessary are relatively small ...

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/124
2020-07-07 17:31:52 +02:00
Florian Müllner
b6a3503f5e window-list: Remove some dead code
Since PanelMenu.Button started to inherit from St.Widget, the custom
_allocate() function isn't called anymore.

Simply changing the function to vfunc_allocate() doesn't work as other
changes happened in the meantime, so for now just remove it altogether.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/124
2020-07-07 17:31:52 +02:00
Baurzhan Muftakhidinov
f449ab31c9 Update Kazakh translation 2020-07-02 06:40:14 +00:00
Baurzhan Muftakhidinov
920b925b12 Update Kazakh translation
(cherry picked from commit 9a8b5caca3)
2020-06-25 05:18:54 +00:00
Boyuan Yang
ad5e70b03b Update Chinese (China) translation 2020-06-23 21:15:19 +00:00
sicklylife
7beebc11f6 Update Japanese translation 2020-06-10 12:34:10 +00:00
sicklylife
1391acd71f Update Japanese translation 2020-06-10 12:18:25 +00:00
Jordi Mas
761fdf1036 Update Catalan translation 2020-06-06 14:42:37 +02:00
Florian Müllner
7f2c39cdb2 Bump version to 3.37.2
Update NEWS.
2020-06-02 22:16:25 +02:00
Matej Urbančič
b5ff860118 Updated Slovenian translation 2020-06-01 22:08:36 +02:00
Florian Müllner
aeaba3f379 window-list: Replace removed Clutter.BoxLayout method
The method was deprecated for years and has finally been removed.
Just set appropriate expand/align properties on the children and
add them with the usual add_child() method.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/122
2020-05-28 02:46:06 +02:00
Florian Müllner
f96943a4dc window-list: Replace allocation-changed signal
It has been removed in favor of notify::allocation.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/122
2020-05-28 02:46:06 +02:00
Florian Müllner
60ad2e37ff window-list: Stop using obsolete StBin properties
Those properties were deprecated (and made no-ops) last cycle, and
have now been removed altogether.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/122
2020-05-28 02:46:06 +02:00
Florian Müllner
8c53fd9590 workspace-indicator: Stop using obsolete StBin properties
Those properties were deprecated (and made no-ops) last cycle, and
have now been removed altogether.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/122
2020-05-28 02:46:06 +02:00
Daniel Șerbănescu
867ace0b0a Update Romanian translation 2020-05-22 09:14:46 +00:00
Danial Behzadi
a74862e745 Update Persian translation 2020-05-12 14:27:33 +00:00
Emin Tufan Çetin
c16f9828bd Update Turkish translation 2020-05-05 14:34:53 +00:00
Daniel Mustieles
608a8b1639 Updated Spanish translation 2020-05-04 15:45:54 +02:00
Yuri Chornoivan
7bc9b282a2 Update Ukrainian translation 2020-05-03 19:20:15 +00:00
Florian Müllner
9db7b96f24 window-list: Modernize preference dialog a bit
The current widget uses UI patterns that are reminiscent of GNOME 2.
It doesn't take a lot to make it look more modern: Simply giving the
radio group a distinct background and border allows us to move the
whole UI to the center, making the dialog more balanced and visually
pleasing.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/121
2020-05-03 19:51:24 +02:00
Florian Müllner
c87cfc822a auto-move: Overhaul preference dialog
auto-move uses the same outdated UI pattern as workspace-indicator did
until commit 90d3c5c51d, imposing the same problems for a future GTK4
port.

So replace treeview and toolbar with an editable list like we did for
the other extension.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/121
2020-05-03 19:51:24 +02:00
Laurent Bigonville
d3b687df8b New upstream version 3.36.2 2020-05-03 10:01:14 +02:00
Cheng-Chia Tseng
ff94c5a143 Update Chinese (Taiwan) translation 2020-05-02 08:06:58 +00:00
Florian Müllner
df463177e7 Bump version to 3.36.2
Update NEWS.
2020-04-29 22:45:40 +02:00
Florian Müllner
62af36ebfa Update sass submodule 2020-04-29 22:44:25 +02:00
Florian Müllner
81f999f761 Bump version to 3.37.1
Update NEWS.
2020-04-29 21:55:52 +02:00
Florian Müllner
17b5c0400a Update sass submodule 2020-04-29 21:49:53 +02:00
Florian Müllner
ac937b9549 user-theme: Make rows non-selectable
A row has to be activated to select a theme, not merely selected.
The selection therefore doesn't do anything, so disable it.
2020-04-29 21:44:13 +02:00
Daniel Mustieles
0c223de045 Updated Spanish translation 2020-04-28 17:47:14 +02:00
Anders Jonsson
564235d44c Update Swedish translation 2020-04-26 18:52:30 +00:00
Yuri Chornoivan
92a2361306 Update Ukrainian translation 2020-04-25 08:07:50 +00:00
Danial Behzadi
9f27654729 Update Persian translation 2020-04-24 20:13:04 +00:00
Dz Chen
f4013c7a5c Update Chinese (China) translation 2020-04-18 09:59:29 +00:00
Kristjan SCHMIDT
9e7eff4a3e Update Esperanto translation
(cherry picked from commit c5246b7415)
2020-04-18 09:00:54 +00:00
Kristjan SCHMIDT
c5246b7415 Update Esperanto translation 2020-04-18 09:00:46 +00:00
Florian Müllner
5b2bdd138a user-themes: Support session mode styles
Session mode stylesheets are installed in gnome-shell's theme
directory instead of a subdirectory of the global themes direc-
tory.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/118
2020-04-17 16:33:03 +00:00
Florian Müllner
90d3c5c51d workspace-indicator: Overhaul prefs widget
Inline toolbars are an outdated UI pattern, and both the toolbar widget
and the inline styling have been removed from GTK4. Making sure the
extension doesn't get in the way of a future GTK4 port is a good excuse
for modernizing the UI, so do just that :-)

Replace treeview and toolbar with an editable list as outline in the HIG:
https://developer.gnome.org/hig/stable/lists.html.en

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/120
2020-04-17 17:54:15 +02:00
Milan Crha
b00e531626 window-list: Invalid current mode selected in Preferences
It seems that gtk+ resets the active radio whenever a new radio button
is added into the group, thus rather restore the current mode after
the group is fully populated.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/119
2020-04-17 09:37:13 +02:00
Florian Müllner
b1c1b01184 po: Update POTFILES.in
The user-themes extension actually never had translatable strings.
2020-04-12 04:41:53 +02:00
Florian Müllner
739b1e11a0 user-themes: Add preference widget
While we don't endorse or support 3rd party theming, the extension
exists and is actively used. However right now the most convenient
way of setting it up is by installing Tweak Tool; give users an
alternative by providing a simple settings dialog ourselves.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/117
2020-04-12 04:13:25 +02:00
Florian Müllner
a3541ff0d9 ci: Drop "regular" build job
We already do a meson build/install when exporting extension bundles, and
now that the syntax check is handled by the CI instead of `meson test`,
the job just duplicates work.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/116
2020-04-11 01:08:11 +02:00
Florian Müllner
8fb5476a1c build: Drop syntax-checks from meson test
Those checks are just as well handled by the CI, and removing them
makes for a nice build system cleanup.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/116
2020-04-11 01:08:02 +02:00
Florian Müllner
fc8a46f15a ci: Syntax-check js sources
This is currently done as part of `ninja test`, but doing the check
in a separate CI job means it can run in parallel with other review
jobs and fail before trying to build.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/116
2020-04-11 01:07:55 +02:00
Florian Müllner
2e21f7cf72 ci: Combine commit/source checks under 'review'
The current names are an artifact from when flatpak-ci used
review/stop_review jobs. 'review' is a much better name and
matches what gnome-shell itself uses.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/116
2020-04-11 01:07:45 +02:00
Florian Müllner
a317d79016 ci: Set a default image
All jobs but one use the same issue, so specify that globally instead
of for each job.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/116
2020-04-11 01:07:37 +02:00
Florian Müllner
4722b89cc3 cleanup: Don't linebreak before closing parentheses
Otherwise recent versions of eslint want "dangling" commas,
which is at least ugly considering that most functions don't
allow adding arguments at leisure.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/116
2020-04-11 01:03:38 +02:00
Florian Müllner
5a4b71ba90 ci: Create and expose extension bundles
Similar to how we let CI create flatpaks for application, create
and expose extension bundles for easier testing.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/114
2020-04-10 23:57:09 +02:00
Florian Müllner
a6ee142f21 build: Omit unneeded translations from zip files
Each extension zip we create includes the translations of all extensions,
which is clearly wasteful. Avoid that by generating per-extension .pot
files and filtering out unnecessary translations.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/114
2020-04-10 23:11:43 +02:00
Florian Müllner
35427ed4f1 build: Use gnome-extensions-tool for zipping up
The tool has a dedicated command for creating an extension bundle. It
knows how to handle translations and GSettings schemas, so we don't
have to.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/114
2020-04-10 23:11:43 +02:00
Florian Müllner
bce63d3168 places-menu: Emphasize eject buttons here as well
We already align the buttons correctly here, but otherwise they can
use the same treatment as in the drive-menu.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/223
2020-04-10 14:31:40 +00:00
Florian Müllner
0426d1d8d5 drive-menu: Emphasize eject buttons as distinct controls
The buttons currently appear more as an attachment to the label
than as distinct controls. Address that by:

 - applying .button styling
 - increasing spacing between label and button
 - aligning buttons at the end

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/223
2020-04-10 14:31:40 +00:00
Xiaoguang Wang
d39c1fd685 windowPicker: Wrong signal ID _nWorkspacesNotifyId
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/106


(cherry picked from commit f9aaa732b2)
2020-04-10 14:31:24 +00:00
Florian Müllner
665a7fbbcb ci: Update URL check
Gitlab started inserting a /-/ in its URLs, account for that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/113


(cherry picked from commit 7b82c5e12b)
2020-04-10 14:30:49 +00:00
Xiaoguang Wang
f9aaa732b2 windowPicker: Wrong signal ID _nWorkspacesNotifyId
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/106
2020-04-10 16:27:41 +02:00
Florian Müllner
7b82c5e12b ci: Update URL check
Gitlab started inserting a /-/ in its URLs, account for that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/113
2020-04-10 16:19:27 +02:00
Simon McVittie
a4987d03b8 New upstream version 3.36.1 2020-04-02 10:14:07 +01:00
Yosef Or Boczko
db305687d5 Update Hebrew translation
(cherry picked from commit c477f10bfb)
2020-04-01 15:22:54 +00:00
Yosef Or Boczko
c477f10bfb Update Hebrew translation 2020-04-01 15:22:37 +00:00
Florian Müllner
f527fe3774 build: Post-release version bump
... and official start of the next development cycle.
2020-03-31 01:03:14 +02:00
Florian Müllner
2ae0f368b9 Bump version to 3.36.1
Update NEWS.
2020-03-31 00:58:41 +02:00
Florian Müllner
3428bebb67 Update sass submodule 2020-03-31 00:57:31 +02:00
Iain Lane
ac33058086 New upstream version 3.36.0 2020-03-16 12:13:26 +00:00
Daniel Korostil
73822dc5f5 Update Ukrainian translation 2020-03-10 20:46:17 +00:00
Florian Müllner
961757f717 Bump version to 3.36.0
Update NEWS.
2020-03-07 23:07:37 +01:00
Florian Müllner
7d5c985004 build: Switch to js68 for tests
It's what the cool kids use nowadays ...
2020-03-07 23:07:37 +01:00
Florian Müllner
cd16995503 Update sass submodule 2020-03-07 23:00:47 +01:00
Florian Müllner
3a3b5bac85 Bump version to 3.35.92 2020-03-01 02:22:25 +01:00
Florian Müllner
9f6b83eece Update sass submodule 2020-03-01 02:22:02 +01:00
Marco Trevisan (Treviño)
c7a08aaf74 New upstream version 3.35.91 2020-02-24 14:48:45 +01:00
Florian Müllner
4456b440d8 Bump version to 3.35.91
Update NEWS.
2020-02-18 00:36:15 +01:00
Florian Müllner
f61e2f5f5c Update sass submodule 2020-02-18 00:35:32 +01:00
Zander Brown
a8eecac0ff Update British English translation 2020-02-11 19:32:35 +00:00
Florian Müllner
9a6b4da33c Bump version to 3.35.90
Update NEWS.
2020-02-06 21:54:51 +01:00
Florian Müllner
cb53d0b85c Update sass submodule 2020-02-06 21:51:09 +01:00
Umarzuki Bin Mochlis Moktar
318b9b18af Update Malay translation 2020-01-27 12:27:08 +00:00
Florian Müllner
cdf970d4b6 ci: Fix eslint job
eslint requires a file/directory, and will fail when the parameter
is not specified. Unfortunately it only indicates the failure by
printing its help output, but not via its return value, so our test
still completes successfully.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/105
2020-01-26 23:43:18 +01:00
Florian Müllner
1ee3803265 window-list: Fix typo
Whoops, missed a shift-press there. Another issues that sneaked
in thanks to the broken eslint check.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/105
2020-01-26 23:43:18 +01:00
Florian Müllner
b25c4d07a7 style: Avoid unnecessary parentheses
The eslint check in CI is broken, and some style nits weren't caught
as a consequence.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/105
2020-01-26 23:43:18 +01:00
Florian Müllner
330e7b312d windowsNavigator: Adjust to deprecated API removal
The old raise/lower methods have been deprecated for years, and
mutter finally removed those APIs.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/104
2020-01-26 23:30:55 +01:00
Florian Müllner
01f921541f windowsNavigator: Use normal inheritance for non-GObject class
More fallout from commit 63615cb657.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/104
2020-01-26 23:30:55 +01:00
Florian Müllner
cc52f4a260 windowsNavigator: Add missing imports
Commit 63615cb657 missed that, which is an easy mistake to make.

But how on earth did CI not catch this?!

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/104
2020-01-26 23:25:38 +01:00
sicklylife
eb71474c95 Update Japanese translation 2020-01-20 22:21:08 +00:00
sicklylife
69681cdc9a Update Japanese translation 2020-01-20 22:13:20 +00:00
Florian Müllner
c958e2d0fd window-list: Force single-line window titles
While window titles really really shouldn't contain newline characters,
they are under application control and therefore may very well do.
Force the corresponding labels to be single line, to prevent offending
applications from messing up the whole window list layout.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/202
2020-01-17 15:03:54 +01:00
Florian Müllner
9c964eaf1b drive-menu: Stop using deprecated child properties
StBoxLayout's child properties were deprecated in favor of the generic
expand/align properties.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/102
2020-01-09 20:16:39 +01:00
Florian Müllner
0500480d75 window-list: Stop using deprecated child properties
StBoxLayout's child properties were deprecated in favor of the generic
expand/align properties.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/102
2020-01-09 20:15:52 +01:00
Florian Müllner
37a09b7be1 apps-menu: Stop using deprecated (child) properties
StBoxLayout's child properties were deprecated in favor of the generic
expand/align properties.

StBin now uses the same Clutter.Actor properties instead of its own.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/102
2020-01-09 20:13:11 +01:00
Florian Müllner
d8c734124d classic: Add new import
The shell SCSS got reorganized, and we are now missing an import in
the classic style. Add it to get back a working classic style.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/101
2020-01-09 19:33:34 +01:00
Florian Müllner
25b6b562d9 windowPicker: Adjust to gnome-shell changes
WorkspacesDisplay now takes an adjustment for the workspace position,
provide that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/100
2020-01-09 19:25:25 +01:00
Florian Müllner
f2315d28f9 Update sass submodule 2020-01-09 18:29:44 +01:00
Florian Müllner
9b93931de6 Bump version to 3.35.3
Update NEWS.
2020-01-05 13:23:09 +01:00
Florian Müllner
47a2fd36e1 Update sass submodule 2020-01-05 13:23:09 +01:00
Laurent Bigonville
8c1d6d88cf New upstream version 3.34.2 2019-12-30 00:41:31 +01:00
Fran Dieguez
be19802f78 Update Galician translation 2019-12-25 14:29:08 +00:00
Florian Müllner
33b16681c6 Bump version to 3.34.2
Update NEWS.
2019-12-11 22:56:08 +01:00
Florian Müllner
35746251fd Bump version to 3.35.2
Update NEWS.
2019-12-11 18:59:03 +01:00
Umarzuki Bin Mochlis Moktar
3c51716268 Update Malay translation 2019-12-09 11:59:58 +00:00
Willy Stadnick
e5421b6cc6 screenshot-window-sizer: Fix cycling through all valid sizes
When cycling through window sizes, we should skip any sizes that are
bigger than the available area. We do that, but the current code
assumes that the possible sizes are sorted, which is no longer the
case since the addition of "phone" sizes in commit 5b43d4733c.

As a result, we may now skip sizes that would fit perfectly fine.
Address this by filtering out invalid sizes beforehand instead of
assuming a certain order (wich no longer work due to the addition
of a portrait format).

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/97
2019-11-27 20:56:55 +01:00
Willy Stadnick
a2b014ccbf screenshot-window-sizer: Fix cycling through all valid sizes
When cycling through window sizes, we should skip any sizes that are
bigger than the available area. We do that, but the current code
assumes that the possible sizes are sorted, which is no longer the
case since the addition of "phone" sizes in commit 5b43d4733c.

As a result, we may now skip sizes that would fit perfectly fine.
Address this by filtering out invalid sizes beforehand instead of
assuming a certain order (wich no longer work due to the addition
of a portrait format).

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/97
2019-11-26 00:49:08 +01:00
Florian Müllner
f1e7ae1010 workspace-indicator: Exclude DESKTOP windows from window previews
While nautilus removed its desktop support a while ago in favor of an
extension, it's still possible that some external X11 desktop icon app
is used. As DESKTOP windows cannot be moved between workspaces or stacked,
and aren't perceived as regular windows, it doesn't make sense to show
them as previews in the workspace switcher.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/93
2019-11-21 22:47:01 +01:00
Florian Müllner
10fe907c83 window-list: Exclude DESKTOP windows from window previews
While nautilus removed its desktop support a while ago in favor of an
extension, it's still possible that some external X11 desktop icon app
is used. As DESKTOP windows cannot be moved between workspaces or stacked,
and aren't perceived as regular windows, it doesn't make sense to show
them as previews in the workspace switcher.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/93
2019-11-21 22:47:01 +01:00
Florian Müllner
95131dc252 workspace-indicator: Exclude DESKTOP windows from window previews
While nautilus removed its desktop support a while ago in favor of an
extension, it's still possible that some external X11 desktop icon app
is used. As DESKTOP windows cannot be moved between workspaces or stacked,
and aren't perceived as regular windows, it doesn't make sense to show
them as previews in the workspace switcher.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/93
2019-11-21 21:42:16 +00:00
Florian Müllner
f3acb27d61 window-list: Exclude DESKTOP windows from window previews
While nautilus removed its desktop support a while ago in favor of an
extension, it's still possible that some external X11 desktop icon app
is used. As DESKTOP windows cannot be moved between workspaces or stacked,
and aren't perceived as regular windows, it doesn't make sense to show
them as previews in the workspace switcher.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/93
2019-11-21 21:42:16 +00:00
Florian Müllner
a904d51cf7 window-list: Fix faking overview
The public overview properties are now read-only, so switch to the
private properties which back them to fake the overview visibility.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/96
2019-11-21 22:38:50 +01:00
Florian Müllner
30ad3d670f extensions: Stop setting GTypeName
The type name generated by gjs now includes the filename, so we
don't have to set it ourselves to make sure it's unique.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/95
2019-11-21 22:25:43 +01:00
Marco Trevisan (Treviño)
63615cb657 cleanup: Use inheritance for Actor classes instead of composition
Use GObject types when inheriting from native actor classes.

Related to https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/559

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/89
2019-11-21 21:22:26 +00:00
Stas Solovey
ae9809caba Update Russian translation 2019-11-13 18:42:24 +00:00
Jeremy Bicha
c95d197c5c New upstream version 3.34.1 2019-10-08 22:45:42 -04:00
Florian Müllner
a894897770 Bump version to 3.34.1
Update NEWS.
2019-10-09 03:04:32 +02:00
Florian Müllner
1b2c0a4b6c Update sass submodule 2019-10-09 03:04:32 +02:00
Yi-Jyun Pan
8e8b0392a2 Update Chinese (Taiwan) translation 2019-10-08 11:31:58 +00:00
Ask Hjorth Larsen
aea57f0305 Updated Danish translation 2019-10-02 05:54:09 +02:00
Dušan Kazik
6462af30ee Update Slovak translation 2019-09-26 07:15:50 +00:00
Nathan Follens
8d658f7e0d Update Dutch translation 2019-09-25 10:55:33 +00:00
Xiaoguang Wang
05bcd981cd data: Adjust to g-s-d's plugin removals
Remove "org.gnome.SettingsDaemon.Clipboard" and
"org.gnome.SettingsDaemon.Mouse", now the function is moved to
gnome-shell/mutter.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/94
2019-09-17 09:09:22 +08:00
Florian Müllner
ecf608ead8 Revert "ci: Import run-eslint script from gnome-shell"
Filtering errors by changed lines in a merge request means some
errors can slip through, for example when an import becomes unused
but isn't removed.

That's more common than rules changing behind our back, so revert
to running eslint directly again.

This reverts commit 119da3291b.
2019-09-14 01:55:58 +02:00
Iain Lane
ae8749b7e1 New upstream version 3.34.0 2019-09-10 10:53:04 +01:00
Florian Müllner
4ad50ab035 Bump version to 3.34.0
Update NEWS.
2019-09-09 20:32:39 +02:00
Sabri Ünal
934d17db4b Update Turkish translation 2019-09-06 20:09:49 +00:00
Milo Casagrande
b25e9541ce Update Italian translation 2019-09-06 08:41:27 +00:00
Iain Lane
84a548c0b9 New upstream version 3.33.92 2019-09-05 18:21:22 +01:00
Efstathios Iosifidis
3204fd7842 Update Greek translation 2019-09-05 16:28:15 +00:00
Rafael Fontenelle
808f75e998 Update Brazilian Portuguese translation 2019-09-05 05:22:30 +00:00
Florian Müllner
56ecc684cc Bump version to 3.33.92
Update NEWS.
2019-09-04 23:30:47 +02:00
Goran Vidović
67ceca8f70 Update Croatian translation 2019-09-03 15:50:36 +00:00
Fabio Tomat
953445d6cf Update Friulian translation 2019-08-28 07:35:27 +00:00
Ryuta Fujii
cb834f9fa1 Update Japanese translation 2019-08-27 13:00:02 +00:00
Ryuta Fujii
ca2cd844b2 Update Japanese translation 2019-08-27 12:58:15 +00:00
Changwoo Ryu
98b3da41e8 Update Korean translation 2019-08-26 11:17:23 +00:00
Fran Dieguez
c00c749c0b Update Galician translation 2019-08-25 16:13:27 +00:00
Claude Paroz
e11c90365b Updated French translation 2019-08-25 10:44:16 +02:00
Balázs Úr
c812fdc134 Update Hungarian translation 2019-08-24 19:56:32 +00:00
Matej Urbančič
9299db49fb Updated Slovenian translation 2019-08-24 20:05:57 +02:00
Rūdolfs Mazurs
3a15dffe76 Update Latvian translation 2019-08-24 14:33:04 +00:00
Tim Sabsch
3df4e5fdbb Update German translation 2019-08-23 19:29:11 +00:00
Марко Костић
c0a5d0d091 Update Serbian translation 2019-08-21 21:16:23 +00:00
Florian Müllner
d36a196540 Bump version to 3.33.91
Update NEWS.
2019-08-21 20:00:22 +00:00
Florian Müllner
9077687c0a places-menu: Fix loop
Fix fallout from commit 63c07bdc73.
2019-08-21 20:00:22 +00:00
Florian Müllner
fcbfaec53e apps-menu: Adjust to mutter API change
The global grab API got dropped from mutter's Clutter fork, so use the
corresponding input device API instead.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/90
2019-08-21 19:39:11 +02:00
Florian Müllner
7c170e7e90 cleanup: Always use type-safe comparisons
The type coercion performed by the regular == and != operators can
have surprising results. It is therefore considered good practice
to use the type-safe === and !== variants instead.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:44 +00:00
Florian Müllner
ed7a292805 cleanup: Don't use comparison operator when checking falsy values
We mostly use the regular == and != comparison operators over their
type-safe === and !== counterparts. This is about to change, but there
are some places where we don't care whether a value is null, undefined
or 0; just check for falsiness there instead of using operators, so
we can start to consistently use the type-safe operators everywhere
else in a follow-up commit.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:44 +00:00
Florian Müllner
eb79f5b512 cleanup: Require "dangling" commas
Since ES5, trailing commas in arrays and object literals are valid.
We generally haven't used them so far, but they are actually a good
idea, as they make additions and removals in diffs much cleaner.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:44 +00:00
Florian Müllner
eceff51ba1 cleanup: Use consistent brace style of blocks
Our coding style has always been to avoid braces when all blocks
are single-lines. Make sure we apply that style consistently.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:44 +00:00
Florian Müllner
63c07bdc73 cleanup: Don't shadow variables
Having variables that share the same name in overlapping scopes is
confusing and error-prone, and is best avoided.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:44 +00:00
Florian Müllner
fdc3dda484 cleanup: Fix stray/missing spaces
Those are wrong according to our style guidelines, but the previous
eslint ruleset didn't catch them.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:44 +00:00
Florian Müllner
fca516e58a cleanup: Disambiguate assignments in arrow functions
As arrow functions have an implicit return value, an assignment of
this.foo = bar could have been intended as a this.foo === bar
comparison. To catch those errors, we will disallow these kinds
of assignments unless they are marked explicitly by an extra pair
of parentheses.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
c14f7f6fb8 cleanup: Use consistent style for ternary operator
We are currently inconsistent whether to put the operators in front
of the corresonding line or at the end of the preceding one. The
former makes more sense, so go with that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
2497dc6d31 cleanup: Use object destructuring where possible
ES6's destructuring is a nice way of assigning a variable in a concise way,
without duplicating the name of the object property. Use it consistently
where possible.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
a1f38d818d cleanup: Use some more array destructuring
Array destructuring has been supported by gjs/mozjs for quite some time,
so we are already using it heavily where it makes sense.

However one place still sneaked through where using destructuring makes
sense, as the element's position has semantic meaning (instead of just
making it the first, second, ... element).

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
9646149f9a cleanup: Use object shorthand where possible
ES6 allows to omit property names where they match the name of the
assigned variable, which makes code less redundant and thus cleaner.
We will soon enforce that in our eslint rules, so make sure we use
the shorthand wherever possible.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
b6d02f8e1f cleanup: Use operator shorthands where possible
Shorthands like a += b are well-established, so prefer them over the
less concise a = a + b.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
5f96b3c11c cleanup: Don't omit parens when constructing
While it is legal to omit parentheses when invoking a constructor
with no arguments, we generally avoid that in our coding style.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
e217f23767 cleanup: Avoid unnecessary parentheses
Extra parentheses usually add noise rather than clarity, so avoid
them.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
579a290bae screenshot-window-sizer: Rearrange calculation
eslint has a rule to prohibit unnecessary parentheses. While this is
generally a good idea stylistically, the parentheses in a calculation
of (a / b) * c add more clarity, as a / b * c lacks the unambiguity of
proper math notation:

   a                a
  --- * c   vs   -------
   b              b * c

We can still follow the style rule by rearranging to the unambiguous
c * a / b.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
2dc4325a90 places-menu: Use spread operator for variadic function
Invoking functions via Function.prototype.apply() and .call() is
less performant than a regular function call, and makes code harder
to read.

Before ES6 there was no other way of writing a function with variadic
arguments, but since we now have the spread operator, we can use that
as the better alternative.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
376502e952 windowsNavigator: Don't add linebreak before operator
When breaking overly long conditions into multiple lines, the operator
should end the previous line instead of starting the new one.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
91c9982d7f workspace-indicator: Remove some inactive code
This code has been commented out since it was added, presumably due to
difficulty in avoiding a cycle of reloading rows on settings changes
and writing settings on row changes.

Considering that the setting changing while the preference dialog is
up is extremely unlikely, don't bother with making it work and just
remove the dead code.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
c721121a2d native-window-placement: Fix weird comment styles
Don't use gtk-doc style comments for regular comments, and WTF is
/// comment ////?!

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
4007b61cf2 apps-menu: Minor cleanup
We have a much more idiomatic way of transforming one array
into another than pushing values while iterating over the
original array ...

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Florian Müllner
2655419880 lint: Sync configuration with gjs
gjs updated its eslint configuration to a much more complete and
thorough set.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/91
2019-08-21 15:13:43 +00:00
Danial Behzadi
9f1b52c852 Update Persian translation 2019-08-21 11:31:51 +00:00
Jordi Mas
d375cac32e Update Catalan translation 2019-08-21 09:18:10 +02:00
Piotr Drąg
66e2b32c8f Update Polish translation 2019-08-20 19:24:05 +02:00
Daniel Mustieles
95dd651b29 Updated Spanish translation 2019-08-20 12:43:32 +02:00
Aurimas Černius
1534e50a15 Updated Lithuanian translation 2019-08-18 22:07:01 +03:00
Florentina Mușat
23781abead Update Romanian translation 2019-08-18 12:25:30 +00:00
Jiri Grönroos
8065d38fdd Update Finnish translation 2019-08-17 13:00:55 +00:00
Kukuh Syafaat
05faa0763b Update Indonesian translation 2019-08-16 08:44:06 +00:00
Marek Černocký
e88cd44b3c Updated Czech translation 2019-08-16 10:20:25 +02:00
Florian Müllner
85fa282153 lint: Convert eslint JSON to YAML
gjs will change its configuration to YAML, so switch to that format
to keep syncing possible.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/90
2019-08-14 16:34:45 +00:00
Florian Müllner
119da3291b ci: Import run-eslint script from gnome-shell
Since we dropped the legacy configuration, we run eslint directly
instead of via a script. However gnome-shell's variant of the script
also has special treatment of merge requests to only consider errors
in changed lines.

While we strive for zero errors, new errors can appear when we update
eslint or change the configuration. Not blocking merge requests due
to unrelated eslint errors is a good thing, run eslint through a
modified version of the gnome-shell script.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/90
2019-08-14 16:34:45 +00:00
Marco Trevisan (Treviño)
f047cb0baf New upstream version 3.33.90 2019-08-13 04:25:54 +02:00
Anders Jonsson
6675d1c55d Update Swedish translation 2019-08-12 19:32:37 +00:00
Asier Sarasua Garmendia
be1a22069a Update Basque translation 2019-08-12 06:20:02 +00:00
Asier Sarasua Garmendia
2b9162b79d Update Basque translation 2019-08-11 13:48:18 +00:00
Florian Müllner
6aab09bd06 screenshot-window-sizer: Fix imports
Since we replaced Tweener with Clutter animations, we must import the
latter and don't need the former.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/88
2019-08-10 18:33:18 +02:00
Florian Müllner
c336e7d70e Bump version to 3.33.90
Update NEWS.
2019-08-10 00:41:55 +02:00
Florian Müllner
f486dfa112 Update sass submodule 2019-08-10 00:40:11 +02:00
Florian Müllner
80de26dc16 cleanup: Stop using Tweener
gnome-shell added convenience API for Clutter animations and replaced
Tweener everywhere; follow suite and do the same.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/87
2019-08-10 00:27:20 +02:00
Florian Müllner
af6f5fea54 window-list: Adjust animation time
gnome-shell changed all animations times to use milliseconds.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/86
2019-08-10 00:25:08 +02:00
Florian Müllner
9743054174 window-list: Don't override existing signal
Since commit b6a6de9bb5 turned WindowPicker into a ClutterActor
subclass, we already have a 'scroll-event' signal and don't need
to define our own.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/86
2019-08-10 00:25:08 +02:00
Florian Müllner
827af154b8 window-list: Support showing windows from all workspaces
gnome-panel's window list applet has such an option, so let's support
it as well.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/154
2019-08-09 22:20:43 +00:00
Jor Teron
f9b87f9b44 Update Karbi translation 2019-07-25 10:46:02 +00:00
Florian Müllner
a41bcd4f10 Bump version to 3.33.4
Update NEWS.
2019-07-20 18:09:56 +02:00
Piotr Drąg
1a13f29b0c Update POTFILES.in 2019-07-20 14:01:47 +02:00
Florian Müllner
b6a6de9bb5 window-list: Actorize
gnome-shell is in the process of moving from composition to subclassing.
Do the same here, and use custom actor classes instead of "actor" and
"_delegate" properties.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/84
2019-07-20 00:20:51 +02:00
Florian Müllner
5b7631898c cleanup: Use GObject.NotImplementedError
Since version 1.50.0, gjs defines GObject.NotImplementedError for throwing
errors when a virtual method that requires a subclass implementation is not
defined.

So use this instead of a generic JS Error in such cases.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/84
2019-07-20 00:20:51 +02:00
Florian Müllner
f8bae05036 cleanup: Stop using PopupMenuItem.actor properties
Popup menu items are now actor subclasses, and their actor property
points to the item itself.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/84
2019-07-20 00:20:51 +02:00
Florian Müllner
60c75e5fcf classic: Add 'horizontal-workspaces' extension
Vertical workspaces are another defining characteristics of GNOME 3,
and thus rather un-classic. That switch was driven by the overall
layout of the overview, and now that we disable the overview in
GNOME Classic, we can just return to the traditional workspace
layout as well.

Add a small extension that does just that.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/72
2019-07-19 13:54:09 +02:00
Florian Müllner
c6d2063f4d workspace-indicator: Show previews in workspace switcher
Currently the new horizontal workspace switcher only shows a series of
buttons, with no indication of the workspaces' contents. Go full GNOME 2
and add tiny draggable preview rectangles that represent the windows
on a particular workspace.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/77
2019-07-19 13:48:21 +02:00
Florian Müllner
52f373fb70 workspace-indicator: Support horizontal workspace layout
Just like we did for the workspace indicator in the window-list, improve
the handling of horizontal workspace layouts by showing the switcher
in-place instead of delegating the functionality to a menu.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:42:44 +02:00
Florian Müllner
283a1ec5c2 workspace-indicator: Minor cleanup
Pass the style class at construction time instead of setting it later.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:24:50 +02:00
Florian Müllner
c516f05927 workspace-indicator: Refactor workspace signal handlers
We are about to support a separate representation if horizontal
workspaces are used. To prepare for that, rename the handlers to
something more generic and split out menu-specific bits into a
dedicated helper function.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:24:50 +02:00
Florian Müllner
e836a9e5e0 workspace-indicator: Minor cleanup
Mutter has a dedicated method for getting the index of the active
workspace, use that instead of getting first the active workspace
and then its index.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:24:50 +02:00
Florian Müllner
d1674c5f75 workspace-indicator: Update workspace names in-place
There's no good reason to rebuild the entire menu on workspace names
changes, we can simply update the labels in-place.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:24:50 +02:00
Florian Müllner
9fa283877c workspace-indicator: Make some properties private
There's no reason why they should be public.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:24:50 +02:00
Florian Müllner
f1a154207f workspace-indicator: Fix whitespace error
We only want a single space before and after operators, not at least
one. Unfortunately eslint only enforces the latter ...

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71
2019-07-19 13:24:50 +02:00
Florian Müllner
5b07dfded9 window-list: Show previews in workspace switcher
Currently the new horizontal workspace switcher only shows a series of
buttons, with no indication of the workspaces' contents. Go full GNOME 2
and add tiny draggable preview rectangles that represent the windows
on a particular workspace.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/74
2019-07-19 13:16:40 +02:00
Florian Müllner
9f9dbd579b window-list: Turn workspace thumbs into drop targets
It makes some sense to allow using the workspace indicator for moving
windows between workspaces as well as for workspace switching. This
applies particularly in GNOME classic after we disabled the overview
there, so that there is again a non-shortcut way of moving windows
between workspaces.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/74
2019-07-19 13:15:52 +02:00
Florian Müllner
c9477dd94d window-list: Support horizontal workspace layout
Unlike in GNOME 2, the workspace indicator we display in the window list
isn't a workspace switcher, but a menu button that allows switching
workspaces via its menu. The reason for that is that a horizontal
in-place switcher would be at odds with the vertical workspace layout
used in GNOME 3.

However that reasoning doesn't apply when the layout is changed to a
horizontal one, so replace the button with a traditional workspace
switcher in that case.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:22 +02:00
Florian Müllner
5a30ebe403 window-list: Refactor workspace signal handlers
We are about to support a separate representation if horizontal
workspaces are used. To prepare for that, rename the handlers to
something more generic and split out menu-specific bits into a
dedicated helper function.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:15 +02:00
Florian Müllner
a5f347ba10 window-list: Improve workspace label styling
The border currently looks off - it extends all the way vertically
and leaves zero spacing to the label horizontally. Fix both issues
by setting appropriate padding/margins.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:09 +02:00
Florian Müllner
dab326c17e window-list: Minor cleanup
Mutter has a dedicated method for getting the index of the active
workspace, use that instead of getting first the active workspace
and then its index.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:09 +02:00
Florian Müllner
bdf6af3ee3 window-list: Update workspace names in-place
There's no good reason to rebuild the entire menu on workspace names
changes, we can simply update the labels in-place.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:09 +02:00
Florian Müllner
1532c15325 window-list: Make some properties private
There's no reason why they should be public.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:09 +02:00
Florian Müllner
cbd1b7d983 window-list: Use a more specific GTypeName for workspace indicator
Now that the class inherits from GObject, the generic name easily
conflicts with other classes otherwise, for example with the one
from the workspace-indicator extension.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:09 +02:00
Florian Müllner
4b9c53ff2e window-list: Split out workspaceIndicator
The extension has grown unwieldily big, so before starting to improve
on the workspace indicator, move it to its own source file.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70
2019-07-19 13:11:09 +02:00
Florian Müllner
6eb3a62e2b apps-menu: Add drop-shadow to application icons
... to make sure they are readable on light backgrounds.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/168
2019-07-18 11:17:04 +00:00
Florian Müllner
0469fc6aa9 Update sass submodule (again) 2019-07-18 12:32:15 +02:00
Florian Müllner
1f6f22010e Update sass submodule 2019-07-18 12:24:15 +02:00
Jakub Steiner
ae1b17d29c classic: Update window-list styling
Make buttons flatter, rounder to match default styling.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/82
2019-07-16 11:17:11 +02:00
Jakub Steiner
3fa750ce17 classic: No special casing of notifications
The default already handles light variant.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/82
2019-07-16 11:17:10 +02:00
Jakub Steiner
56e2a570e3 classic: hover state for panel buttons
- prelight before active
- lighten up slightly, similar to what the default does (inverted)

Fixes https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/169
2019-07-15 23:45:03 +02:00
Jor Teron
167f0be6b4 Update Karbi translation 2019-07-16 02:51:57 +00:00
Jor Teron
80eb29bd51 Add Karbi translation 2019-07-14 04:30:50 +00:00
Florian Müllner
f2b261c573 window-list: Handle closing window picker with Escape
Just like the overview can be closed with Escape, it makes sense to
allow the same for the window picker (in addition to pressing super
repeatedly).

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/80
2019-07-02 21:20:01 +02:00
Florian Müllner
6c49ca825c window-list: Move super-key handling into WindowPicker
We have an option to put a window list on each monitor, so we may have
more than one window picker toggle. We don't want each of those try to
toggle the window picker simultanuously, so move handling of the super
key directly into the picker.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/80
2019-07-02 21:20:01 +02:00
Florian Müllner
6a25971366 lint: Also allow camelcase for default signal handlers
on_some_signal() is used less than vfunc_some_method(), but it can
still be useful.
2019-07-02 02:44:22 +02:00
Florian Müllner
dc3523a344 lint: Remove misleading globals
While those are defined by gnome-shell, we generally want to define our
own with the correct gettext domain.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/79
2019-06-29 03:07:56 +02:00
Florian Müllner
2ef6dba0a5 window-list: Fix resetting handler ID
This is embarrassing, although destroy() is expected to only run once,
so the bug shouldn't have an effect in practice.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/78
2019-06-29 02:56:33 +02:00
Florian Müllner
92db87f7cb window-list: Add window picker button
With the latest changes, GNOME Classic has become so classic that it
is bordering dull. Salvage at least a tiny piece of GNOME 3 in form
of a window-pick button which toggles an exposé-like reduced overview.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/73
2019-06-28 23:02:58 +02:00
Florian Müllner
82d2011061 classic: Disable overview
The overview is one of the defining features of GNOME 3, and thus
almost by definition at odds with the classic session, which
emulates a traditional GNOME 2 desktop.

Even with the less prominent placement inside the application menu
it never quite fit in - it doesn't help that besides the different
UI paradigma, the overview keeps its "normal" styling which differs
greatly with classic's normal mode.

So besides removing the "Activities" button via the session mode
definition, now that the apps-menu extension doesn't replace it anymore,
disable the overview completely in the classic session.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69
2019-06-28 20:55:28 +00:00
Florian Müllner
545b811562 apps-menu: Hide overview when launching app
Now that we no longer hide the overview when the menu is opened,
it is possible to activate menu entries from the overview. Start
hiding the overview in that case, which is consistent with app
launching elsewhere.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69
2019-06-28 20:55:28 +00:00
Florian Müllner
d99d0a06bd apps-menu: Stop hiding the overview when toggled
Now that the extension no longer doubles as the "Activities" button,
that behavior is confusing.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69
2019-06-28 20:55:28 +00:00
Florian Müllner
6105eecff2 apps-menu: Stop taking over Activities button
We don't want the "Activities" button in GNOME Classic, but the current
way of handling it is confusing:

 - the button is hidden, but the corresponding hot corner
   sometimes works (when the application menu isn't open)

 - the button is effectively moved inside the menu, although
   it's clearly not an app or category

 - the apps-menu can be used independent from classic mode, in
   which case removing the "Activities" button may not be wanted

Address those points by removing any handling of the activities button
from the apps-menu extension. We will remove it again from the classic
session via a session mode tweak.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69
2019-06-28 20:55:28 +00:00
Florian Müllner
d1254d9b57 places-menu: Don't hardcode position
The extension currently assumes that we have the "Activities" button
at the left of the top bar. This is currently true, not only in the
regular session, but also in GNOME classic where the button is hidden
(but still present).

However this is about to change: We will stop taking over the button
from the apps-menu extension, and instead disable "Activities" from
the session mode definition.

Prepare for this by adding the places menu before the application menu
instead of assuming a hardcoded position.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69
2019-06-28 20:55:28 +00:00
Florian Müllner
2db4589dea cleanup: Re-order imports
They should be grouped between external (GI/gjs) and shell and in
alphabetical order. Until commit bab4be1a ExtensionUtils was special
as it was required for some imports, but that's no longer the case
for most extensions.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/76
2019-06-28 21:51:38 +02:00
Florian Müllner
dfeb99fc0a apps-menu: Add missing chain-up
PanelMenu.Button is a bit weird in that it also "contains" its parent
actor. That container is supposed to be destroyed with the button, but
as we currently don't chain up to the parent class' _onDestroy(), we
leave behind an empty container every time the extension is disabled.

Fix this by adding the missing chain-up.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/75
2019-06-27 04:26:35 +02:00
Florian Müllner
48ea80d391 Bump version to 3.33.3
Update NEWS.
2019-06-24 20:34:02 +02:00
Jakub Steiner
b138e218bb classic: fix a broken build
- redesign of the default theme nuked some local variables
  breaking the build.
2019-06-24 20:28:03 +02:00
Florian Müllner
829440f546 Update sass submodule 2019-06-24 20:02:18 +02:00
Marco Trevisan (Treviño)
14859b4009 window-list: Pass the actor as PopupMenuManager owner
PopupMenuManager's grabHelper starting from gnome-shell@7bb84da must be
an actor, so pass it explicitly instead of expecting the shell to do it
for us.

This fixes an error during pushModal that was causing a grab not to be
released.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/68
2019-05-29 14:45:43 -05:00
Florian Müllner
3a596054ad places-menu: Adjust to GObject-ification of menu items
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67
2019-05-29 09:38:21 +00:00
Florian Müllner
65191d83b4 drive-menu: Adjust to GObject-ification of menu items
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67
2019-05-29 09:38:21 +00:00
Florian Müllner
8499b0e254 apps-menu: Adjust to GObject-ification of menu items
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67
2019-05-29 09:38:21 +00:00
Florian Müllner
f166ca501f window-list: Stop using deprecated actor property
Since PanelMenu.Button was changed to inherit from St.Widget, its actor
property is deprecated and points to itself. Stop using it to avoid the
corresponding warning.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67
2019-05-29 09:38:21 +00:00
Florian Müllner
a36331522f Bump version to 3.33.2
Update NEWS.
2019-05-22 18:58:31 +00:00
Florian Müllner
25e43a5d08 lint: Remove legacy configuration
After the last batch of indentation changes, the whole code base
conforms to the new style now, so we can drop the legacy eslint
configuration.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:19 +02:00
Florian Müllner
ad914441a2 window-list: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:19 +02:00
Florian Müllner
200d337769 apps-menu: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:19 +02:00
Florian Müllner
e56f1a976e native-window-placement: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:19 +02:00
Florian Müllner
6a66cd4fa6 places-menu: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:19 +02:00
Florian Müllner
55c493389a auto-move-windows: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:18 +02:00
Florian Müllner
06f1303834 drive-menu: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:18 +02:00
Florian Müllner
3d5687ae3c workspace-indicator: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:18 +02:00
Florian Müllner
cdd3fba593 screenshot-window-sizer: Reindent to conform with new style
Instead of aligning arguments like we used to do, use a consistent
four-space indent as mandated by gjs' current style guide.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66
2019-05-22 20:40:18 +02:00
Florian Müllner
f11c101878 Bump version to 3.33.1
Update NEWS.
2019-05-14 17:53:56 +00:00
Florian Müllner
7c412ca7d9 window-list: Don't use anchor point
It is deprecated and we can easily replace it with a translation.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/64
2019-04-28 11:08:02 +00:00
Florian Müllner
e3a6e8f82c Bump version to 3.32.1
Update NEWS.
2019-04-17 22:09:40 +02:00
Florian Müllner
ce10ad64c4 Update sass submodule 2019-04-17 22:06:50 +02:00
Adrien Plazas
5b43d4733c screenshot-window-sizer: Add phone screenshot sizes
This is going to be convenient to take fake screenshots for phones like
the Librem 5.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/65
2019-04-12 14:31:53 +02:00
Florian Müllner
3671d5a299 cleanup: Use an extension object instead of globals
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/143
2019-04-08 06:00:29 +00:00
Florian Müllner
a024d9f005 windowsNavigator: Use subclasses instead of injections
gnome-shell moved to ES6 classes, which means the constructor is
no longer a regular method that we can swap out with an injected
version.

Instead, do our modifications in subclasses and use them to replace
the original classes.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/143
2019-04-08 06:00:29 +00:00
Fabian P. Schmidt
d94a3500f6 README: Re-add extension alternate-tab with obsolescence notice
This commit adds a short notice about the former extension
alternate-tab to the README. This notice should be removed once
the traffic of users searching for this obsolete extension settled
down.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/62
2019-03-20 12:00:08 +01:00
Iain Lane
28494941e1 New upstream version 3.32.0 2019-03-12 16:33:30 +00:00
Florian Müllner
78141e6433 Bump version to 3.32.0
Update NEWS.
2019-03-12 00:02:14 +01:00
Florian Müllner
dd53fb8eb7 Update sass submodule 2019-03-12 00:01:26 +01:00
Mart Raudsepp
6cd2be452b Update Estonian translation 2019-03-10 17:27:41 +00:00
Kristjan SCHMIDT
36abd576b5 Update Esperanto translation 2019-03-06 21:15:21 +00:00
Victor Ibragimov
730547b3e1 Update Tajik Translation 2019-03-06 21:03:41 +05:00
Iain Lane
b70059ac4d New upstream version 3.31.92 2019-03-06 15:39:47 +00:00
Iain Lane
eb567c1120 New upstream version 3.31.90 2019-02-21 10:08:46 +00:00
Simon McVittie
b1eb9b9080 New upstream version 3.30.1 2018-11-02 09:22:09 +00:00
Jeremy Bicha
a0b6535210 New upstream version 3.30.0 2018-09-05 12:32:25 -04:00
Simon McVittie
9a9b3afa31 New upstream version 3.29.91 2018-08-20 19:55:42 +01:00
Simon McVittie
59bc054ef6 New upstream version 3.29.90 2018-08-02 10:32:10 +01:00
Simon McVittie
57e9dfe722 Merge remote-tracking branch 'origin/upstream/latest' into upstream/latest 2018-07-27 09:14:56 +01:00
Simon McVittie
f17a519c38 New upstream version 3.29.3 2018-07-27 08:43:26 +01:00
Jeremy Bicha
8223ca9739 New upstream version 3.28.1 2018-05-14 21:50:46 -04:00
Jeremy Bicha
fe20c27b60 New upstream version 3.28.0 2018-03-15 21:28:20 -04:00
Jeremy Bicha
5ba59d1096 New upstream version 3.27.92 2018-03-05 20:55:43 -05:00
Jeremy Bicha
0ad1e9bbc1 New upstream version 3.27.91 2018-02-23 19:30:14 -05:00
Jeremy Bicha
5ea14f063f New upstream version 3.26.2 2017-12-15 15:11:42 -05:00
Jeremy Bicha
3cc3d03f0b Initial upstream branch 2017-12-15 15:11:26 -05:00
Florian Müllner
057e5bb0c1 Bump version to 3.26.2
Update NEWS.
2017-11-02 19:51:10 +01:00
Florian Müllner
07fc66765d auto-move: Remove unused imports 2017-10-27 14:45:09 +02:00
Xavi Ivars
daa7b9b6ab [l10n] Updated Catalan (Valencian) translation 2017-10-05 14:02:06 +02:00
147 changed files with 16961 additions and 10366 deletions

View File

@@ -1,6 +0,0 @@
{
"extends": [
"./lint/eslintrc-gjs.json",
"./lint/eslintrc-shell.json"
]
}

3
.eslintrc.yml Normal file
View File

@@ -0,0 +1,3 @@
extends:
- ./lint/eslintrc-gjs.yml
- ./lint/eslintrc-shell.yml

29
.gitignore vendored
View File

@@ -1,29 +0,0 @@
ABOUT-NLS
Makefile
Makefile.in
Makefile.in.in
aclocal.m4
autom4te.cache/
config/
configure
config.log
config.status
data/*.json
m4/
po/*.header
po/*.sed
po/*.sin
po/Makevars.template
po/POTFILES
po/Rules-quot
po/gnome-shell-extensions.pot
po/stamp-it
staging/
zip-files/
*~
*.gmo
metadata.json
*.desktop
*.gschema.valid
*.session

View File

@@ -1,40 +0,0 @@
stages:
- commit_check
- source_check
- build
variables:
LINT_LOG: "eslint-report.txt"
.only_default: &only_default
only:
- branches
- tags
- merge_requests
check_commit_log:
image: registry.gitlab.gnome.org/gnome/gjs:fedora.static-analysis
stage: commit_check
script:
- ./.gitlab-ci/check-commit-log.sh
only:
- merge_requests
eslint:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: source_check
script:
- sh lint/generate-report.sh -o $LINT_LOG || { cat $LINT_LOG; false; }
<<: *only_default
artifacts:
paths:
- ${LINT_LOG}
when: on_failure
build-shell-extensions:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: build
script:
- meson _build .
- ninja -C _build test install
<<: *only_default

View File

@@ -1,31 +0,0 @@
#!/usr/bin/env bash
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
echo Cannot review non-merge request
exit 1
fi
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
branch_point=$(git merge-base HEAD FETCH_HEAD)
commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA)
if [ -z "$commits" ]; then
echo Commit range empty
exit 1
fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}
for commit in $commits; do
if ! commit_message_has_url $commit; then
echo "Missing merge request or issue URL on commit $(echo $commit | cut -c -8)"
exit 1
fi
done

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "data/gnome-shell-sass"]
path = data/gnome-shell-sass
url = https://gitlab.gnome.org/GNOME/gnome-shell-sass.git

313
NEWS
View File

@@ -1,3 +1,316 @@
40.1
====
* Disable welcome dialog in classic session [Florian; !169]
* windowsNavigator: Adjust to a late gnome-shell change [Florian; !170]
Contributors:
Florian Müllner
Translators:
Ngọc Quân Trần [vi], Anders Jonsson [sv], Carmen Bianca BAKKER [eo],
Pawan Chitrakar [ne], Quentin PAGÈS [oc]
40.0
====
Translators:
Jiri Grönroos [fi]
40.rc
=====
* native-window-placement: Adjust to gnome-shell changes [Florian; !164]
* windows-navigator: Adjust to gnome-shell changes [Florian; !163]
* window-list, workspace-indicator: Only show previews for up to six workspaces
[Florian; !165]
* window-list, workspace-indicator: Improve workspace preview appearance
[Florian; !166]
Contributors:
Florian Müllner
Translators:
Fran Dieguez [gl]
40.beta
=======
* Add tooltips to workspace thumbnails [Florian; !155]
* Drop arrows from top bar menus [Florian; !156]
* drive-menu: Mark mounts that can be unmounted as removable [Michael; !152]
* Remove horizontal-workspaces extension [Florian; !158]
* Adjust to shell overview changes [Florian; !159, !160]
* Fix crashes [Daniel; !157]
* Misc. bug fixes and cleanups [Florian; !154, !161]
Contributors:
Michael Lawton, Florian Müllner, Daniel van Vugt
Translators:
Аляксей [be], A S Alam [pa]
40.alpha.1
==========
* Don't depend on sassc when building from tarball [Florian; !150]
* Port extensions preferences to GTK4 [Florian; !148]
* Misc. bug fixes and cleanups [Florian, Jonas; !149, !151, !153]
Contributors:
Jonas Dreßler, Florian Müllner
40.alpha
========
* window-list: Honor changes in skip-taskbar property [Sergio; !130]
* window-list, workspace-indicator: Adjust to 3.38 changes [Florian; !133]
* window-list, workspace-indicator: Improve previews in workspace thumbs
[Florian; #260, !142]
* auto-move: Improve behavior on multi-monitor setups [Florian; !135]
* windowNavigator: Adjust to 3.38 changes [Thun; #259]
* Misc. bug fixes and cleanups [Florian, Jonas Å, Jordan, Ray; !131, !136,
!137, !140, !141, !144, !146, !145]
Contributors:
Sergio Costas, Florian Müllner, Jordan Petridis, Thun Pin, Ray Strode,
Jonas Ådahl
Translators:
Fabio Tomat [fur], Jordi Mas [ca]
3.38.1
======
Contributors:
Yacine Bouklif, Florian Müllner
Translators:
Yacine Bouklif [kab], Cheng-Chia Tseng [zh_TW], Stas Solovey [ru],
Yosef Or Boczko [he]
3.38.0
======
Translators:
Balázs Meskó [hu], Alan Mortensen [da], Juliano Camargo [pt], Tim Sabsch [de],
Milo Casagrande [it], Rūdolfs Mazurs [lv]
3.37.92
=======
Translators:
Nathan Follens [nl], Zander Brown [en_GB], Aurimas Černius [lt],
Marek Černocký [cs], Changwoo Ryu [ko], Dušan Kazik [sk]
3.37.91
=======
Contributors:
Florian Müllner
Translators:
Fran Dieguez [gl], Akarshan Biswas [bn_IN], Kukuh Syafaat [id],
Piotr Drąg [pl], Rafael Fontenelle [pt_BR], Jiri Grönroos [fi],
Марко Костић [sr], Goran Vidović [hr]
3.37.90
=======
* Misc. bug fixes and cleanups [Florian, Piotr; !126, !128]
Contributors:
Piotr Drąg, Florian Müllner
Translators:
Fabio Tomat [fur], Efstathios Iosifidis [el], Anders Jonsson [sv],
Asier Sarasua Garmendia [eu], Alexandre Franke [fr]
3.37.3
======
* window-list, native-window-placement: Adjust to shell changes [Florian; !124]
Contributors:
Florian Müllner
Translators:
Jordi Mas [ca], sicklylife [ja], Boyuan Yang [zh_CN],
Baurzhan Muftakhidinov [kk]
3.37.2
======
* window-list, auto-move: Modernize preference dialogs [Florian; !121]
* Adjust to gnome-shell changes [Florian; !122]
Contributors:
Florian Müllner
Translators:
Cheng-Chia Tseng [zh_TW], Yuri Chornoivan [uk], Daniel Mustieles [es],
Emin Tufan Çetin [tr], Danial Behzadi [fa], Daniel Șerbănescu [ro],
Matej Urbančič [sl]
3.37.1
======
* drive-menu: Emphasize eject buttons [Florian; #223]
* user-theme: Add preference dialog [Florian; !117]
* window-list: Fix inconsistent state in preference dialog [Milan; !119]
* workspace-indicator: Overhaul preference dialog [Florian; !120]
* user-theme: Support session mode styles [Florian; !118]
* Misc. bug fixes and cleanups [Florian, Xiaoguang; !113, !106, !114, !116]
Contributors:
Milan Crha, Florian Müllner, Xiaoguang Wang
Translators:
Daniel Korostil [uk], Yosef Or Boczko [he], Kristjan SCHMIDT [eo],
Dz Chen [zh_CN], Danial Behzadi [fa], Yuri Chornoivan [uk],
Anders Jonsson [sv], Daniel Mustieles [es]
3.36.0
======
Contributors:
Florian Müllner
3.35.91
=======
Contributors:
Florian Müllner
Translators:
Zander Brown [en_GB]
3.35.90
=======
* Adjust to gnome-shell changes [Florian; !100, !101, !102]
* Force single-line window titles in window list [Florian; #202]
* Misc. bug fixes and cleanup [Florian; !104, !105]
Contributors:
Florian Müllner
Translators:
sicklylife [ja], Umarzuki Bin Mochlis Moktar [ms]
3.35.3
======
Translators:
Fran Dieguez [gl]
3.35.2
======
* Adjust to gnome-shell changes [Marco, Florian; !89, !95, !96]
* window-list, workspace-indicator: Exclude DESKTOP windows from previews
[Florian; !93]
* screenshot-window-sizer: Fix cycling through all valid sizes [Willy; !97]
Contributors:
Marco Trevisan (Treviño), Florian Müllner, Willy Stadnick
3.34.1
======
* Adjust to gnome-settings-daemon plugin removals [Xiaoguang; !94]
Contributors:
Florian Müllner, Xiaoguang Wang
Translators:
Nathan Follens [nl], Dušan Kazik [sk], Ask Hjorth Larsen [da],
Yi-Jyun Pan [zh_TW]
3.34.0
======
Translators:
Rafael Fontenelle [pt_BR], Efstathios Iosifidis [el], Milo Casagrande [it],
Sabri Ünal [tr]
3.33.92
=======
Translators:
Марко Костић [sr], Tim Sabsch [de], Rūdolfs Mazurs [lv], Matej Urbančič [sl],
Balázs Úr [hu], Claude Paroz [fr], Fran Dieguez [gl], Changwoo Ryu [ko],
Ryuta Fujii [ja], Fabio Tomat [fur], Goran Vidović [hr]
3.33.91
=======
* Misc. bug fixes and cleanups [Florian; !88, !90, !91, !92]
Contributors:
Florian Müllner
Translators:
Asier Sarasua Garmendia [eu], Anders Jonsson [sv], Marek Černocký [cs],
Kukuh Syafaat [id], Jiri Grönroos [fi], Florentina Mușat [ro],
Aurimas Černius [lt], Daniel Mustieles [es], Piotr Drąg [pl], Jordi Mas [ca],
Danial Behzadi [fa]
3.33.90
=======
* window-list: Support showing windows from all workspaces [Florian; #154]
* Misc. bug fixes and cleanups [Florian; !86, !87]
Contributors:
Florian Müllner
Translators:
Jor Teron [mjw]
3.33.4
======
* Make GNOME Classic more classic:
- Disable GNOME 3 overview [Florian; !69]
- Add window picker button to window list [Florian; !73, !80]
- Style improvements and fixes [Jakub; #169, !82]
- Support horizontal workspace layout in window list [Florian; !70]
- Add draggable previews to window list workspace switcher [Florian; !74]
- Arrange workspaces horizontally [Florian; !72]
* workspace-indicator: Support horizontal workspace layout [Florian; !71]
* workspace-indicator: Add draggable previews [Florian; !77]
* Misc. bug fixes and cleanups [Florian; !75, !76, !79, !78, #168, !84]
Contributors:
Florian Müllner, Jakub Steiner, Jor Teron
Translators:
Jor Teron [mjw]
3.33.3
======
* Misc. bug fixes [Florian, Marco; !67, !68]
Contributors:
Florian Müllner, Marco Trevisan (Treviño)
3.33.2
======
* Misc. bug fixes and cleanups [Florian; !66]
Contributors:
Florian Müllner
3.33.1
======
* Misc. bug fixes [Florian; !64]
Contributors:
Florian Müllner
3.32.1
======
* Fix windowsNavigator extension after ES6 port [Florian; #143]
* screenshot-window-sizer: Add phone screenshot sizes [Adrien; !65]
* Misc. bug fixes and cleanups [Fabian; !62]
Contributors:
Florian Müllner, Adrien Plazas, Fabian P. Schmidt
3.32.0
======
Contributors:
Florian Müllner
Translations:
Victor Ibragimov [tg], Kristjan SCHMIDT [eo], Mart Raudsepp [et]
3.31.92
=======
* Misc. bug fixes and cleanups [Florian; !57, !58, !59, !60]

View File

@@ -15,6 +15,12 @@ Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
## Extensions
* alternate-tab (**OBSOLETE**)
Lets you use classic Alt+Tab (window-based instead of app-based) in GNOME Shell.
This extension is obsolete since GNOME 3.30, see [this blogpost][alternatetab-post]
for further details.
* apps-menu
Lets you reach an application using gnome 2.x style menu on the panel.
@@ -74,3 +80,4 @@ file for details.
[shell-page]: https://wiki.gnome.org/Projects/GnomeShell
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues
[license]: COPYING
[alternatetab-post]: https://blogs.gnome.org/fmuellner/2018/10/11/the-future-of-alternatetab-and-why-you-need-not-worry/

View File

@@ -1,8 +1,10 @@
{
"parentMode": "user",
"stylesheetName": "gnome-classic.css",
"hasOverview": false,
"showWelcomeDialog": false,
"enabledExtensions": [@CLASSIC_EXTENSIONS@],
"panel": { "left": ["activities", "appMenu"],
"panel": { "left": ["appMenu"],
"center": [],
"right": ["a11y", "keyboard", "dateMenu", "aggregateMenu"]
}

2290
data/gnome-classic.css Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Name=GNOME Classic
Comment=This session logs you into GNOME Classic
Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session --session gnome-classic
Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session
TryExec=gnome-session
Type=Application
DesktopNames=GNOME-Classic;GNOME;

View File

@@ -4,6 +4,7 @@ $variant: 'light';
@import "gnome-shell-sass/_colors"; //use gtk colors
@import "gnome-shell-sass/_drawing";
@import "gnome-shell-sass/_common";
@import "gnome-shell-sass/_widgets";
/* Overrides */
@@ -32,18 +33,32 @@ $variant: 'light';
font-weight: normal;
color: $fg_color;
text-shadow: none;
&:active, &:overview, &:focus, &:checked {
// Trick due to St limitations. It needs a background to draw
// a box-shadow
background-color: $selected_bg_color !important;
color: $selected_fg_color !important;
box-shadow: none;
& > .system-status-icon { icon-shadow: none; }
transition-duration: 0ms;
border: 0;
border-radius: 0px;
&.clock-display {
.clock {
transition-duration: 0ms;
border: 0;
border-radius: 0px;
}
}
&:hover {
color: lighten($fg_color,10%);
text-shadow: none;
& .system-status-icon { icon-shadow: none; }
}
&:active, &:overview, &:focus, &:checked {
// Trick due to St limitations. It needs a background to draw
// a box-shadow
background-color: $selected_bg_color;
color: $selected_fg_color;
box-shadow: none;
& > .system-status-icon { icon-shadow: none; }
}
.app-menu-icon { width: 0; height: 0; margin: 0; } // shell's display:none; :D
.system-status-icon {
@@ -60,13 +75,12 @@ $variant: 'light';
&.lock-screen,
&.unlock-screen,
&.login-screen {
background-color: transparentize($_bubble_bg_color, 0.5);
background-gradient-start: transparentize($_bubble_bg_color, 0.5);
background-gradient-end: transparentize($_bubble_bg_color, 0.5);
background-color: transparentize($bg_color, 0.5);
background-gradient-start: transparentize($bg_color, 0.5);
background-gradient-end: transparentize($bg_color, 0.5);
border-bottom: none;
.panel-button { color: $osd_fg_color; }
}
.popup-menu-arrow { width: 0; height: 0; } // shell's display: none;
}
#appMenu {
@@ -91,15 +105,3 @@ $variant: 'light';
background-image: url("calendar-today.svg");
}
.message-list-clear-button.button {
color: $fg_color
}
.notification-banner {
background-color: $bg_color !important;
color: $fg_color;
.notification-button {
background-color: darken($bg_color,5%);
&:hover, &focus { background-color: darken($bg_color,2%); }
}
}

View File

@@ -1,3 +0,0 @@
[GNOME Session]
Name=GNOME Classic
RequiredComponents=org.gnome.Shell;org.gnome.SettingsDaemon.A11ySettings;org.gnome.SettingsDaemon.Clipboard;org.gnome.SettingsDaemon.Color;org.gnome.SettingsDaemon.Datetime;org.gnome.SettingsDaemon.Housekeeping;org.gnome.SettingsDaemon.Keyboard;org.gnome.SettingsDaemon.MediaKeys;org.gnome.SettingsDaemon.Mouse;org.gnome.SettingsDaemon.Power;org.gnome.SettingsDaemon.PrintNotifications;org.gnome.SettingsDaemon.Rfkill;org.gnome.SettingsDaemon.ScreensaverProxy;org.gnome.SettingsDaemon.Sharing;org.gnome.SettingsDaemon.Smartcard;org.gnome.SettingsDaemon.Sound;org.gnome.SettingsDaemon.Wacom;org.gnome.SettingsDaemon.XSettings;

View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

View File

@@ -0,0 +1,16 @@
# GNOME Shell Sass
GNOME Shell Sass is a project intended to allow the sharing of the
theme sources in sass between gnome-shell and other projects like
gnome-shell-extensions.
Any changes should be done in the [GNOME Shell subtree][shell-subtree]
and not the stand-alone [gnome-shell-sass repository][sass-repo]. They
will then be synchronized periodically before releases.
## License
GNOME Shell Sass is distributed under the terms of the GNU General Public
License, version 2 or later. See the [COPYING][license] file for details.
[shell-subtree]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/master/data/theme/gnome-shell-sass
[sass-repo]: https://gitlab.gnome.org/GNOME/gnome-shell-sass
[license]: COPYING

View File

@@ -0,0 +1,44 @@
// When color definition differs for dark and light variant,
// it gets @if ed depending on $variant
$base_color: if($variant == 'light', #fff, lighten(desaturate(#241f31, 20%), 2%));
$bg_color: if($variant == 'light', #f6f5f4, darken(desaturate(#3d3846, 100%), 4%));
$fg_color: if($variant == 'light', #2e3436, #eeeeec);
$selected_fg_color: #fff;
$selected_bg_color: if($variant == 'light', #3584e4, darken(#3584e4, 10%));
$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, 8%));
$borders_edge: if($variant == 'light', rgba(255,255,255,0.8), 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%));
$top_hilight: $borders_edge;
$warning_color: #f57900;
$error_color: #ff8080;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$osd_fg_color: #eeeeec;
$osd_text_color: white;
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04);
$osd_insensitive_bg_color: transparentize(mix($osd_fg_color, opacify($osd_bg_color, 1), 10%), 0.5);
$osd_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
$osd_borders_color: transparentize(black, 0.3);
$osd_outer_borders_color: transparentize(white, 0.84);
$shadow_color: if($variant == 'light', rgba(0,0,0,0.1), rgba(0,0,0,0.2));
$system_bg_color: desaturate(#241f31,100%); //neutralize the HIG color
//insensitive state derived colors
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
$insensitive_bg_color: mix($bg_color, $base_color, 60%);
$insensitive_borders_color: mix($borders_color, $base_color, 60%);
//colors for the backdrop state, derived from the main colors.
$backdrop_base_color: if($variant =='light', darken($base_color,1%), lighten($base_color,1%));
$backdrop_bg_color: $bg_color;
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
$backdrop_insensitive_color: if($variant =='light', darken($backdrop_bg_color,15%), lighten($backdrop_bg_color,15%));
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);

View File

@@ -0,0 +1,176 @@
//This is the RIGHT PLACE to edit the stylesheet
//let's start by telling people not to edit the generated CSS:
$cakeisalie: "This stylesheet is generated, DO NOT EDIT";
/* #{$cakeisalie} */
/* Copyright 2009, 2015 Red Hat, Inc.
*
* Portions adapted from Mx's data/style/default.css
* Copyright 2009 Intel Corporation
*
* 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, write to the Free Software Foundation,
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Global Values */
// padding, margin and spacing
$base_padding: 6px;
$base_margin: 4px;
$base_spacing: 6px;
// border radii
$base_border_radius: 8px;
$modal_radius:$base_border_radius * 2;
// non-standard colors
$bubble_borders_color: lighten($borders_color, if($variant=='light', 0%, 5%));
// $bubble_borders_color: if($variant == 'light', rgba(255,255,255,0.1), rgba(0,0,0,0.3));
// hover
$hover_bg_color: if($variant=='light', darken($bg_color, 3%), lighten($bg_color, 5%));
$hover_fg_color: if($variant=='light', darken($fg_color, 5%), lighten($fg_color, 5%));
$hover_borders_color: lighten($borders_color,if($variant=='light', 5%, 3%));
// active
$active_bg_color: if($variant == 'light', darken($bg_color, 7%), darken($bg_color, 9%));
$active_fg_color: darken($fg_color,if($variant=='light', 5%, 3%));
$active_borders_color: darken($borders_color,if($variant=='light', 5%, 3%));
// fonts
$base_font_size: 11;
$text_shadow_color: if($variant == 'light', rgba(255,255,255,0.3), rgba(0,0,0,0.2));
// icons
$base_icon_size: 1.09em;
// $base_icon_size: 16px;
// Stage
stage {
@include fontsize($base_font_size);
color: $fg_color;
}
/* Common Stylings */
// Text
%status_text {
font-size: 2em;
font-weight: bold;
color: $osd_fg_color;
}
// osd panels
%osd_panel {
color: $osd_fg_color;
background-color: $osd_bg_color;
//border: 1px solid $osd_outer_borders_color;
border-radius: $base_border_radius * 2 + 4px;
padding: $base_padding * 2;
}
// Overview panels
// for the dash and workspace switcher
%overview_panel {
color: $osd_fg_color;
background-color: transparentize($osd_fg_color, 0.9);
}
// icon tiles
%icon_tile {
border-radius: $base_border_radius + 4px;
padding: $base_padding;
border: 2px solid transparent;
transition-duration: 100ms;
text-align: center;
}
// dialogs
%bubble_panel {
color: $fg_color;
background-color: $bg_color;
border: 1px solid if($variant=='light', rgba(0,0,0, 0.6), $borders_color);
}
// button styling
%button {
border-radius: $base_border_radius;
border-style: solid;
border-width: 1px;
min-height: 22px;
padding: $base_padding * 0.5 $base_padding * 4;
@include button(normal);
&:focus { @include button(focus);}
&:hover { @include button(hover);}
&:insensitive { @include button(insensitive);}
&:active { @include button(active);}
}
// buttons in dialogs
%bubble_button {
@include button(normal, $shadow: none);
padding: $base_padding * 2;
border-style: solid;
border-width: 1px;
border-left-width: 0;
border-bottom-width: 0;
&:insensitive { @include button(insensitive, $shadow: none); }
&:focus { @include button(focus, $shadow: none); }
&:hover { @include button(hover, $shadow: none); }
&:active { @include button(active, $shadow: none); }
// radius is 2 pixel less to fit in bubble
&:first-child {
border-radius: 0 0 0 $modal_radius - 2px;
}
&:last-child {
border-right-width: 0;
border-radius: 0 0 $modal_radius - 2px 0;
}
&:first-child:last-child {
border-radius: 0 0 $modal_radius - 2px $modal_radius - 2px;
}
}
// notification styling
@mixin notification_bubble($flat: false) {
border-width: 1px;
border-style: solid;
border-radius: $base_border_radius + 2px;
margin: $base_margin;
@if $flat {
@include button(undecorated);
} @else {
@include button(normal);
}
&:focus {
@include button(focus);
}
&:hover {
@include button(hover);
}
&:active {
@include button(active);
}
}

View File

@@ -0,0 +1,232 @@
// Drawing mixins
// generic drawing of more complex things
@function draw_widget_edge($c:$borders_edge) {
// outer highlight "used" on most widgets
@return 0 1px $c;
}
// provide font size in rem, with px fallback
@mixin fontsize($size: 24, $base: 16) {
font-size: round($size) + pt;
//font-size: ($size / $base) * 1rem;
}
@mixin draw_shadows($shadow1, $shadow2:none, $shadow3:none, $shadow4:none) {
//
// Helper function to stack up to 4 box-shadows;
//
@if $shadow4!=none { box-shadow: $shadow1, $shadow2, $shadow3, $shadow4; }
@else if $shadow3!=none { box-shadow: $shadow1, $shadow2, $shadow3; }
@else if $shadow2!=none { box-shadow: $shadow1, $shadow2; }
@else { box-shadow: $shadow1; }
}
// entries
@mixin entry($t, $fc:$selected_bg_color, $edge: $borders_edge) {
//
// Entries drawing function
//
// $t: entry type
// $fc: focus color
// $edge: set to none to not draw the bottom edge or specify a color to not use the default one
//
// possible $t values:
// normal, focus, insensitive
//
@if $t==normal {
background-color: $base_color;
border-color: $borders_color;
}
@if $t==focus {
border-color: if($fc==$selected_bg_color,
$selected_borders_color,
darken($fc,35%));
box-shadow: inset 0 0 0 1px $fc;
}
@if $t==hover { }
@if $t==insensitive {
color: $insensitive_fg_color;
border-color: $insensitive_bg_color;
box-shadow: none;
}
}
// buttons
@function draw_border_color ($c) {
//
// colored buttons want the border form the base color
//
@return if($variant == 'light', darken($c, 18%), darken($c, 4%));
}
@function draw_text_shadow_color ($tc:$fg_color, $bg:$bg_color) {
//
// calculate the color of text shadows
//
// $tc is the text color
// $bg is the background color
//
$lbg: lightness($bg)/100%;
@if lightness($tc)<50% { @return rgba(255,255,255,$lbg/($lbg*1.3)); }
@else { @return rgba(0,0,0,1-$lbg*0.8); }
}
@function draw_button_hilight_color($c) {
//
// calculate the right top highlight color for buttons
//
// $c: base color;
//
@if lightness($c)>90% { @return white; }
@else if lightness($c)>80% { @return rgba(255,255,255, 0.7); }
@else if lightness($c)>50% { @return rgba(255,255,255, 0.5); }
@else if lightness($c)>40% { @return rgba(255,255,255, 0.3); }
@else { @return rgba(255,255,255, 0.1); }
}
@mixin draw_button_text_shadow ($tc:$fg_color, $bg:$bg_color) {
//
// helper function for the text emboss effect
//
// $tc is the optional text color, not the shadow color
//
// TODO: this functions needs a way to deal with special cases
//
$shadow: draw_text_shadow_color($tc, $bg);
@if lightness($tc)<50% {
text-shadow: 0 1px $shadow;
icon-shadow: 0 1px $shadow;
}
@else {
text-shadow: 0 -1px $shadow;
icon-shadow: 0 -1px $shadow;
}
}
@mixin button($t, $c:$bg_color, $tc:$fg_color, $edge: $borders_edge, $shadow: $shadow_color) {
//
// Button drawing function
//
// $t: button type,
// $c: base button color for colored* types
// $tc: optional text color for colored* types
// $edge: set to none to not draw the bottom edge or specify a color to not
// use the default one
// $shadow: set to none to not draw the drop shadow or specify a color to not
// use the default one
//
// possible $t values:
// normal, hover, active, insensitive, insensitive-active,
// backdrop, backdrop-active, backdrop-insensitive, backdrop-insensitive-active,
// osd, osd-hover, osd-active, osd-insensitive, osd-backdrop, undecorated
//
$hilight_color: draw_button_hilight_color($c);
$button_edge: if($edge == none, none, draw_widget_edge($edge));
$blank_edge: if($edge == none, none, draw_widget_edge(transparentize($edge,1)));
$button_shadow: if($shadow == none, none, 0 1px 1px 0 $shadow);
// normal button
@if $t==normal {
color: $tc;
background-color: lighten($c, 3%);
border-color: draw_border_color($c);
@include draw_shadows($button_shadow);
// box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
}
// focused button
@if $t==focus {
color: $tc;
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
box-shadow: inset 0 0 0 2px transparentize($selected_bg_color, 0.4);
//border-color: $selected_bg_color;
}
// hover button
@else if $t==hover {
color: $tc;
background-color: lighten($c, if($variant == 'light', 8%, 5%));
border-color: if($variant == 'light', draw_border_color(lighten($c, 7%)), draw_border_color($c));
@include draw_shadows($button_shadow);
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
}
// active button
@else if $t==active {
color: $tc;
background-color: darken($c,3%);
border-color: draw_border_color(if($variant == 'light', $c, darken($c,7%)));
text-shadow: none;
icon-shadow: none;
box-shadow: none;
}
// insensitive button
@else if $t==insensitive {
color: $insensitive_fg_color;
border-color: $insensitive_borders_color;
background-color: $insensitive_bg_color;
box-shadow: none;
text-shadow: none;
icon-shadow: none;
}
// reset
@else if $t==undecorated {
border-color: transparent;
background-color: transparent;
background-image: none;
@include draw_shadows(inset 0 1px rgba(255,255,255,0),$blank_edge);
text-shadow: none;
icon-shadow: none;
}
}
// overview icons
@mixin overview-icon($color) {
.overview-icon {
@extend %icon_tile;
color: $color;
}
&:hover,
&:selected {
.overview-icon {
background-color: transparentize($color, .9);
}
}
&:focus {
.overview-icon {
background-color: transparentize($color, .7);
// border-color: $selected_bg_color;
}
}
&:drop {
.overview-icon {
border: 2px solid $selected_bg_color; //already 2px transparent so no jumping
background-color: transparentize($selected_bg_color, .8);
}
}
&:active,
&:checked {
.overview-icon {
background-color: transparentize(darken($osd_bg_color, 10%), .5);
}
}
}

View File

@@ -0,0 +1,42 @@
// When color definition differs for dark and light variant,
// it gets @if ed depending on $variant
$base_color: #222;
$bg_color: #000;
$fg_color: #fff;
$selected_fg_color: #ffffff;
$selected_bg_color: darken(#4a90d9,20%);
$selected_borders_color: darken($selected_bg_color, 20%);
$borders_color: darken($bg_color,12%);
$borders_edge: transparentize($fg_color, 0.9);
$link_color: lighten($selected_bg_color,20%);
$link_visited_color: lighten($selected_bg_color,10%);
$top_hilight: $borders_edge;
$warning_color: #f57900;
$error_color: #cc0000;
$success_color: darken(#73d216,10%);
$destructive_color: darken(#ef2929,10%);
$osd_fg_color: #eeeeec;
$osd_bg_color: #2e3436;
$osd_borders_color: rgba(0,0,0, 0.7);
$osd_outer_borders_color: rgba(255,255,255, 0.1);
$shadow_color: rgba(0,0,0, 0.1);
$system_bg_color: desaturate(#241f31,100%); //neutralize the HIG color
//insensitive state derived colors
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
$insensitive_bg_color: mix($bg_color, $base_color, 60%);
$insensitive_borders_color: $borders_color;
//colors for the backdrop state, derived from the main colors.
$backdrop_base_color: lighten($base_color,1%);
$backdrop_bg_color: $bg_color;
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
$backdrop_insensitive_color: lighten($backdrop_bg_color,15%);
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);

View File

@@ -0,0 +1,51 @@
//
// Shell widgets stylesheets are placed in separate .scss files
// in 'widgets' and imported into the main stylesheet in this file.
// To create or update a widget for the shell modify the list below.
//
/* WIDGETS */
// Primary widgets
@import 'widgets/base';
@import 'widgets/entries';
@import 'widgets/buttons';
@import 'widgets/check-box';
@import 'widgets/switches';
@import 'widgets/slider';
@import 'widgets/scrollbars';
// Popovers
@import 'widgets/popovers';
@import 'widgets/calendar';
@import 'widgets/message-list';
@import 'widgets/ibus-popup';
// Notifications
@import 'widgets/notifications';
@import 'widgets/hotplug';
// Dialogs
@import 'widgets/dialogs';
@import 'widgets/network-dialog';
// OSDs
@import 'widgets/osd';
@import 'widgets/switcher-popup';
@import 'widgets/workspace-switcher';
// Panel
@import 'widgets/panel';
@import 'widgets/corner-ripple';
// Overview
@import 'widgets/overview';
@import 'widgets/window-picker';
@import 'widgets/search-entry';
@import 'widgets/search-results';
@import 'widgets/dash';
@import 'widgets/app-grid';
@import 'widgets/workspace-thumbnails';
// A11y / misc
@import 'widgets/a11y';
@import 'widgets/misc';
@import 'widgets/tiled-previews';
@import 'widgets/keyboard';
@import 'widgets/looking-glass';
// Lock / login screens
@import 'widgets/login-dialog';
@import 'widgets/screen-shield';

View File

@@ -0,0 +1,37 @@
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:gnome="http://api.gnome.org/doap-extensions#"
xmlns="http://usefulinc.com/ns/doap#">
<name xml:lang="en">GNOME Shell Sass</name>
<shortdesc xml:lang="en">Sass sources of GNOME Shell</shortdesc>
<description>GNOME Shell Sass is a project intended to allow the sharing of the
sass theme sources between gnome-shell and other projects like gnome-shell-extensions.</description>
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
<programming-language>sass</programming-language>
<programming-language>css</programming-language>
<maintainer>
<foaf:Person>
<foaf:name>Carlos Soriano</foaf:name>
<foaf:mbox rdf:resource="mailto:csoriano@gnome.org" />
<gnome:userid>csoriano</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Florian Müllner</foaf:name>
<foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" />
<gnome:userid>fmuellner</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Jakub Steiner</foaf:name>
<foaf:mbox rdf:resource="mailto:jimmac@gmail.com" />
<gnome:userid>jimmac</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@@ -0,0 +1,24 @@
// Pointer location
.ripple-pointer-location {
width: $ripple_size;
height: $ripple_size;
border-radius: $ripple_size * 0.5; // radius equals the size of the box to give us the curve
background-color: lighten(transparentize($selected_bg_color, 0.7), 30%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
}
// Pointer accessibility notifications
.pie-timer {
width: 60px;
height: 60px;
-pie-border-width: 3px;
-pie-border-color: $selected_bg_color;
-pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
}
// Screen zoom/Magnifier
.magnifier-zoom-region {
border: 2px solid $selected_bg_color;
&.full-screen { border-width: 0; }
}

View File

@@ -0,0 +1,168 @@
/* App Grid */
$app_icon_size: 96px;
// app icons
.icon-grid {
row-spacing: $base_spacing * 2;
column-spacing: $base_spacing * 2;
max-row-spacing: $base_spacing * 12;
max-column-spacing: $base_spacing * 12;
page-padding-top: $base_padding * 4;
page-padding-bottom: $base_padding * 4;
page-padding-left: $base_padding * 2;
page-padding-right: $base_padding * 2;
}
/* App Icons */
$app_grid_fg_color: #fff;
// Icon tiles in the app grid
.app-well-app,
%app-well-app {
@include overview-icon($app_grid_fg_color);
.overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
> StBoxLayout {
spacing: $base_spacing;
}
}
}
/* App Folders */
.app-well-app.app-folder {
background-color: $dash_background_color;
border-radius: $base_border_radius + 4px; // same as %icon_tile
}
// expanded folder
.app-folder-dialog { //style like the dash
border-radius: $modal_radius * 1.5;
background-color: $dash_background_color;
padding: 12px 0px 12px 0px;
& .folder-name-container {
padding: 24px 36px 0;
spacing: 12px;
& .folder-name-label,
& .folder-name-entry {
font-size: 18pt;
font-weight: 800;
}
& .folder-name-entry { width: 300px }
/* FIXME: this is to keep the label in sync with the entry */
& .folder-name-label { padding: 5px 7px; color: $osd_fg_color; }
& .edit-folder-button {
@extend %button;
padding: 0;
width: 36px;
height: 36px;
border-radius: 18px;
& > StIcon { icon-size: 16px }
}
}
& .icon-grid {
row-spacing: $base_spacing * 2;
column-spacing: $base_spacing * 5;
page-padding-top: 0;
page-padding-bottom: 0;
page-padding-left: 0;
page-padding-right: 0;
}
& .page-indicators {
margin-bottom: 18px;
}
}
.app-folder-dialog-container {
padding: 12px;
width: 620px;
height: 620px;
}
// Running app indicator (also shown in dash)
.app-well-app-running-dot {
height: 5px;
width: 5px;
border-radius:5px;
background-color: $osd_fg_color;
margin-bottom: 1px;
}
// Rename popup for app folders
.rename-folder-popup {
.rename-folder-popup-item {
spacing: $base_spacing;
&:ltr, &:rtl { padding: 0 $base_padding * 2; }
}
}
// right-click app menu
.app-menu,
.app-well-menu {
max-width: 27.25em;
}
// App Grid pagination indicators
.page-indicator {
padding: $base_padding $base_padding * 2 0;
.page-indicator-icon {
width: 10px;
height: 10px;
border-radius: 10px; // the same as height&width
background-color: white;
}
}
.apps-scroll-view {
padding: 0;
}
// shutdown and other actions in the grid
.system-action-icon {
background-color: rgba(0,0,0,0.8);
color: #fff;
border-radius: 99px;
icon-size: $app_icon_size * 0.5;
}
.page-navigation-hint {
width: 300px;
&.dnd {
background: rgba(255, 255, 255, 0.1);
}
&.next:ltr,
&.previous:rtl {
background-gradient-start: rgba(255, 255, 255, 0.05);
background-gradient-end: transparent;
background-gradient-direction: horizontal;
border-radius: 15px 0px 0px 15px;
}
&.previous:ltr,
&.next:rtl {
background-gradient-start: transparent;
background-gradient-end: rgba(255, 255, 255, 0.05);
background-gradient-direction: horizontal;
border-radius: 0px 15px 15px 0px;
}
}
.page-navigation-arrow {
margin: 6px;
width: 24px;
height: 24px;
}

View File

@@ -0,0 +1,18 @@
// Links
.shell-link {
color: $link_color;
&:hover {
color: lighten($link_color, 10%);
}
}
// Outline for low res icons
.lowres-icon {
icon-shadow: 0 1px 2px rgba(black, 0.3);
}
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 5px rgba(black, 0.8);
}

View File

@@ -0,0 +1,5 @@
/* Buttons */
.button {
@extend %button; // that's it
}

View File

@@ -0,0 +1,291 @@
/* Date/Time Menu */
.clock-display-box {
spacing: 2px;
.clock {
padding-left: $base_padding * 2;
padding-right: $base_padding * 2;
}
}
// overall menu
#calendarArea {
padding:0;
}
// Calendar menu side column
.datemenu-calendar-column {
spacing: $base_spacing;
border: 0 solid $bubble_borders_color;
padding: 0 $base_padding * 2;
&:ltr {margin-right: $base_margin * 2; border-left-width: 1px; }
&:rtl {margin-left: $base_margin * 2; border-right-width: 1px; }
.datemenu-displays-section {
}
.datemenu-displays-box {
spacing: $base_spacing;
}
}
.events-section-title {
@include notification_bubble($flat: true);
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
padding: .4em;
}
/* today button (the date) */
.datemenu-today-button {
@include notification_bubble($flat: true);
padding: $base_padding * 1.5;
// weekday label
.day-label {
@include fontsize($base_font_size+1);
font-weight: bold;
}
// date label
.date-label {
@include fontsize($base_font_size+7);
font-weight: 1000;
}
}
/* Calendar */
.calendar {
@include notification_bubble;
padding: $base_padding;
// month
.calendar-month-label {
color: lighten($fg_color,5%);
font-weight: bold;
padding: 8px 0;
&:focus {}
}
// prev/next month icons
.calendar-change-month-back StIcon,
.calendar-change-month-forward StIcon {
icon-size: $base_icon_size;
}
.pager-button {
background-color: transparent;
height: 32px;
width: 32px;
border-radius: $base_border_radius;
&:hover, &:focus { background-color: lighten($hover_bg_color, 5%); }
&:active { background-color: $active_bg_color; }
}
$calendar_day_size: 32px;
.calendar-day-base {
@include fontsize($base_font_size - 3);
text-align: center;
width: $calendar_day_size;
height: $calendar_day_size;
padding: 0;
margin: 2px;
border-radius: $calendar_day_size * 0.5 + 2px;
border: 1px solid transparent; //avoid jumparound due to today
font-feature-settings: "tnum";
&:hover, &:focus { background-color: $hover_bg_color; }
&:active,&:selected {
color: lighten($fg_color,10%);
background-color: darken($bg_color,5%);
}
// day of week heading
&.calendar-day-heading {
color: lighten($fg_color,10%);
margin-top: 1em;
@include fontsize($base_font_size - 4);
}
}
.calendar-day { //border collapse hack - see calendar.js
border-width: 0;
}
.calendar-day-top {
border-top-width: 1px;
}
.calendar-day-left {
border-left-width: 1px;
}
.calendar-work-day {}
.calendar-nonwork-day {
color: $insensitive_fg_color;
}
// Today
.calendar-today {
font-weight: bold;
border: 1px solid transparent;
background-color: $selected_bg_color;
color: $selected_fg_color;
&:hover,&:focus {
background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color;
}
&:active,&:selected {
background-color: $selected_bg_color;
color: $selected_fg_color;
&:hover,&:focus {
background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color;
}
}
}
.calendar-day-with-events {
background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg");
&.calendar-work-day {
color: lighten($fg_color,10%);
font-weight: bold;
}
}
.calendar-other-month-day {
color: transparentize($fg_color ,0.5);
}
.calendar-week-number {
@include fontsize($base_font_size - 4);
font-weight: bold;
height: 1.8em;
width: 2.3em;
border-radius: 2px;
margin: 6px;
background-color: darken($bg_color, 2%);
color: lighten($fg_color, 5%);
}
}
/* Events */
.events-button {
@include notification_bubble;
padding: $base_padding * 2;
.events-box {
spacing: $base_spacing;
}
.events-list {
spacing: 2 * $base_spacing;
}
.events-title {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
margin-bottom: $base_margin;
}
.event-time {
color: darken($fg_color,20%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 1);
}
}
/* World clocks */
.world-clocks-button {
@include notification_bubble;
padding: $base_padding * 2;
.world-clocks-grid {
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
// title
.world-clocks-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
}
// city label
.world-clocks-city {
color: $fg_color;
@include fontsize($base_font_size);
font-weight: normal;
}
// timezone time
.world-clocks-time {
font-weight: bold;
color: $fg_color;
font-feature-settings: "tnum";
@include fontsize($base_font_size);
&:ltr { text-align: right; }
&:rtl { text-align: left; }
}
// timezone offset label
.world-clocks-timezone {
color: darken($fg_color,20%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 1);
}
}
/* Weather */
.weather-button {
@include notification_bubble;
padding: $base_padding * 2;
.weather-box {
spacing: $base_spacing + $base_margin;
}
.weather-header-box {
spacing: $base_spacing;
}
.weather-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
&.location {
font-weight: normal;
@include fontsize($base_font_size - 1);
}
}
.weather-grid {
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
.weather-forecast-time {
color: darken($fg_color,30%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 2);
font-weight: normal;
padding-top: 0.2em;
padding-bottom: 0.4em;
}
.weather-forecast-icon {
icon-size: $base_icon_size * 2;
}
.weather-forecast-temp {
font-weight: bold;
}
}

View File

@@ -0,0 +1,18 @@
/* Check Boxes */
// these are equal to the size of the SVG assets
$check_height: 22px;
$check_width: 24px;
.check-box {
StBoxLayout { spacing: .8em; }
StBin {
width: $check_width;
height: $check_height;
background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg");
}
&:focus StBin { background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); }
&:checked StBin { background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); }
&:focus:checked StBin { background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); }
}

View File

@@ -0,0 +1,15 @@
/* Activities Ripple */
$ripple_size: 50px;
.ripple-box {
background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
// plus + 2px for the border (box-shadow)
width: $ripple_size + 2px;
height: $ripple_size + 2px;
border-radius: 0 0 $ripple_size + 2px 0; // radius equals the size of the box to give us the curve
// just a simple change to the border radius position
&:rtl { border-radius: 0 0 0 $ripple_size + 2px; }
}

View File

@@ -0,0 +1,73 @@
/* Dash */
$dash_background_color: #3b3b3b;
$dash_placeholder_size: 32px;
$dash_padding: $base_padding + 4px; // 10px
$dash_spacing: $base_padding / 4;
$dash_bottom_margin: $base_margin * 4;
$dash_border_radius: $modal_radius * 1.5;
#dash {
@include fontsize($base_font_size - 2);
margin-top: $base_spacing * 3;
padding: 0 $dash_padding;
.placeholder {
// background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
background-image:none;
background-size: contain;
height: $dash_placeholder_size;
}
.empty-dash-drop-target {
width: $dash_placeholder_size;
height: $dash_placeholder_size;
}
.overview-icon {
padding: $dash_padding / 2;
}
}
.dash-background {
background-color: $dash_background_color;
margin-bottom: $dash_bottom_margin;
padding: $dash_padding;
border-radius: $dash_border_radius;
}
// Dash Items
.dash-item-container .app-well-app, .show-apps {
padding: $dash_padding $dash_spacing $dash_padding + $dash_bottom_margin;
}
.dash-separator {
width: 1px;
margin: 0 ($dash_spacing + ($dash_padding / 2)) $dash_bottom_margin;
background-color: transparentize($osd_fg_color,0.7);
}
// OSD Tooltip
.dash-label {
color: $osd_fg_color;
background-color: $osd_bg_color;
border-radius: 99px;
padding: $base_padding $base_padding * 2;
text-align: center;
-y-offset: $base_margin * 3; // distance from the dash edge
}
// Show apps button
.show-apps {
@include overview-icon($osd_fg_color);
&:focus,
&:checked {
.overview-icon {
background-color: transparentize($osd_bg_color,0.5);
color: $fg_color;
}
}
}

View File

@@ -0,0 +1,173 @@
/* Modal Dialogs */
.headline {
@include fontsize($base_font_size + 1);
}
.modal-dialog {
border-radius: $modal_radius;
@extend %bubble_panel;
.modal-dialog-content-box {
margin: 32px 40px;
spacing: 32px;
max-width: 28em;
}
.modal-dialog-linked-button {
@extend %bubble_button;
}
}
/* End Session Dialog */
.end-session-dialog {
width: 30em;
.end-session-dialog-battery-warning,
.dialog-list-title {
color: $warning_color;
}
}
/* Message Dialog */
.message-dialog-content {
spacing: 18px;
.message-dialog-title {
text-align: center;
font-size: 18pt;
font-weight: 800;
&.lightweight {
font-size: 13pt;
font-weight: 800;
}
}
.message-dialog-description { text-align: center; }
}
/* Dialog List */
.dialog-list {
spacing: 18px;
.dialog-list-title {
text-align: center;
font-weight: bold;
}
.dialog-list-scrollview { max-height: 200px; }
.dialog-list-box {
spacing: 1em;
.dialog-list-item {
spacing: 1em;
.dialog-list-item-title { font-weight: bold; }
.dialog-list-item-description {
color: darken($fg_color,5%);
@include fontsize($base_font_size - 1);
}
}
}
}
/* Run Dialog */
.run-dialog {
.modal-dialog-content-box {
margin-top: 24px;
margin-bottom: 14px;
}
.run-dialog-entry { width: 20em; }
.run-dialog-description {
@include fontsize($base_font_size - 1);
text-align: center;
color: darken($fg_color, 20%);
}
}
/* Password or Authentication Dialog */
.prompt-dialog {
width: 28em;
.modal-dialog-content-box {
margin-bottom: 24px;
}
}
.prompt-dialog-password-grid {
spacing-rows: 8px;
spacing-columns: 4px;
.prompt-dialog-password-entry {
width: auto;
// 4px (spacing) + 16px (spinner-width)
&:ltr { margin-left: 20px; }
&:rtl { margin-right: 20px; }
}
}
.prompt-dialog-password-layout {
spacing: 8px;
}
.prompt-dialog-password-entry {
width: 20em;
}
.prompt-dialog-error-label,
.prompt-dialog-info-label,
.prompt-dialog-null-label {
text-align: center;
@include fontsize($base_font_size - 1);
}
.prompt-dialog-error-label {
color: $warning_color;
}
/* Polkit Dialog */
.polkit-dialog-user-layout {
text-align: center;
spacing: 8px;
margin-bottom: 6px;
.polkit-dialog-user-root-label { color: $warning_color; }
}
/* Audio selection dialog */
.audio-device-selection-dialog {
.modal-dialog-content-box { margin-bottom: 28px; }
.audio-selection-box { spacing: 20px; }
}
.audio-selection-device {
border: 1px solid $bubble_borders_color;
border-radius: 12px;
&:hover,&:focus { background-color: $hover_bg_color; }
&:active {
background-color: $selected_bg_color;
color: $selected_fg_color;
}
}
.audio-selection-device-box {
padding: 20px;
spacing: 20px;
}
.audio-selection-device-icon {
icon-size: $base_icon_size * 4;
}
/* Welcome dialog */
.welcome-dialog-image {
background-image: url("resource:///org/gnome/shell/theme/gnome-shell-start.svg");
background-size: contain;
/* Reasonable maximum dimensions */
height: 300px;
width: 300px;
}

View File

@@ -0,0 +1,27 @@
/* Entries */
StEntry {
border-radius: $base_border_radius;
padding: 8px;
border-width: 1px;
color: $fg_color;
@include entry(normal);
//&:hover { @include entry(hover);}
&:focus { @include entry(focus);}
&:insensitive { @include entry(insensitive);}
selection-background-color: $selected_bg_color;
selected-color: $selected_fg_color;
StIcon.capslock-warning {
icon-size: 16px;
warning-color: $warning_color;
padding: 0 4px;
}
StIcon.peek-password {
icon-size: $base_icon_size;
padding: 0 4px;
}
StLabel.hint-text {
margin-left: 2px;
color: transparentize($fg_color, 0.3);
}
}

View File

@@ -0,0 +1,10 @@
// hotplug
.hotplug-notification-item {
@extend %bubble_button;
}
.hotplug-notification-item-icon {
icon-size: 24px;
padding: 0 4px;
}

View File

@@ -0,0 +1,35 @@
// IBus Candidate Popup
.candidate-popup-boxpointer {
@extend .popup-menu-boxpointer;
}
.candidate-popup-content {
padding: 0.5em;
spacing: 0.3em;
}
.candidate-index {
padding: 0 0.5em 0 0;
color: darken($fg_color,10%);
}
.candidate-box {
padding: 0.3em 0.5em 0.3em 0.5em;
border-radius: $base_border_radius;
&:selected,&:hover { background-color: $selected_bg_color; color: $selected_fg_color; }
}
.candidate-page-button-box {
height: 2em;
.vertical & { padding-top: 0.5em; }
.horizontal & { padding-left: 0.5em; }
}
.candidate-page-button {
padding: 4px;
}
.candidate-page-button-previous { border-radius: $base_border_radius 0px 0px $base_border_radius; border-right-width: 0; }
.candidate-page-button-next { border-radius: 0px $base_border_radius $base_border_radius 0px; }
.candidate-page-button-icon { icon-size: 1em; }

View File

@@ -0,0 +1,115 @@
/* On-screen Keyboard */
$key_size: 1.2em;
$key_border_radius: $base_border_radius + 3px;
$key_bg_color: $bg_color;
// $default_key_bg_color: darken($key_bg_color, 4%);
$default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten($osd_bg_color, 2%));
// draw keys using button function
#keyboard {
background-color: transparentize(if($variant=='light', darken($bg_color, 5%), darken($bg_color, 8%)), 0.1);
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color;
.page-indicator {
padding: $base_padding;
.page-indicator-icon {
width: 8px;
height: 8px;
}
}
}
// the container for individual keys
.key-container {
padding: $base_margin;
spacing: $base_margin;
}
// the keys
.keyboard-key {
@include button(normal, $c:$key_bg_color);
&:focus { @include button(focus);}
&:hover, &:checked { @include button(hover, $c: $key_bg_color);}
&:active { @include button(active, $c: $key_bg_color); }
@include fontsize($base_font_size + 5);
min-height: $key_size;
min-width: $key_size;
border-width: 1px;
border-style: solid;
border-radius: $key_border_radius;
&:grayed { //FIXMEy
background-color: darken($bg_color, 3%);
color: $osd_fg_color;
border-color: $osd_borders_color;
}
// non-character keys
&.default-key {
@include button(normal, $c:$default_key_bg_color);
&:hover, &:checked {@include button(hover, $c: $default_key_bg_color);}
&:active { @include button(active, $c: $default_key_bg_color);}
}
// enter key is suggested-action
&.enter-key {
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
&:hover, &:checked { @include button(hover, $c: lighten($selected_bg_color, 3%));}
&:active {@include button(active, $c: darken($selected_bg_color, 2%));}
}
&.shift-key-uppercase { color: $selected_bg_color }
StIcon { icon-size: 1.125em; }
}
// long press on a key popup
.keyboard-subkeys {
color: $osd_fg_color;
-arrow-border-radius: $modal_radius;
-arrow-background-color: $osd_bg_color;
-arrow-border-width: 1px;
-arrow-border-color: lighten($osd_bg_color, 9%);
-arrow-base: 20px;
-arrow-rise: 10px;
-boxpointer-gap: $base_spacing;
.keyboard-key {
@include button(normal, $c:$key_bg_color);
&:focus { @include button(focus);}
&:hover, &:checked { @include button(hover, $c: $key_bg_color);}
&:active { @include button(active, $c: $key_bg_color); }
border-radius:$base_border_radius;
}
}
// emoji
.emoji-page {
.keyboard-key {
background-color: transparent;
border: none;
color: initial;
}
}
.emoji-panel {
.keyboard-key:latched {
border-color: lighten($selected_bg_color, 5%);
background-color: $selected_bg_color;
}
}
// suggestions
.word-suggestions {
@include fontsize($base_font_size + 3);
spacing: 12px;
min-height: 20pt;
}

View File

@@ -0,0 +1,174 @@
/* Login Dialog */
.login-dialog-banner-view {
padding-top: 24px;
max-width: 23em;
}
.login-dialog,
.unlock-dialog {
//reset
border: none;
background-color: transparent;
$_gdm_bg: $system_bg_color;
StEntry {
@if $variant=='dark' {
$_gdm_entry_bg: darken($system_bg_color, 3%);
background-color: $_gdm_entry_bg;
color: $fg_color;
}
}
.modal-dialog-button-box { spacing: 3px; }
.modal-dialog-button {
padding: 4px 18px;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
background-color: darken($system_bg_color, 3%);
border-color: darken($system_bg_color, 3%);
color: $osd_fg_color;
$_hover_c: lighten($_gdm_bg, 5%);
&:hover, &:focus {
background-color: $_hover_c;
border-color: $_hover_c;
}
&:active {
$_active_c: darken($_gdm_bg, 5%);
box-shadow: none;
background-color: $_active_c;
border-color: $_active_c;
}
&:insensitive {
@include button(insensitive);
border-color: darken($_gdm_bg, 5%);
background-color: darken($_gdm_bg, 5%);
color: transparentize($osd_fg_color, 0.3);
}
&:default {
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
border-color: $selected_bg_color;
&:hover, &:focus {
@include button(hover,$c:$selected_bg_color, $tc:$selected_fg_color);
$_def_hover_c: lighten($selected_bg_color, 5%);
background-color: $_def_hover_c;
border-color: $_def_hover_c;
}
&:active {
@include button(active,$c:$selected_bg_color, $tc:$selected_fg_color);
$_def_active_c: darken($selected_bg_color, 5%);
background-color: $_def_active_c;
border-color: $_def_active_c;
}
&:insensitive {
@include button(insensitive);
border-color: darken($selected_bg_color, 10%);
background-color: darken($selected_bg_color, 10%);
color: transparentize($selected_fg_color, 0.3);
}
}
}
.cancel-button,
.switch-user-button,
.login-dialog-session-list-button {
padding: 0;
border-radius: 99px;
width: $base_icon_size * 2;
height: $base_icon_size * 2;
border-color: darken($system_bg_color, 3%);
background-color: darken($system_bg_color, 3%);
StIcon { icon-size: $base_icon_size; }
}
.caps-lock-warning-label,
.login-dialog-message-warning {
color: $osd_fg_color;
}
}
.login-dialog-logo-bin { padding: 24px 0px; }
.login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { width: 23em; spacing: 5px; }
.login-dialog-message { text-align: center; }
.login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label {
padding-left: 2px;
.login-dialog-not-listed-button:focus &,
.login-dialog-not-listed-button:hover & {
color: $osd_fg_color;
}
}
.login-dialog-not-listed-label {
@include fontsize($base_font_size - 1);
font-weight: bold;
color: darken($osd_fg_color,30%);
padding-top: 1em;
}
.login-dialog-user-list-view { -st-vfade-offset: 1em; }
.login-dialog-user-list {
spacing: 12px;
width: 23em;
&:expanded .login-dialog-user-list-item:selected { background-color: $selected_bg_color; color: $selected_fg_color; }
&:expanded .login-dialog-user-list-item:logged-in { border-right: 2px solid $selected_bg_color; }
}
.login-dialog-user-list-item {
border-radius: $base_border_radius + 4px;
padding: 6px;
color: darken($osd_fg_color,30%);
&:ltr .user-widget { padding-right: 1em; }
&:rtl .user-widget { padding-left: 1em; }
.login-dialog-timed-login-indicator {
height: 2px;
margin-top: 6px;
background-color: $osd_fg_color;
}
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
}
.user-widget-label {
color: $osd_fg_color;
}
.user-widget.horizontal .user-widget-label {
@include fontsize($base_font_size + 2);
font-weight: bold;
padding-left: 15px;
&:ltr { padding-left: 14px; text-align: left; }
&:rtl { padding-right: 14px; text-align: right; }
}
.user-widget.vertical .user-widget-label {
@include fontsize($base_font_size + 5);
text-align: center;
font-weight: normal;
padding-top: 16px;
}
.login-dialog-timed-login-indicator {
height: 2px;
background-color: darken($fg_color,40%);
}
.login-dialog-prompt-layout {
padding-top: 24px;
padding-bottom: 12px;
spacing: $base_spacing * 2;
width: 23em;
}
.login-dialog-prompt-entry {
height: 1.5em;
}
.login-dialog-prompt-label {
color: darken($osd_fg_color, 20%);
@include fontsize($base_font_size + 1);
padding-top: 1em;
}

View File

@@ -0,0 +1,109 @@
/* Looking Glass */
$text_fg_color: #ccc;
// Dialog
#LookingGlassDialog {
background-color: $osd_bg_color;
spacing: $base_spacing;
padding: 4px;
border: 1px solid transparentize($osd_fg_color, 0.8);
border-radius: $base_border_radius;
color: $osd_fg_color;
& > #Toolbar {
border: none;
border-radius: $base_border_radius;
background-color: $osd_bg_color;
}
.labels { spacing: $base_spacing; }
.notebook-tab {
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: 6px;
font-weight: bold;
color: darken($osd_fg_color, 15%);
transition-duration: 100ms;
padding-left: .3em;
padding-right: .3em;
border-bottom-width: 2px;
&:hover {
color: $osd_fg_color;
}
&:selected {
border-bottom-width: 2px;
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color, 5%);
color: $osd_fg_color;
}
}
StBoxLayout#EvalBox { padding: 4px; spacing: $base_spacing; }
StBoxLayout#ResultsArea { spacing: $base_spacing; }
}
.lg-dialog {
StEntry {
background-color: transparentize(lighten($osd_bg_color, 5%), 0.4);
color: $osd_fg_color;
border-color: transparentize($osd_fg_color, 0.8);
min-height: 22px;
selection-background-color: $selected_bg_color;
selected-color: $selected_fg_color;
}
.shell-link {
color: $link_color;
&:hover { color: lighten($link_color, 10%); }
&:active { color: darken($link_color, 10%); }
}
.actor-link {
color: $text_fg_color;
&:hover { color: lighten($text_fg_color, 20%); }
&:active { color: darken($text_fg_color, 20%); }
}
}
.lg-completions-text {
font-size: .9em;
font-style: italic;
}
.lg-obj-inspector-title {
spacing: $base_spacing;
}
.lg-obj-inspector-button {
border: 1px solid $osd_borders_color;
padding: 4px;
border-radius: $base_border_radius;
&:hover { border: 1px solid #ffffff; }
}
// Extensions
#lookingGlassExtensions { padding: 4px; }
.lg-extensions-list {
padding: 4px;
spacing: 6px;
}
.lg-extension {
border: 1px solid lighten($osd_borders_color, 5%);
background-color: lighten($osd_bg_color, 5%);
border-radius: $base_border_radius;
padding: 4px;
}
.lg-extension-name {
font-weight: bold;
}
.lg-extension-meta {
spacing: 6px;
}
// Inspector
#LookingGlassPropertyInspector {
background: $osd_bg_color;
border: 1px solid $osd_borders_color;
border-radius: $base_border_radius;
padding: 6px;
}

View File

@@ -0,0 +1,136 @@
/* Message List */
// a.k.a. notifications in the menu
// main list
.message-list {
width: 31.5em;
padding: 0 $base_padding * 2;
.message-list-placeholder { spacing: 12px; }
}
.message-list-sections {
spacing: $base_spacing;
margin: 0 $base_margin * 4; // to account for scrollbar
}
.message-list-section,
.message-list-section-list {
spacing: $base_spacing;
}
// do-not-disturb + clear button
.message-list-controls {
margin: ($base_margin * 2) ($base_margin * 4) 0;
// NOTE: remove the padding if notification_bubble could remove margin for drop shadow
padding: $base_margin;
spacing: $base_spacing * 2;
}
// message bubbles
.message {
@include notification_bubble;
// icon container
.message-icon-bin {
padding: ($base_padding * 3) 0 ($base_padding * 3) ($base_padding * 2);
&:rtl {
padding: ($base_padding * 3) ($base_padding * 2) ($base_padding * 3) 0;
}
// icon size and color
> StIcon {
icon-size: $base_icon_size*2; // 32px
-st-icon-style: symbolic;
}
// fallback
> .fallback-app-icon {
width: $base_icon_size;
height: $base_icon_size;
}
}
// content
.message-content {
padding: $base_padding + $base_margin * 2;
spacing: 4px;
}
// title
.message-title {
font-weight: bold;
}
// secondary container in title box
.message-secondary-bin {
padding: 0 $base_margin * 2;
// notification time stamp
> .event-time {
color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2);
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: 0.13em;
&:ltr { text-align: right };
&:rtl { text-align: left };
}
}
// close button
.message-close-button {
color: lighten($fg_color, 15%);
&:hover { color: if($variant=='light', lighten($fg_color, 30%), darken($fg_color, 10%)); }
&:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); }
}
// body
.message-body {
color: darken($fg_color, 10%);
}
}
// URLs in messages
.url-highlighter {
link-color: $link_color;
}
/* Media Controls */
.message-media-control {
padding: $base_padding * 2 1.64em; // $base_padding * 4 = 24px
color: darken($fg_color, 15%);
// uses $hover_bg_color since the media controls are in a notification_bubble
&:hover {
background-color: lighten($hover_bg_color, 5%);
color: $fg_color;
}
&:active {
background-color: darken($hover_bg_color, 2%);
color: $fg_color;
}
&:insensitive { color: darken($fg_color,40%); }
// fix border-radius for last button
&:last-child:ltr { border-radius: 0 $base_border_radius+2 $base_border_radius+2 0; }
&:last-child:rtl { border-radius: $base_border_radius+2 0 0 $base_border_radius+2; }
}
// album-art
.media-message-cover-icon {
icon-size: $base_icon_size*2 !important; // 48px
border-radius: $base_border_radius;
// when there is no artwork
&.fallback {
color: darken($fg_color, 17%);
background-color: $bg_color;
border: 1px solid transparent;
border-radius: $base_border_radius;
icon-size: $base_icon_size * 2 !important;
}
}

View File

@@ -0,0 +1,59 @@
// Rubberband for select-area screenshots
.select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color;
}
// User icon
.user-icon {
background-size: contain;
color: $osd_fg_color;
border-radius: 99px;
icon-size: $base_icon_size * 4; // 64px
&:hover {
color: lighten($osd_fg_color,30%);
}
& StIcon {
background-color: transparentize($osd_fg_color,0.95);
border-radius: 99px;
padding: $base_padding * 2 ; // 12px
width: $base_icon_size * 2.5; height: $base_icon_size * 2.5; // 40px;
}
&.user-avatar {
border: 2px $osd_fg_color;
}
}
.user-widget.vertical .user-icon {
icon-size: $base_icon_size * 6; // 128px
& StIcon {
padding: $base_padding * 3 + 2px; // 20px
padding-top: $base_padding * 3; // 18 px
padding-bottom: $base_padding * 3 + 4px; // 22px
width: $base_icon_size * 5.5; height: $base_icon_size * 5.5; // 88px;
}
}
.lightbox { background-color: black; }
.flashspot { background-color: white; }
// Hidden
.hidden { color: rgba(0,0,0,0);}
// Caps-lock warning
.caps-lock-warning-label {
text-align: center;
padding-bottom: 8px;
@include fontsize($base_font_size - 1);
color: $warning_color;
}
/* Workspace animation */
.workspace-animation {
background-color: $system_bg_color;
}

View File

@@ -0,0 +1,56 @@
/* Network Dialogs */
.nm-dialog {
max-height: 34em;
min-height: 31em;
min-width: 32em;
}
.nm-dialog-content {
spacing: 20px;
padding: 24px;
}
.nm-dialog-airplane-box { spacing: 12px; }
.nm-dialog-airplane-headline {
font-weight: bold;
text-align: center;
}
.nm-dialog-airplane-text { color: $fg_color; }
// header
.nm-dialog-header {
font-weight: bold;
}
.nm-dialog-header-icon {
icon-size: $base_icon_size * 2;
}
.nm-dialog-header-hbox { spacing: 10px; }
// list of networks
.nm-dialog-scroll-view {
border: 1px solid $borders_color;
padding:0;
background-color: darken($bg_color, 3%);
}
// list item
.nm-dialog-item {
@include fontsize($base_font_size);
border-bottom: 1px solid $borders_color;
padding: $base_padding * 2;
spacing: 0px;
&:selected {
background-color: $selected_bg_color;
color: $selected_fg_color;
}
}
// icons in list
.nm-dialog-icon { icon-size: $base_icon_size; }
.nm-dialog-icons { spacing: $base_spacing * 2; }
// no networks
.no-networks-label { color: $insensitive_fg_color; }
.no-networks-box { spacing: $base_padding; }

View File

@@ -0,0 +1,57 @@
/* Notifications & Message Tray */
$notification_banner_height: 64px;
$notification_banner_width: 34em;
// Banner notifications
.notification-banner {
min-height: $notification_banner_height;
width: $notification_banner_width;
.notification-actions {
spacing: 0;
}
.notification-button {
@extend %bubble_button;
}
}
// counter
.summary-source-counter {
font-size: $base_font_size - 1pt;
font-weight: bold;
height: 1.6em;
width: 1.6em;
-shell-counter-overlap-x: 3px;
-shell-counter-overlap-y: 3px;
background-color: $selected_bg_color;
color: $selected_fg_color;
border: 2px solid $fg_color;
box-shadow: 0 2px 2px rgba(0,0,0,0.5);
border-radius: 0.9em; // should be 0.8 but whatever; wish I could do 50%;
}
// chat bubbles
.chat-body { spacing: 5px; }
.chat-response { margin: 5px; }
.chat-log-message { color: darken($fg_color,10%); }
.chat-new-group { padding-top: 1em; }
.chat-received {
padding-left: 4px;
&:rtl { padding-left: 0px; padding-right: 4px; }
}
.chat-sent {
padding-left: 18pt;
color: lighten($fg_color, 15%);
&:rtl { padding-left: 0; padding-right: 18pt; }
}
.chat-meta-message {
padding-left: 4px;
@include fontsize($base_font_size - 2);
font-weight: bold;
color: lighten($fg_color,18%);
&:rtl { padding-left: 0; padding-right: 4px; }
}

View File

@@ -0,0 +1,45 @@
/* OSD */
$osd_levelbar_height:8px;
.osd-window {
@extend %osd_panel;
text-align: center;
font-weight: bold;
spacing: $base_spacing * 2; // 12px
margin: $base_margin * 8; // 32px
min-width: 64px;
min-height: 64px;
StIcon {
icon-size:$base_icon_size * 6;
}
.osd-monitor-label { font-size: 3em; }
.level {
height: $osd_levelbar_height;
-barlevel-height: $osd_levelbar_height;
-barlevel-background-color: transparentize($osd_fg_color, if($variant=='light', 0.7, 0.9));
-barlevel-active-background-color: $osd_fg_color;
-barlevel-overdrive-color: $destructive_color;
-barlevel-overdrive-separator-width: 3px;
}
}
/* Pad OSD */
.pad-osd-window {
padding: 32px;
background-color: transparentize(#000, 0.2);
.pad-osd-title-box { spacing: 12px; }
.pad-osd-title-menu-box { spacing: 6px; }
}
.combo-box-label {
width: 15em;
}
.resize-popup {
@extend %osd_panel;
}

View File

@@ -0,0 +1,13 @@
/* OVERVIEW */
.controls-manager, .secondary-monitor-workspaces {
spacing: $base_spacing * 2;
}
#overviewGroup {
background-color: $system_bg_color;
}
.overview-controls {
padding-bottom: 32px;
}

View File

@@ -0,0 +1,135 @@
/* Top Bar */
// a.k.a. the panel
$panel_corner_radius: $base_border_radius+1;
$panel_bg_color: #000;
$panel_fg_color: #ddd;
$panel_height: 2.2em;
$panel_transition_duration: 250ms; // same as the overview transition duration
#panel {
background-color: $panel_bg_color;
font-weight: bold;
height: $panel_height;
font-feature-settings: "tnum";
transition-duration: $panel_transition_duration;
// transparent panel on lock & login screens
&.unlock-screen,
&.login-screen,
&:overview {
background-color: transparent;
.panel-corner {
-panel-corner-opacity: 0;
}
}
// the rounded outset corners
.panel-corner {
-panel-corner-radius: $panel_corner_radius;
-panel-corner-background-color: $panel_bg_color;
-panel-corner-border-width: 2px;
-panel-corner-border-color: transparent;
-panel-corner-opacity: 1;
transition-duration: $panel_transition_duration;
}
// panel menus
.panel-button {
font-weight: bold;
color: $panel_fg_color;
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: $base_padding;
transition-duration: 150ms;
border: 3px solid transparent;
border-radius: 99px;
&.clock-display {
.clock {
transition-duration: 150ms;
border: 3px solid transparent;
border-radius: 99px;
}
}
&:hover, &:active, &:overview, &:focus, &:checked {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.20);
// The clock display needs to have the background on .clock because
// we want to exclude the do-not-disturb indicator from the background
&.clock-display {
box-shadow: none;
.clock {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.20);
}
}
}
// status area icons
.system-status-icon {
icon-size: $base_icon_size;
padding: $base_padding - 1px;
margin: 0 $base_margin;
}
.panel-status-indicators-box .system-status-icon,
.panel-status-menu-box .system-status-icon {
margin: 0;
}
// app menu icon
.app-menu-icon {
-st-icon-style: symbolic;
// dimensions of the icon are hardcoded
}
&#panelActivities {
-natural-hpadding: $base_padding * 3;
}
}
&.unlock-screen,
&.login-screen,
&:overview {
.panel-button {
&:hover, &:active, &:overview, &:focus, &:checked {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15);
&.clock-display {
box-shadow: none;
.clock {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15);
}
}
}
}
}
.panel-status-indicators-box,
.panel-status-menu-box {
spacing: 2px;
}
// spacing between power icon and (optional) percentage label
.power-status.panel-status-indicators-box {
spacing: 0;
}
// indicator for active
.screencast-indicator,
.remote-access-indicator { color: $warning_color; }
}
// App Menu
#appMenu {
spacing: $base_spacing;
.label-shadow { color: transparent; }
}
#appMenu .panel-status-menu-box {
padding: 0 $base_padding;
spacing: $base_spacing;
}

View File

@@ -0,0 +1,131 @@
/* Popovers/Menus */
$popover_arrow_height: 12px;
//.the popover itself
.popup-menu-boxpointer {
-arrow-border-radius: $base_border_radius+4;
-arrow-background-color: $bg_color;
-arrow-border-width: 1px;
-arrow-border-color: $borders_color;
-arrow-base: $popover_arrow_height * 2;
-arrow-rise: $popover_arrow_height;
-arrow-box-shadow: 0 1px 3px rgba(0,0,0,0.5); // dreaming bugzilla #689995
}
// container of the popover menu
.popup-menu {
min-width: 15em;
color: $fg_color;
//.popup-status-menu-item { font-weight: normal; color: pink; } //dunno what that is
&.panel-menu {
-boxpointer-gap: $base_margin; // distance from the panel
margin-bottom: 1.75em;
}
}
.popup-menu-content {
padding: $base_padding * 2 + $base_margin 0;
}
// menu items
.popup-menu-item {
spacing: $base_padding;
padding: $base_padding;
&:ltr { padding-right:1.75em; padding-left: 0; }
&:rtl { padding-right: 0; padding-left:1.75em; }
&:checked {
background-color: lighten($bg_color, 2%);
box-shadow: none;
}
&.selected {
background-color: transparentize(white, if($variant=='light', 0.2, 0.9));
color: $fg_color;
}
&:active {
background-color: $selected_bg_color;
color: $selected_fg_color;
}
&:insensitive { color: transparentize($fg_color,0.5);}
}
// all icons and other graphical elements
.popup-inactive-menu-item {
color: $fg_color;
&:insensitive { color: transparentize($fg_color,0.5); }
}
// symbolic icons in popover
.popup-menu-arrow,
.popup-menu-icon { icon-size: $base_icon_size; }
// popover submenus
.popup-sub-menu {
background-color: darken($bg_color, 3%);
box-shadow: none;
border-top: 1px solid transparentize($borders_color, 0.2);
border-bottom: 1px solid transparentize($borders_color, 0.2);
}
// container for radio and check boxes
.popup-menu-ornament {
width: 1.2em;
&:ltr { text-align: right };
&:rtl { text-align: left };
}
// separator
.popup-separator-menu-item {
padding: 0;
.popup-separator-menu-item-separator {
//-margin-horizontal: 24px;
height: 1px; //not really the whole box
margin: 6px 64px;
background-color: lighten($borders_color, 2%);
.popup-sub-menu & { //submenu separators
margin: 0 64px 0 32px;
@if $variant == 'dark' {
background-color: lighten($bg_color,10%);
}
}
}
}
// desktop background menu
.background-menu {
-boxpointer-gap: $base_margin;
-arrow-rise: 0px; // hide the beak on the menu
}
// system status menu
.aggregate-menu {
min-width: 21em;
// lock screen, shutdown, etc. buttons
.popup-menu-icon {
padding:0;
margin: 0 $base_margin;
-st-icon-style: symbolic;
}
.popup-sub-menu .popup-menu-item > :first-child {
// account for icons in submenus with padding
&:ltr {
padding-left: $base_padding + $base_margin * 2;
margin-left: $base_icon_size;
}
&:rtl {
padding-right: $base_padding + $base_margin * 2; ;
margin-right: $base_icon_size;
}
}
}

View File

@@ -0,0 +1,78 @@
/* Screen Shield */
.unlock-dialog-clock {
color: white;
font-weight: 300;
text-align: center;
spacing: 24px;
padding-bottom: 2.5em;
}
.unlock-dialog-clock-time {
font-size: 64pt;
padding-top: 42px;
font-feature-settings: "tnum";
}
.unlock-dialog-clock-date {
font-size: 16pt;
font-weight: normal;
}
.unlock-dialog-clock-hint {
font-weight: normal;
padding-top: 48px;
}
.unlock-dialog-notifications-container {
margin: 12px 0;
spacing: 6px;
width: 23em;
background-color: transparent;
.summary-notification-stack-scrollview {
padding-top: 0;
padding-bottom: 0;
}
.notification,
.unlock-dialog-notification-source {
padding: 12px 6px;
border: none;
background-color: transparentize($osd_bg_color,0.7);
color: $osd_fg_color;
border-radius: $modal_radius;
&.critical { background-color: transparentize($osd_bg_color,0.1) }
}
}
.unlock-dialog-notification-label {
padding: 0px 0px 0px 12px;
}
.unlock-dialog-notification-count-text {
weight: bold;
padding: 0 6px;
color: $osd_bg_color;
background-color: transparentize($osd_fg_color, 0.7);
border-radius: 99px;
margin-right: 12px;
}
.screen-shield-background { //just the shadow, really
background: black;
box-shadow: 0px 2px 4px rgba(0,0,0,0.6);
}
#lockDialogGroup {
background-color: $system_bg_color;
}
#unlockDialogNotifications {
StButton#vhandle, StButton#hhandle {
background-color: transparentize($bg_color,0.7);
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
&:active { background-color: transparentize($selected_bg_color,0.5); }
}
}

View File

@@ -0,0 +1,29 @@
/* Scrollbars */
StScrollView {
&.vfade { -st-vfade-offset: 68px; }
&.hfade { -st-hfade-offset: 68px; }
}
StScrollBar {
padding: 0;
StScrollView & {
min-width: 14px;
min-height: 14px;
}
StBin#trough {
border-radius: 0;
background-color: transparent;
}
StButton#vhandle, StButton#hhandle {
border-radius: 8px;
background-color: mix($fg_color, $bg_color, 60%);
//border: 3px solid transparent; //would be nice to margin or at least to transparent
margin: 3px;
&:hover { background-color: mix($fg_color, $bg_color, 80%); }
&:active { background-color: $selected_bg_color; }
}
}

View File

@@ -0,0 +1,37 @@
// Search entry
$search_entry_width: 320px;
$search_entry_height: 36px;
%search_entry,
.search-entry {
width: $search_entry_width;
padding: $base_padding+1 $base_padding+3;
border-radius: $search_entry_height * 0.5; // half the height
color: transparentize($fg_color,0.3);
background-color: $bg_color;
border-color: $borders_color;
margin-top: $base_spacing * 2;
margin-bottom: $base_spacing;
&:hover {
background-color: $hover_bg_color;
border-color: $hover_borders_color;
color: $hover_fg_color;
}
&:focus {
padding: $base_padding $base_padding+2; // 1px less to account for wider border
border-width: 2px;
border-style: solid;
border-color: $selected_bg_color;
color: $fg_color;
box-shadow: inset 0 1px 2px 1px rgba(0,0,0,0.2);
}
.search-entry-icon {
icon-size: $base_icon_size;
padding: 0 4px;
color: inherit;
}
}

View File

@@ -0,0 +1,108 @@
/* Search */
// search overview container
#searchResultsContent {
max-width: 1024px;
spacing: $base_margin * 2;
}
// search results sections "the boxes"
.search-section {
// This should be equal to #searchResultsContent spacing
spacing: $base_margin * 2;
// separator
.search-section-separator {
// height: 1px;
// background-color: $osd_outer_borders_color;
height: 0;
background-color: transparent;
}
}
// content
.search-section-content {
background-color: transparentize(lighten($osd_bg_color, 5%), 0.2);
border-radius: $modal_radius+3;
border: 1px solid $osd_outer_borders_color;
box-shadow: 0 2px 4px 0 $shadow_color;
text-shadow: 0 1px if($variant == 'light', rgba(255,255,255,0.2), rgba(0,0,0,0.2));
color: $osd_fg_color;
padding: $base_padding * 3;
// This is the space between the provider icon and the results container
spacing: $base_margin * 2;
}
%search-section-content-item {
@extend %icon_tile;
&:focus,
&:hover,
&:selected {
background-color: transparentize($osd_fg_color, .9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color, 10%), .1);
}
}
// "no results" text
.search-statustext {
@extend %status_text;
}
.grid-search-results {
spacing: $base_spacing * 6;
}
// Search results with icons
.grid-search-result {
@extend %app-well-app;
}
// search result provider
.search-provider-icon {
@extend %search-section-content-item;
// content
.list-search-provider-content {
spacing: $base_spacing * 2;
// provider labels
.list-search-provider-details {
width: 120px;
margin-top: 0;
color: darken($osd_fg_color, 8%);
// font-weight: bold;
}
}
}
// search results list
.list-search-results {
spacing: $base_spacing;
}
// search result listitem
.list-search-result {
@extend %search-section-content-item;
// content
.list-search-result-content {
spacing: $base_padding;
}
// list item title (with leading icon)
.list-search-result-title {
spacing: $base_spacing * 2;
// font-weight: bold;
}
// list item description
.list-search-result-description {
color: darken($osd_fg_color, 30%);
}
}

View File

@@ -0,0 +1,27 @@
/* Slider */
$slider_size: 15px;
.slider {
height: $slider_size;
// slider trough
-barlevel-height: 3px; // has to be an odd number
-barlevel-background-color: $borders_color; //background of the trough
-barlevel-border-width: 1px;
-barlevel-border-color: $borders_color; // trough border color
// fill style
-barlevel-active-background-color: $selected_bg_color; //active trough fill
-barlevel-active-border-color: if($variant == 'light', darken($selected_bg_color, 4%), lighten($selected_bg_color, 2%)); //active trough border
// overfill style (red in this case)
-barlevel-overdrive-color: $destructive_color;
-barlevel-overdrive-border-color: if($variant == 'light', darken($destructive_color, 4%), lighten($destructive_color, 2%)); //trough border when red;
-barlevel-overdrive-separator-width:1px;
// slider handler
-slider-handle-radius: $slider_size * 0.5; // half the size of the size
-slider-handle-border-width: 1px;
-slider-handle-border-color: if($variant == 'light', $borders_color, $fg_color);
color: if($variant == 'light', lighten($bg_color, 10%), $fg_color);
&:hover { color: $hover_bg_color; }
&:active { color: $active_bg_color; }
}

View File

@@ -0,0 +1,65 @@
/* App Switcher */
.switcher-popup {
padding: 8px;
spacing: $base_spacing * 4;
}
// switcher onscreen panel
.switcher-list {
@extend %osd_panel;
.item-box {
padding: 8px;
border-radius: $base_border_radius + 1px;
border: 1px solid transparent;
&:outlined {
background-color: transparentize($osd_fg_color, 0.7);
}
&:selected {
background-color: transparentize($osd_fg_color, 0.7);
color: $osd_fg_color;
}
}
// window thumbnails
.thumbnail-box {
padding: 2px;
spacing: $base_spacing;
}
.thumbnail {
width: 256px;
}
.separator {
width: 1px;
background: $borders_color;
}
.switcher-list-item-container {
spacing: $base_spacing * 2;
}
}
.switcher-arrow {
border-color: rgba(0,0,0,0);
color: transparentize($fg_color,0.2);
&:highlighted {
color: $fg_color;
}
}
// Input Source Switcher
.input-source-switcher-symbol {
font-size: 34pt;
width: 96px;
height: 96px;
}
// Window cycler highlight
.cycler-highlight {
border: 5px solid $selected_bg_color;
}

View File

@@ -0,0 +1,16 @@
/* Switches */
// these are equal to the size of the SVG assets
$switch_height: 22px;
$switch_width: 46px;
.toggle-switch {
color: $fg_color;
height: $switch_height;
width: $switch_width;
background-size: contain;
background-image: if($variant == 'light', url("resource:///org/gnome/shell/theme/toggle-off.svg"),url("resource:///org/gnome/shell/theme/toggle-off-dark.svg"));
&:checked {
background-image: if($variant == 'light', url("resource:///org/gnome/shell/theme/toggle-on.svg"),url("resource:///org/gnome/shell/theme/toggle-on-dark.svg"));
}
}

View File

@@ -0,0 +1,19 @@
/* Tiled window previews */
$tile_corner_radius: $base_border_radius + 1px;
.tile-preview {
background-color: transparentize($selected_bg_color,0.5);
border: 1px solid $selected_bg_color;
}
.tile-preview-left.on-primary {
border-radius: $tile_corner_radius 0 0 0;
}
.tile-preview-right.on-primary {
border-radius: 0 $tile_corner_radius 0 0;
}
.tile-preview-left.tile-preview-right.on-primary {
border-radius: $tile_corner_radius $tile_corner_radius 0 0;
}

View File

@@ -0,0 +1,53 @@
/* Window Picker */
$window_picker_spacing: $base_spacing; // 6px
$window_picker_padding: $base_padding * 2; // 12px
$window_thumbnail_label_color: transparentize($osd_bg_color, 0.4);
$window_close_button_size: 30px;
$window_close_button_padding: 3px;
// Window picker
.window-picker {
// Space between window thumbnails
spacing: $window_picker_spacing;
}
// Window titles
.window-caption {
color: $osd_fg_color;
background-color: $osd_bg_color;
border-radius: 99px;
padding: $base_padding $base_padding * 2;
}
// Close button
.window-close {
background-color: $osd_bg_color;
color: $osd_fg_color;
border-radius: $window_close_button_size * 0.5 + $window_close_button_padding * 2;
padding: $window_close_button_padding;
height: $window_close_button_size;
width: $window_close_button_size;
box-shadow: -1px 1px 5px 0px rgba(0,0,0,0.5);
transition-duration: 300ms;
& StIcon { icon-size: 24px; }
&:hover {
background-color: lighten($osd_bg_color, 15%);
}
&:active {
color: transparentize($osd_fg_color, 0.2);
background-color: darken($osd_bg_color, 5%);
}
}
.workspace-background {
// keep in sync with BACKGROUND_CORNER_RADIUS_PIXELS in workspace.js
border-radius: 30px;
background-color: $osd_bg_color;
box-shadow: 0 4px 16px 4px transparentize(darken($osd_bg_color, 30%), 0.7);
}

View File

@@ -0,0 +1,36 @@
/* Workspace Switcher */
.workspace-switcher-group {
padding: $base_padding * 2;
}
.workspace-switcher-container {
@extend %osd_panel;
}
.workspace-switcher {
background: transparent;
border: none;
border-radius: 0;
padding: 0;
spacing: $base_spacing * 2;
}
.ws-switcher-box {
background: transparent;
height: 50px;
background-size: 32px;
border: 1px solid transparentize($osd_fg_color,0.9);
border-radius: $base_border_radius + 3px;
}
// active workspace in the switcher
.ws-switcher-active-up,
.ws-switcher-active-down,
.ws-switcher-active-left,
.ws-switcher-active-right {
height: 52px;
background-color: $selected_bg_color;
border: 1px solid if($variant=='light', darken($selected_bg_color, 8%), lighten($selected_bg_color, 5%));
border-radius: $base_border_radius + 3px;
color: $selected_fg_color;
}

View File

@@ -0,0 +1,28 @@
/* Workspace pager */
// thumbnails in overview
.workspace-thumbnails {
visible-width: 32px; //amount visible before hover
spacing: $base_spacing;
padding: $base_padding;
.workspace-thumbnail {
@extend %overview_panel;
border-radius: 3px;
}
// drag and drop indicator
.placeholder {
background-image: url("resource:///org/gnome/shell/theme/workspace-placeholder.svg");
background-size: contain;
width: 18px;
}
}
// selected indicator
.workspace-thumbnail-indicator {
border: 3px solid $selected_bg_color;
border-radius: 3px;
padding: 0px;
// background-color: transparentize($selected_bg_color, 0.9);
}

View File

@@ -1,18 +1,12 @@
sessions = [
['gnome-classic.session.desktop.in', sessiondir],
['gnome-classic.desktop.in', xsessiondir]
]
foreach s : sessions
name_array = s[0].split('.')
i18n.merge_file('',
input: s[0],
output: '.'.join([name_array[0], name_array[1]]),
po_dir: '../po',
install: true,
install_dir: s[1],
type: 'desktop'
)
endforeach
session_desktop = 'gnome-classic.desktop'
i18n.merge_file('',
input: session_desktop + '.in',
output: session_desktop,
po_dir: '../po',
install: true,
install_dir: xsessiondir,
type: 'desktop'
)
classic_uuids = []
foreach e : classic_extensions
@@ -34,7 +28,42 @@ theme_sources = files(
'gnome-shell-sass/_colors.scss',
'gnome-shell-sass/_common.scss',
'gnome-shell-sass/_drawing.scss',
'gnome-shell-sass/_high-contrast-colors.scss'
'gnome-shell-sass/_high-contrast-colors.scss',
'gnome-shell-sass/_widgets.scss',
'gnome-shell-sass/widgets/_a11y.scss',
'gnome-shell-sass/widgets/_app-grid.scss',
'gnome-shell-sass/widgets/_base.scss',
'gnome-shell-sass/widgets/_buttons.scss',
'gnome-shell-sass/widgets/_calendar.scss',
'gnome-shell-sass/widgets/_check-box.scss',
'gnome-shell-sass/widgets/_corner-ripple.scss',
'gnome-shell-sass/widgets/_dash.scss',
'gnome-shell-sass/widgets/_dialogs.scss',
'gnome-shell-sass/widgets/_entries.scss',
'gnome-shell-sass/widgets/_hotplug.scss',
'gnome-shell-sass/widgets/_ibus-popup.scss',
'gnome-shell-sass/widgets/_keyboard.scss',
'gnome-shell-sass/widgets/_login-dialog.scss',
'gnome-shell-sass/widgets/_looking-glass.scss',
'gnome-shell-sass/widgets/_message-list.scss',
'gnome-shell-sass/widgets/_misc.scss',
'gnome-shell-sass/widgets/_network-dialog.scss',
'gnome-shell-sass/widgets/_notifications.scss',
'gnome-shell-sass/widgets/_osd.scss',
'gnome-shell-sass/widgets/_overview.scss',
'gnome-shell-sass/widgets/_panel.scss',
'gnome-shell-sass/widgets/_popovers.scss',
'gnome-shell-sass/widgets/_screen-shield.scss',
'gnome-shell-sass/widgets/_scrollbars.scss',
'gnome-shell-sass/widgets/_search-entry.scss',
'gnome-shell-sass/widgets/_search-results.scss',
'gnome-shell-sass/widgets/_slider.scss',
'gnome-shell-sass/widgets/_switcher-popup.scss',
'gnome-shell-sass/widgets/_switches.scss',
'gnome-shell-sass/widgets/_tiled-previews.scss',
'gnome-shell-sass/widgets/_window-picker.scss',
'gnome-shell-sass/widgets/_workspace-switcher.scss',
'gnome-shell-sass/widgets/_workspace-thumbnails.scss'
)
theme_data = [
@@ -47,15 +76,20 @@ theme_data = [
'gnome-classic-high-contrast.css'
]
style = 'gnome-classic'
custom_target(style + '.css',
input: style + '.scss',
output: style + '.css',
depend_files: theme_sources,
command: [sassc, '-a', '@INPUT@', '@OUTPUT@'],
install: true,
install_dir: themedir
)
stylesheet = 'gnome-classic.css'
if fs.exists(stylesheet)
install_data(stylesheet, install_dir: themedir)
else
sassc = find_program('sassc', required: true)
custom_target(stylesheet,
input: fs.replace_suffix(stylesheet, '.scss'),
output: stylesheet,
depend_files: theme_sources,
command: [sassc, '-a', '@INPUT@', '@OUTPUT@'],
install: true,
install_dir: themedir
)
endif
install_data(theme_data, install_dir: themedir)

View File

@@ -21,16 +21,23 @@ for f in $extensiondir/*; do
uuid=$name@gnome-shell-extensions.gcampax.github.com
schema=$schemadir/org.gnome.shell.extensions.$name.gschema.xml
cp $srcdir/NEWS $srcdir/COPYING $f
cp -r $localedir $f
xgettext --from-code=UTF-8 --output-dir=$builddir --output=$name.pot $f/*.js
if [ -f $schema ]; then
mkdir $f/schemas
cp $schema $f/schemas;
glib-compile-schemas $f/schemas
if [ -f $builddir/$name.pot ]; then
mkdir $f/po
for l in $(<$srcdir/po/LINGUAS); do
msgmerge --quiet --output-file=$f/po/$l.po \
$srcdir/po/$l.po $builddir/$name.pot
done
fi
(cd $f && zip -rmq $srcdir/zip-files/$uuid.shell-extension.zip .)
cp $srcdir/NEWS $srcdir/COPYING $f
sources=(NEWS COPYING $(cd $f; ls *.js))
[ -f $schema ] || unset schema
gnome-extensions pack ${sources[@]/#/--extra-source=} \
${schema:+--schema=$schema} --out-dir=$srcdir/zip-files $f
done
rm -rf $builddir

View File

@@ -2,19 +2,19 @@
/* exported init enable disable */
const {
Atk, Clutter, Gio, GLib, GMenu, GObject, Gtk, Meta, Shell, St
Atk, Clutter, Gio, GLib, GMenu, GObject, Gtk, Meta, Shell, St,
} = imports.gi;
const Signals = imports.signals;
const DND = imports.ui.dnd;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Signals = imports.signals;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const ExtensionUtils = imports.misc.extensionUtils;
const appSys = Shell.AppSystem.get_default();
const APPLICATION_ICON_SIZE = 32;
@@ -25,50 +25,37 @@ const NAVIGATION_REGION_OVERSHOOT = 50;
Gio._promisify(Gio._LocalFilePrototype, 'query_info_async', 'query_info_finish');
Gio._promisify(Gio._LocalFilePrototype, 'set_attributes_async', 'set_attributes_finish');
class ActivitiesMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(button) {
super();
this._button = button;
this.actor.add_child(new St.Label({ text: _('Activities Overview') }));
}
activate(event) {
this._button.menu.toggle();
Main.overview.toggle();
super.activate(event);
}
}
var ApplicationMenuItem = GObject.registerClass(
class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(button, app) {
super();
_init(button, app) {
super._init();
this._app = app;
this._button = button;
this._iconBin = new St.Bin();
this.actor.add_child(this._iconBin);
this.add_child(this._iconBin);
let appLabel = new St.Label({
text: app.get_name(),
y_expand: true,
y_align: Clutter.ActorAlign.CENTER
y_align: Clutter.ActorAlign.CENTER,
});
this.actor.add_child(appLabel);
this.actor.label_actor = appLabel;
this.add_child(appLabel);
this.label_actor = appLabel;
let textureCache = St.TextureCache.get_default();
let iconThemeChangedId = textureCache.connect('icon-theme-changed',
this._updateIcon.bind(this));
this.actor.connect('destroy', () => {
this._updateIcon.bind(this));
this.connect('destroy', () => {
textureCache.disconnect(iconThemeChangedId);
});
this._updateIcon();
this.actor._delegate = this;
let draggable = DND.makeDraggable(this.actor);
this._delegate = this;
let draggable = DND.makeDraggable(this);
let maybeStartDrag = draggable._maybeStartDrag;
draggable._maybeStartDrag = (event) => {
draggable._maybeStartDrag = event => {
if (this._dragEnabled)
return maybeStartDrag.call(draggable, event);
return false;
@@ -80,6 +67,8 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem {
this._button.selectCategory(null);
this._button.menu.toggle();
super.activate(event);
Main.overview.hide();
}
setActive(active, params) {
@@ -88,8 +77,8 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem {
super.setActive(active, params);
}
setDragEnabled(enable) {
this._dragEnabled = enable;
setDragEnabled(enabled) {
this._dragEnabled = enabled;
}
getDragActor() {
@@ -101,13 +90,16 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem {
}
_updateIcon() {
this._iconBin.set_child(this.getDragActor());
let icon = this.getDragActor();
icon.style_class = 'icon-dropshadow';
this._iconBin.set_child(icon);
}
}
});
var CategoryMenuItem = GObject.registerClass(
class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(button, category) {
super();
_init(button, category) {
super._init();
this._category = category;
this._button = button;
@@ -120,8 +112,9 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
else
name = _('Favorites');
this.actor.add_child(new St.Label({ text: name }));
this.actor.connect('motion-event', this._onMotionEvent.bind(this));
this.add_child(new St.Label({ text: name }));
this.connect('motion-event', this._onMotionEvent.bind(this));
this.connect('notify::active', this._onActiveChanged.bind(this));
}
activate(event) {
@@ -131,9 +124,9 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
}
_isNavigatingSubmenu([x, y]) {
let [posX, posY] = this.actor.get_transformed_position();
let [posX, posY] = this.get_transformed_position();
if (this._oldX == -1) {
if (this._oldX === -1) {
this._oldX = x;
this._oldY = y;
return true;
@@ -146,11 +139,11 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
this._oldY = y;
// If it lies outside the x-coordinates then it is definitely outside.
if (posX > x || posX + this.actor.width < x)
if (posX > x || posX + this.width < x)
return false;
// If it lies inside the menu item then it is definitely inside.
if (posY <= y && posY + this.actor.height >= y)
if (posY <= y && posY + this.height >= y)
return true;
// We want the keep-up triangle only if the movement is more
@@ -171,37 +164,38 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
// only check for triangle ABC.
if (posY > y) {
let offset = posY - y;
y = posY + this.actor.height + offset;
y = posY + this.height + offset;
}
// Ensure that A is (0, 0).
x -= posX;
y -= posY + this.actor.height;
y -= posY + this.height;
// Check which side of line AB the point P lies on by taking the
// cross-product of AB and AP. See:
// http://stackoverflow.com/questions/3461453/determine-which-side-of-a-line-a-point-lies
if (((this.actor.width * y) - (NAVIGATION_REGION_OVERSHOOT * x)) <= 0)
if (this.width * y - NAVIGATION_REGION_OVERSHOOT * x <= 0)
return true;
return false;
}
_onMotionEvent(actor, event) {
if (!Clutter.get_pointer_grab()) {
let device = event.get_device();
if (!device.get_grabbed_actor()) {
this._oldX = -1;
this._oldY = -1;
Clutter.grab_pointer(this.actor);
device.grab(this);
}
this.actor.hover = true;
this.hover = true;
if (this._isNavigatingSubmenu(event.get_coords()))
return true;
this._oldX = -1;
this._oldY = -1;
this.actor.hover = false;
Clutter.ungrab_pointer();
this.hover = false;
device.ungrab();
let source = event.get_source();
if (source instanceof St.Widget)
@@ -210,14 +204,14 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
return false;
}
setActive(active, params) {
if (active) {
this._button.selectCategory(this._category);
this._button.scrollToCatButton(this);
}
super.setActive(active, params);
_onActiveChanged() {
if (!this.active)
return;
this._button.selectCategory(this._category);
this._button.scrollToCatButton(this);
}
}
});
class ApplicationsMenu extends PopupMenu.PopupMenu {
constructor(sourceActor, arrowAlignment, arrowSide, button) {
@@ -229,28 +223,9 @@ class ApplicationsMenu extends PopupMenu.PopupMenu {
return false;
}
open(animate) {
this._button.hotCorner.setBarrierSize(0);
if (this._button.hotCorner.actor) // fallback corner
this._button.hotCorner.actor.hide();
super.open(animate);
}
close(animate) {
let size = Main.layoutManager.panelBox.height;
this._button.hotCorner.setBarrierSize(size);
if (this._button.hotCorner.actor) // fallback corner
this._button.hotCorner.actor.show();
super.close(animate);
}
toggle() {
if (this.isOpen) {
if (this.isOpen)
this._button.selectCategory(null);
} else {
if (Main.overview.visible)
Main.overview.hide();
}
super.toggle();
}
}
@@ -262,7 +237,7 @@ class DesktopTarget {
this._windowAddedId =
global.window_group.connect('actor-added',
this._onWindowAdded.bind(this));
this._onWindowAdded.bind(this));
global.get_window_actors().forEach(a => {
this._onWindowAdded(a.get_parent(), a);
@@ -270,14 +245,14 @@ class DesktopTarget {
}
get hasDesktop() {
return this._desktop != null;
return this._desktop !== null;
}
_onWindowAdded(group, actor) {
if (!(actor instanceof Meta.WindowActor))
return;
if (actor.meta_window.get_window_type() == Meta.WindowType.DESKTOP)
if (actor.meta_window.get_window_type() === Meta.WindowType.DESKTOP)
this._setDesktop(actor);
}
@@ -322,8 +297,8 @@ class DesktopTarget {
// Hack: force nautilus to reload file info
info = new Gio.FileInfo();
info.set_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_ACCESS,
GLib.get_real_time());
info.set_attribute_uint64(
Gio.FILE_ATTRIBUTE_TIME_ACCESS, GLib.get_real_time());
try {
await file.set_attributes_async(info, queryFlags, ioPriority, null);
} catch (e) {
@@ -388,30 +363,24 @@ class ApplicationsButton extends PanelMenu.Button {
// role ATK_ROLE_MENU like other elements of the panel.
this.accessible_role = Atk.Role.LABEL;
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
this._label = new St.Label({
text: _('Applications'),
y_expand: true,
y_align: Clutter.ActorAlign.CENTER
y_align: Clutter.ActorAlign.CENTER,
});
hbox.add_child(this._label);
hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
this.add_actor(hbox);
this.add_actor(this._label);
this.name = 'panelApplications';
this.label_actor = this._label;
this.connect('captured-event', this._onCapturedEvent.bind(this));
this._showingId = Main.overview.connect('showing', () => {
this.add_accessible_state (Atk.StateType.CHECKED);
this.add_accessible_state(Atk.StateType.CHECKED);
});
this._hidingId = Main.overview.connect('hiding', () => {
this.remove_accessible_state (Atk.StateType.CHECKED);
this.remove_accessible_state(Atk.StateType.CHECKED);
});
Main.layoutManager.connect('startup-complete',
this._setKeybinding.bind(this));
this._setKeybinding.bind(this));
this._setKeybinding();
this._desktopTarget = new DesktopTarget();
@@ -426,14 +395,14 @@ class ApplicationsButton extends PanelMenu.Button {
this._tree = new GMenu.Tree({ menu_basename: 'applications.menu' });
this._treeChangedId = this._tree.connect('changed',
this._onTreeChanged.bind(this));
this._onTreeChanged.bind(this));
this._applicationsButtons = new Map();
this.reloadFlag = false;
this._createLayout();
this._display();
this._installedChangedId = appSys.connect('installed-changed',
this._onTreeChanged.bind(this));
this._onTreeChanged.bind(this));
}
_onTreeChanged() {
@@ -445,49 +414,38 @@ class ApplicationsButton extends PanelMenu.Button {
}
}
get hotCorner() {
return Main.layoutManager.hotCorners[Main.layoutManager.primaryIndex];
}
_createVertSeparator() {
let separator = new St.DrawingArea({
style_class: 'calendar-vertical-separator',
pseudo_class: 'highlighted'
pseudo_class: 'highlighted',
});
separator.connect('repaint', this._onVertSepRepaint.bind(this));
return separator;
}
_onDestroy() {
super._onDestroy();
Main.overview.disconnect(this._showingId);
Main.overview.disconnect(this._hidingId);
appSys.disconnect(this._installedChangedId);
this._tree.disconnect(this._treeChangedId);
this._tree = null;
let handler = Main.sessionMode.hasOverview ?
Main.overview.toggle.bind(Main.overview) : null;
Main.wm.setCustomKeybindingHandler('panel-main-menu',
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
handler);
Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
Main.sessionMode.hasOverview
? Main.overview.toggle.bind(Main.overview)
: null);
this._desktopTarget.destroy();
}
_onCapturedEvent(actor, event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
if (!Main.overview.shouldToggleByCornerOrButton())
return true;
}
return false;
}
_onMenuKeyPress(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
let direction = symbol == Clutter.KEY_Left ?
Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
if (symbol === Clutter.KEY_Left || symbol === Clutter.KEY_Right) {
let direction = symbol === Clutter.KEY_Left
? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
if (this.menu.actor.navigate_focus(global.stage.key_focus, direction, false))
return true;
}
@@ -522,9 +480,8 @@ class ApplicationsButton extends PanelMenu.Button {
_setKeybinding() {
Main.wm.setCustomKeybindingHandler('panel-main-menu',
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
() => this.menu.toggle());
Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
() => this.menu.toggle());
}
_redisplay() {
@@ -536,8 +493,8 @@ class ApplicationsButton extends PanelMenu.Button {
_loadCategory(categoryId, dir) {
let iter = dir.iter();
let nextType;
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
if (nextType == GMenu.TreeItemType.ENTRY) {
while ((nextType = iter.next()) !== GMenu.TreeItemType.INVALID) {
if (nextType === GMenu.TreeItemType.ENTRY) {
let entry = iter.get_entry();
let id;
try {
@@ -550,9 +507,9 @@ class ApplicationsButton extends PanelMenu.Button {
app = new Shell.App({ app_info: entry.get_app_info() });
if (app.get_app_info().should_show())
this.applicationsByCategory[categoryId].push(app);
} else if (nextType == GMenu.TreeItemType.SEPARATOR) {
} else if (nextType === GMenu.TreeItemType.SEPARATOR) {
this.applicationsByCategory[categoryId].push('separator');
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
} else if (nextType === GMenu.TreeItemType.DIRECTORY) {
let subdir = iter.get_directory();
if (!subdir.get_is_nodisplay())
this._loadCategory(categoryId, subdir);
@@ -565,13 +522,13 @@ class ApplicationsButton extends PanelMenu.Button {
let appsScrollBoxAlloc = this.applicationsScrollBox.get_allocation_box();
let currentScrollValue = appsScrollBoxAdj.get_value();
let boxHeight = appsScrollBoxAlloc.y2 - appsScrollBoxAlloc.y1;
let buttonAlloc = button.actor.get_allocation_box();
let buttonAlloc = button.get_allocation_box();
let newScrollValue = currentScrollValue;
if (currentScrollValue > buttonAlloc.y1 - 10)
newScrollValue = buttonAlloc.y1 - 10;
if (boxHeight + currentScrollValue < buttonAlloc.y2 + 10)
newScrollValue = buttonAlloc.y2 - boxHeight + 10;
if (newScrollValue != currentScrollValue)
if (newScrollValue !== currentScrollValue)
appsScrollBoxAdj.set_value(newScrollValue);
}
@@ -580,13 +537,13 @@ class ApplicationsButton extends PanelMenu.Button {
let catsScrollBoxAlloc = this.categoriesScrollBox.get_allocation_box();
let currentScrollValue = catsScrollBoxAdj.get_value();
let boxHeight = catsScrollBoxAlloc.y2 - catsScrollBoxAlloc.y1;
let buttonAlloc = button.actor.get_allocation_box();
let buttonAlloc = button.get_allocation_box();
let newScrollValue = currentScrollValue;
if (currentScrollValue > buttonAlloc.y1 - 10)
newScrollValue = buttonAlloc.y1 - 10;
if (boxHeight + currentScrollValue < buttonAlloc.y2 + 10)
newScrollValue = buttonAlloc.y2 - boxHeight + 10;
if (newScrollValue != currentScrollValue)
if (newScrollValue !== currentScrollValue)
catsScrollBoxAdj.set_value(newScrollValue);
}
@@ -596,10 +553,8 @@ class ApplicationsButton extends PanelMenu.Button {
this.mainBox = new St.BoxLayout({ vertical: false });
this.leftBox = new St.BoxLayout({ vertical: true });
this.applicationsScrollBox = new St.ScrollView({
x_fill: true,
y_fill: false,
y_align: St.Align.START,
style_class: 'apps-menu vfade'
style_class: 'apps-menu vfade',
x_expand: true,
});
this.applicationsScrollBox.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
let vscroll = this.applicationsScrollBox.get_vscroll_bar();
@@ -610,29 +565,13 @@ class ApplicationsButton extends PanelMenu.Button {
this.menu.passEvents = false;
});
this.categoriesScrollBox = new St.ScrollView({
x_fill: true,
y_fill: false,
y_align: St.Align.START,
style_class: 'vfade'
style_class: 'vfade',
});
this.categoriesScrollBox.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
vscroll = this.categoriesScrollBox.get_vscroll_bar();
vscroll.connect('scroll-start', () => this.menu.passEvents = true);
vscroll.connect('scroll-stop', () => this.menu.passEvents = false);
this.leftBox.add(this.categoriesScrollBox, {
expand: true,
x_fill: true,
y_fill: true,
y_align: St.Align.START
});
let activities = new ActivitiesMenuItem(this);
this.leftBox.add(activities.actor, {
expand: false,
x_fill: true,
y_fill: false,
y_align: St.Align.START
});
vscroll.connect('scroll-start', () => (this.menu.passEvents = true));
vscroll.connect('scroll-stop', () => (this.menu.passEvents = false));
this.leftBox.add_child(this.categoriesScrollBox);
this.applicationsBox = new St.BoxLayout({ vertical: true });
this.applicationsScrollBox.add_actor(this.applicationsBox);
@@ -640,16 +579,8 @@ class ApplicationsButton extends PanelMenu.Button {
this.categoriesScrollBox.add_actor(this.categoriesBox);
this.mainBox.add(this.leftBox);
this.mainBox.add(this._createVertSeparator(), {
expand: false,
x_fill: false,
y_fill: true
});
this.mainBox.add(this.applicationsScrollBox, {
expand: true,
x_fill: true,
y_fill: true
});
this.mainBox.add_child(this._createVertSeparator());
this.mainBox.add_child(this.applicationsScrollBox);
section.actor.add_actor(this.mainBox);
}
@@ -658,16 +589,16 @@ class ApplicationsButton extends PanelMenu.Button {
this.mainBox.style = 'width: 35em;';
this.mainBox.hide();
//Load categories
// Load categories
this.applicationsByCategory = {};
this._tree.load_sync();
let root = this._tree.get_root_directory();
let categoryMenuItem = new CategoryMenuItem(this, null);
this.categoriesBox.add_actor(categoryMenuItem.actor);
this.categoriesBox.add_actor(categoryMenuItem);
let iter = root.iter();
let nextType;
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
if (nextType != GMenu.TreeItemType.DIRECTORY)
while ((nextType = iter.next()) !== GMenu.TreeItemType.INVALID) {
if (nextType !== GMenu.TreeItemType.DIRECTORY)
continue;
let dir = iter.get_directory();
@@ -678,12 +609,12 @@ class ApplicationsButton extends PanelMenu.Button {
this.applicationsByCategory[categoryId] = [];
this._loadCategory(categoryId, dir);
if (this.applicationsByCategory[categoryId].length > 0) {
let categoryMenuItem = new CategoryMenuItem(this, dir);
this.categoriesBox.add_actor(categoryMenuItem.actor);
categoryMenuItem = new CategoryMenuItem(this, dir);
this.categoriesBox.add_actor(categoryMenuItem);
}
}
//Load applications
// Load applications
this._displayButtons(this._listApplications(null));
let themeContext = St.ThemeContext.get_for_stage(global.stage);
@@ -720,8 +651,8 @@ class ApplicationsButton extends PanelMenu.Button {
item.setDragEnabled(this._desktopTarget.hasDesktop);
this._applicationsButtons.set(app, item);
}
if (!item.actor.get_parent())
this.applicationsBox.add_actor(item.actor);
if (!item.get_parent())
this.applicationsBox.add_actor(item);
}
}
@@ -731,13 +662,9 @@ class ApplicationsButton extends PanelMenu.Button {
if (categoryMenuId) {
applist = this.applicationsByCategory[categoryMenuId];
} else {
applist = new Array();
let favorites = global.settings.get_strv('favorite-apps');
for (let i = 0; i < favorites.length; i++) {
let app = appSys.lookup_app(favorites[i]);
if (app)
applist.push(app);
}
applist = global.settings.get_strv('favorite-apps')
.map(id => appSys.lookup_app(id))
.filter(app => app);
}
return applist;
@@ -745,19 +672,16 @@ class ApplicationsButton extends PanelMenu.Button {
});
let appsMenuButton;
let activitiesButton;
function enable() {
activitiesButton = Main.panel.statusArea['activities'];
activitiesButton.container.hide();
appsMenuButton = new ApplicationsButton();
Main.panel.addToStatusArea('apps-menu', appsMenuButton, 1, 'left');
let index = Main.sessionMode.panel.left.indexOf('activities') + 1;
Main.panel.addToStatusArea('apps-menu', appsMenuButton, index, 'left');
}
function disable() {
Main.panel.menuManager.removeMenu(appsMenuButton.menu);
appsMenuButton.destroy();
activitiesButton.container.show();
}
function init() {

View File

@@ -2,11 +2,10 @@
// Start apps on custom workspaces
/* exported init enable disable */
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const { Shell } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
class WindowMover {
constructor() {
@@ -17,7 +16,7 @@ class WindowMover {
this._appsChangedId =
this._appSystem.connect('installed-changed',
this._updateAppData.bind(this));
this._updateAppData.bind(this));
this._settings.connect('changed', this._updateAppConfigs.bind(this));
this._updateAppConfigs();
@@ -36,23 +35,22 @@ class WindowMover {
_updateAppData() {
let ids = [...this._appConfigs.keys()];
let removedApps = [...this._appData.keys()].filter(
a => !ids.includes(a.id)
);
let removedApps = [...this._appData.keys()]
.filter(a => !ids.includes(a.id));
removedApps.forEach(app => {
app.disconnect(this._appData.get(app).windowsChangedId);
this._appData.delete(app);
});
let addedApps = ids.map(id => this._appSystem.lookup_app(id)).filter(
app => app != null && !this._appData.has(app)
);
let addedApps = ids
.map(id => this._appSystem.lookup_app(id))
.filter(app => app && !this._appData.has(app));
addedApps.forEach(app => {
let data = {
windowsChangedId: app.connect('windows-changed',
this._appWindowsChanged.bind(this)),
this._appWindowsChanged.bind(this)),
moveWindowsId: 0,
windows: app.get_windows()
windows: app.get_windows(),
};
this._appData.set(app, data);
});
@@ -74,7 +72,7 @@ class WindowMover {
}
_moveWindow(window, workspaceNum) {
if (window.skip_taskbar)
if (window.skip_taskbar || window.is_on_all_workspaces())
return;
// ensure we have the required number of workspaces
@@ -95,9 +93,9 @@ class WindowMover {
// the window still exists and is just moved to a different workspace
// or something; assume it'll be added back immediately, so keep it
// to avoid moving it again
windows.push(...data.windows.filter(
w => !windows.includes(w) && w.get_compositor_private() != null
));
windows.push(...data.windows.filter(w => {
return !windows.includes(w) && w.get_compositor_private() !== null;
}));
let workspaceNum = this._appConfigs.get(app.id);
windows.filter(w => !data.windows.includes(w)).forEach(window => {
@@ -118,14 +116,16 @@ function myCheckWorkspaces() {
let keepAliveWorkspaces = [];
let foundNonEmpty = false;
for (let i = this._workspaces.length - 1; i >= 0; i--) {
if (!foundNonEmpty)
foundNonEmpty = this._workspaces[i].list_windows().length > 0;
else if (!this._workspaces[i]._keepAliveId)
if (!foundNonEmpty) {
foundNonEmpty = this._workspaces[i].list_windows().some(
w => !w.is_on_all_workspaces());
} else if (!this._workspaces[i]._keepAliveId) {
keepAliveWorkspaces.push(this._workspaces[i]);
}
}
// make sure the original method only removes empty workspaces at the end
keepAliveWorkspaces.forEach(ws => ws._keepAliveId = 1);
keepAliveWorkspaces.forEach(ws => (ws._keepAliveId = 1));
prevCheckWorkspaces.call(this);
keepAliveWorkspaces.forEach(ws => delete ws._keepAliveId);

View File

@@ -2,11 +2,10 @@
// Start apps on custom workspaces
/* exported init buildPrefsWidget */
const { Gio, GObject, Gtk } = imports.gi;
const { Gio, GLib, GObject, Gtk, Pango } = imports.gi;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const N_ = e => e;
const ExtensionUtils = imports.misc.extensionUtils;
@@ -14,270 +13,263 @@ const SETTINGS_KEY = 'application-list';
const WORKSPACE_MAX = 36; // compiled in limit of mutter
const Columns = {
APPINFO: 0,
DISPLAY_NAME: 1,
ICON: 2,
WORKSPACE: 3,
ADJUSTMENT: 4
};
const AutoMoveSettingsWidget = GObject.registerClass(
class AutoMoveSettingsWidget extends Gtk.ScrolledWindow {
_init() {
super._init({
hscrollbar_policy: Gtk.PolicyType.NEVER,
});
const Widget = GObject.registerClass({
GTypeName: 'AutoMoveWindowsPrefsWidget',
}, class Widget extends Gtk.Grid {
_init(params) {
super._init(params);
this.set_orientation(Gtk.Orientation.VERTICAL);
const box = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
halign: Gtk.Align.CENTER,
spacing: 12,
margin_top: 36,
margin_bottom: 36,
margin_start: 36,
margin_end: 36,
});
this.set_child(box);
box.append(new Gtk.Label({
label: '<b>%s</b>'.format(_('Workspace Rules')),
use_markup: true,
halign: Gtk.Align.START,
}));
this._list = new Gtk.ListBox({
selection_mode: Gtk.SelectionMode.NONE,
valign: Gtk.Align.START,
show_separators: true,
});
box.append(this._list);
const context = this._list.get_style_context();
const cssProvider = new Gtk.CssProvider();
cssProvider.load_from_data(
'list { min-width: 30em; }');
context.add_provider(cssProvider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
context.add_class('frame');
this._list.append(new NewRuleRow());
this._actionGroup = new Gio.SimpleActionGroup();
this._list.insert_action_group('rules', this._actionGroup);
let action;
action = new Gio.SimpleAction({ name: 'add' });
action.connect('activate', this._onAddActivated.bind(this));
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'remove',
parameter_type: new GLib.VariantType('s'),
});
action.connect('activate', this._onRemoveActivated.bind(this));
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({ name: 'update' });
action.connect('activate', () => {
this._settings.set_strv(SETTINGS_KEY,
this._getRuleRows().map(row => `${row.id}:${row.value}`));
});
this._actionGroup.add_action(action);
this._updateAction = action;
this._settings = ExtensionUtils.getSettings();
this._settings.connect('changed', this._refresh.bind(this));
this._changedPermitted = false;
this._changedId = this._settings.connect('changed',
this._sync.bind(this));
this._sync();
this._store = new Gtk.ListStore();
this._store.set_column_types([
Gio.AppInfo,
GObject.TYPE_STRING,
Gio.Icon,
GObject.TYPE_INT,
Gtk.Adjustment
]);
let scrolled = new Gtk.ScrolledWindow({ shadow_type: Gtk.ShadowType.IN });
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.add(scrolled);
this._treeView = new Gtk.TreeView({
model: this._store,
hexpand: true,
vexpand: true
});
this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE);
let appColumn = new Gtk.TreeViewColumn({
expand: true,
sort_column_id: Columns.DISPLAY_NAME,
title: _('Application')
});
let iconRenderer = new Gtk.CellRendererPixbuf;
appColumn.pack_start(iconRenderer, false);
appColumn.add_attribute(iconRenderer, 'gicon', Columns.ICON);
let nameRenderer = new Gtk.CellRendererText;
appColumn.pack_start(nameRenderer, true);
appColumn.add_attribute(nameRenderer, 'text', Columns.DISPLAY_NAME);
this._treeView.append_column(appColumn);
let workspaceColumn = new Gtk.TreeViewColumn({
title: _('Workspace'),
sort_column_id: Columns.WORKSPACE
});
let workspaceRenderer = new Gtk.CellRendererSpin({ editable: true });
workspaceRenderer.connect('edited', this._workspaceEdited.bind(this));
workspaceColumn.pack_start(workspaceRenderer, true);
workspaceColumn.add_attribute(workspaceRenderer, 'adjustment', Columns.ADJUSTMENT);
workspaceColumn.add_attribute(workspaceRenderer, 'text', Columns.WORKSPACE);
this._treeView.append_column(workspaceColumn);
scrolled.add(this._treeView);
let toolbar = new Gtk.Toolbar({ icon_size: Gtk.IconSize.SMALL_TOOLBAR });
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
this.add(toolbar);
let newButton = new Gtk.ToolButton({
icon_name: 'bookmark-new-symbolic',
label: _('Add Rule'),
is_important: true
});
newButton.connect('clicked', this._createNew.bind(this));
toolbar.add(newButton);
let delButton = new Gtk.ToolButton({ icon_name: 'edit-delete-symbolic' });
delButton.connect('clicked', this._deleteSelected.bind(this));
toolbar.add(delButton);
let selection = this._treeView.get_selection();
selection.connect('changed', () => {
delButton.sensitive = selection.count_selected_rows() > 0;
});
delButton.sensitive = selection.count_selected_rows() > 0;
this._changedPermitted = true;
this._refresh();
this.connect('destroy', () => this._settings.run_dispose());
}
_createNew() {
let dialog = new Gtk.Dialog({
title: _('Create new matching rule'),
transient_for: this.get_toplevel(),
use_header_bar: true,
modal: true
});
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
let addButton = dialog.add_button(_('Add'), Gtk.ResponseType.OK);
dialog.set_default_response(Gtk.ResponseType.OK);
let grid = new Gtk.Grid({
column_spacing: 10,
row_spacing: 15,
margin: 10
});
dialog._appChooser = new Gtk.AppChooserWidget({ show_all: true });
dialog._appChooser.connect('application-selected', (w, appInfo) => {
addButton.sensitive = appInfo && this._checkId(appInfo.get_id());
});
let appInfo = dialog._appChooser.get_app_info();
addButton.sensitive = appInfo && this._checkId(appInfo.get_id());
grid.attach(dialog._appChooser, 0, 0, 2, 1);
grid.attach(new Gtk.Label({
label: _('Workspace'),
halign: Gtk.Align.END
}), 0, 1, 1, 1);
let adjustment = new Gtk.Adjustment({
lower: 1,
upper: WORKSPACE_MAX,
step_increment: 1
});
dialog._spin = new Gtk.SpinButton({
adjustment: adjustment,
snap_to_ticks: true
});
dialog._spin.set_value(1);
grid.attach(dialog._spin, 1, 1, 1, 1);
dialog.get_content_area().add(grid);
dialog.connect('response', (dialog, id) => {
if (id != Gtk.ResponseType.OK) {
dialog.destroy();
return;
_onAddActivated() {
const dialog = new NewRuleDialog(this.get_root());
dialog.connect('response', (dlg, id) => {
const appInfo = id === Gtk.ResponseType.OK
? dialog.get_widget().get_app_info() : null;
if (appInfo) {
this._settings.set_strv(SETTINGS_KEY, [
...this._settings.get_strv(SETTINGS_KEY),
`${appInfo.get_id()}:1`,
]);
}
let appInfo = dialog._appChooser.get_app_info();
if (!appInfo)
return;
let index = Math.floor(dialog._spin.value);
if (isNaN(index) || index < 0)
index = 1;
this._changedPermitted = false;
this._appendItem(appInfo.get_id(), index);
this._changedPermitted = true;
this._appendRow(appInfo, index);
dialog.destroy();
});
dialog.show_all();
dialog.show();
}
_deleteSelected() {
let [any, model_, iter] = this._treeView.get_selection().get_selected();
if (any) {
let appInfo = this._store.get_value(iter, Columns.APPINFO);
this._changedPermitted = false;
this._removeItem(appInfo.get_id());
this._changedPermitted = true;
this._store.remove(iter);
}
_onRemoveActivated(action, param) {
const removed = param.deepUnpack();
this._settings.set_strv(SETTINGS_KEY,
this._settings.get_strv(SETTINGS_KEY).filter(entry => {
const [id] = entry.split(':');
return id !== removed;
}));
}
_workspaceEdited(renderer, pathString, text) {
let index = parseInt(text);
if (isNaN(index) || index < 0)
index = 1;
let path = Gtk.TreePath.new_from_string(pathString);
let [model_, iter] = this._store.get_iter(path);
let appInfo = this._store.get_value(iter, Columns.APPINFO);
this._changedPermitted = false;
this._changeItem(appInfo.get_id(), index);
this._store.set_value(iter, Columns.WORKSPACE, index);
this._changedPermitted = true;
_getRuleRows() {
return [...this._list].filter(row => !!row.id);
}
_refresh() {
if (!this._changedPermitted)
// Ignore this notification, model is being modified outside
return;
this._store.clear();
let currentItems = this._settings.get_strv(SETTINGS_KEY);
let validItems = [];
for (let i = 0; i < currentItems.length; i++) {
let [id, index] = currentItems[i].split(':');
let appInfo = Gio.DesktopAppInfo.new(id);
if (!appInfo)
continue;
validItems.push(currentItems[i]);
this._appendRow(appInfo, parseInt(index));
}
if (validItems.length != currentItems.length) // some items were filtered out
this._settings.set_strv(SETTINGS_KEY, validItems);
}
_appendRow(appInfo, workspace) {
let iter = this._store.append();
let icon = appInfo.get_icon();
let displayName = appInfo.get_display_name();
let adj = new Gtk.Adjustment({
lower: 1,
upper: WORKSPACE_MAX,
step_increment: 1,
value: workspace
_sync() {
const oldRules = this._getRuleRows();
const newRules = this._settings.get_strv(SETTINGS_KEY).map(entry => {
const [id, value] = entry.split(':');
return { id, value };
});
let { APPINFO, ICON, DISPLAY_NAME, WORKSPACE, ADJUSTMENT } = Columns;
this._store.set(iter,
[APPINFO, ICON, DISPLAY_NAME, WORKSPACE, ADJUSTMENT],
[appInfo, icon, displayName, workspace, adj]);
}
_checkId(id) {
let items = this._settings.get_strv(SETTINGS_KEY);
return !items.some(i => i.startsWith(`${id}:`));
}
this._settings.block_signal_handler(this._changedId);
this._updateAction.enabled = false;
_appendItem(id, workspace) {
let currentItems = this._settings.get_strv(SETTINGS_KEY);
currentItems.push(`${id}:${workspace}`);
this._settings.set_strv(SETTINGS_KEY, currentItems);
}
newRules.forEach(({ id, value }, index) => {
const row = oldRules.find(r => r.id === id);
const appInfo = row
? null : Gio.DesktopAppInfo.new(id);
_removeItem(id) {
let currentItems = this._settings.get_strv(SETTINGS_KEY);
let index = currentItems.map(el => el.split(':')[0]).indexOf(id);
if (row)
row.set({ value });
else if (appInfo)
this._list.insert(new RuleRow(appInfo, value), index);
});
if (index < 0)
return;
currentItems.splice(index, 1);
this._settings.set_strv(SETTINGS_KEY, currentItems);
}
const removed = oldRules.filter(
({ id }) => !newRules.find(r => r.id === id));
removed.forEach(r => this._list.remove(r));
_changeItem(id, workspace) {
let currentItems = this._settings.get_strv(SETTINGS_KEY);
let index = currentItems.map(el => el.split(':')[0]).indexOf(id);
if (index < 0)
currentItems.push(`${id}:${workspace}`);
else
currentItems[index] = `${id}:${workspace}`;
this._settings.set_strv(SETTINGS_KEY, currentItems);
this._settings.unblock_signal_handler(this._changedId);
this._updateAction.enabled = true;
}
});
const RuleRow = GObject.registerClass({
Properties: {
'id': GObject.ParamSpec.string(
'id', 'id', 'id',
GObject.ParamFlags.READABLE,
''),
'value': GObject.ParamSpec.uint(
'value', 'value', 'value',
GObject.ParamFlags.READWRITE,
1, WORKSPACE_MAX, 1),
},
}, class RuleRow extends Gtk.ListBoxRow {
_init(appInfo, value) {
const box = new Gtk.Box({
spacing: 6,
margin_top: 6,
margin_bottom: 6,
margin_start: 6,
margin_end: 6,
});
super._init({
activatable: false,
value,
child: box,
});
this._appInfo = appInfo;
const icon = new Gtk.Image({
gicon: appInfo.get_icon(),
pixel_size: 32,
});
icon.get_style_context().add_class('icon-dropshadow');
box.append(icon);
const label = new Gtk.Label({
label: appInfo.get_display_name(),
halign: Gtk.Align.START,
hexpand: true,
max_width_chars: 20,
ellipsize: Pango.EllipsizeMode.END,
});
box.append(label);
const spinButton = new Gtk.SpinButton({
adjustment: new Gtk.Adjustment({
lower: 1,
upper: WORKSPACE_MAX,
step_increment: 1,
}),
snap_to_ticks: true,
margin_end: 6,
});
this.bind_property('value',
spinButton, 'value',
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
box.append(spinButton);
const button = new Gtk.Button({
action_name: 'rules.remove',
action_target: new GLib.Variant('s', this.id),
icon_name: 'edit-delete-symbolic',
});
box.append(button);
this.connect('notify::value',
() => this.activate_action('rules.update', null));
}
get id() {
return this._appInfo.get_id();
}
});
const NewRuleRow = GObject.registerClass(
class NewRuleRow extends Gtk.ListBoxRow {
_init() {
super._init({
action_name: 'rules.add',
child: new Gtk.Image({
icon_name: 'list-add-symbolic',
pixel_size: 16,
margin_top: 12,
margin_bottom: 12,
margin_start: 12,
margin_end: 12,
}),
});
this.update_property(
[Gtk.AccessibleProperty.LABEL], [_('Add Rule')]);
}
});
const NewRuleDialog = GObject.registerClass(
class NewRuleDialog extends Gtk.AppChooserDialog {
_init(parent) {
super._init({
transient_for: parent,
modal: true,
});
this._settings = ExtensionUtils.getSettings();
this.get_widget().set({
show_all: true,
show_other: true, // hide more button
});
this.get_widget().connect('application-selected',
this._updateSensitivity.bind(this));
this._updateSensitivity();
}
_updateSensitivity() {
const rules = this._settings.get_strv(SETTINGS_KEY);
const appInfo = this.get_widget().get_app_info();
this.set_response_sensitive(Gtk.ResponseType.OK,
appInfo && !rules.some(i => i.startsWith(appInfo.get_id())));
}
});
function init() {
ExtensionUtils.initTranslations();
}
function buildPrefsWidget() {
let widget = new Widget({ margin: 12 });
widget.show_all();
return widget;
return new AutoMoveSettingsWidget();
}

View File

@@ -1,40 +1,51 @@
/* exported init enable disable */
// Drive menu extension
const { Gio, GObject, Shell, St } = imports.gi;
const { Clutter, Gio, GObject, Shell, St } = imports.gi;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const ShellMountOperation = imports.ui.shellMountOperation;
const ExtensionUtils = imports.misc.extensionUtils;
var MountMenuItem = GObject.registerClass(
class MountMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(mount) {
super();
_init(mount) {
super._init({
style_class: 'drive-menu-item',
});
this.label = new St.Label({ text: mount.get_name() });
this.actor.add(this.label, { expand: true });
this.actor.label_actor = this.label;
this.label = new St.Label({
text: mount.get_name(),
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this.label);
this.label_actor = this.label;
this.mount = mount;
this.connect('destroy', this._onDestroy.bind(this));
let ejectIcon = new St.Icon({
icon_name: 'media-eject-symbolic',
style_class: 'popup-menu-icon'
style_class: 'popup-menu-icon',
});
let ejectButton = new St.Button({
child: ejectIcon,
style_class: 'button',
});
let ejectButton = new St.Button({ child: ejectIcon });
ejectButton.connect('clicked', this._eject.bind(this));
this.actor.add(ejectButton);
this.add(ejectButton);
this._changedId = mount.connect('changed', this._syncVisibility.bind(this));
this._syncVisibility();
}
destroy() {
_onDestroy() {
if (this._changedId) {
this.mount.disconnect(this._changedId);
this._changedId = 0;
@@ -51,32 +62,33 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem {
let volume = this.mount.get_volume();
if (volume == null) {
if (!volume) {
// probably a GDaemonMount, could be network or
// local, but we can't tell; assume it's local for now
return true;
}
return volume.get_identifier('class') != 'network';
return volume.get_identifier('class') !== 'network';
}
_syncVisibility() {
this.actor.visible = this._isInteresting();
this.visible = this._isInteresting();
}
_eject() {
let unmountArgs = [
Gio.MountUnmountFlags.NONE,
(new ShellMountOperation.ShellMountOperation(this.mount)).mountOp,
null // Gio.Cancellable
new ShellMountOperation.ShellMountOperation(this.mount).mountOp,
null, // Gio.Cancellable
];
if (this.mount.can_eject())
if (this.mount.can_eject()) {
this.mount.eject_with_operation(...unmountArgs,
this._ejectFinish.bind(this));
else
this._ejectFinish.bind(this));
} else {
this.mount.unmount_with_operation(...unmountArgs,
this._unmountFinish.bind(this));
this._unmountFinish.bind(this));
}
}
_unmountFinish(mount, result) {
@@ -102,28 +114,25 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem {
}
activate(event) {
let uri = this.mount.get_root().get_uri();
let context = global.create_app_launch_context(event.get_time(), -1);
Gio.AppInfo.launch_default_for_uri(this.mount.get_root().get_uri(),
context);
Gio.AppInfo.launch_default_for_uri(uri, context);
super.activate(event);
}
}
});
let DriveMenu = GObject.registerClass(
class DriveMenu extends PanelMenu.Button {
_init() {
super._init(0.0, _('Removable devices'));
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
let icon = new St.Icon({
icon_name: 'media-eject-symbolic',
style_class: 'system-status-icon'
style_class: 'system-status-icon',
});
hbox.add_child(icon);
hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
this.add_child(hbox);
this.add_child(icon);
this._monitor = Gio.VolumeMonitor.get();
this._addedId = this._monitor.connect('mount-added', (monitor, mount) => {
@@ -150,7 +159,7 @@ class DriveMenu extends PanelMenu.Button {
}
_updateMenuVisibility() {
if (this._mounts.filter(i => i.actor.visible).length > 0)
if (this._mounts.filter(i => i.visible).length > 0)
this.show();
else
this.hide();
@@ -165,13 +174,13 @@ class DriveMenu extends PanelMenu.Button {
_removeMount(mount) {
for (let i = 0; i < this._mounts.length; i++) {
let item = this._mounts[i];
if (item.mount == mount) {
if (item.mount === mount) {
item.destroy();
this._mounts.splice(i, 1);
return;
}
}
log ('Removing a mount that was never added to the menu');
log('Removing a mount that was never added to the menu');
}
_onDestroy() {
@@ -193,7 +202,7 @@ function init() {
let _indicator;
function enable() {
_indicator = new DriveMenu;
_indicator = new DriveMenu();
Main.panel.addToStatusArea('drive-menu', _indicator);
}

View File

@@ -1 +1,7 @@
/* This extensions requires no custom styling */
.drive-menu-item { spacing: 12px; }
.drive-menu-item .button {
border-radius: 99px;
padding: 3px;
min-height: auto;
}

View File

@@ -5,7 +5,7 @@ let _activateOriginal = null;
function enable() {
_activateOriginal = AppDisplay.AppIcon.prototype.activate;
AppDisplay.AppIcon.prototype.activate = function() {
AppDisplay.AppIcon.prototype.activate = function () {
_activateOriginal.call(this, 2);
};
}

View File

@@ -3,7 +3,7 @@ js_sources = []
metadata_name = 'metadata.json'
foreach e : all_extensions
foreach e : enabled_extensions
uuid = e + uuid_suffix
metadata_conf = configuration_data()
@@ -19,27 +19,11 @@ foreach e : all_extensions
subdir(e)
js_sources += extension_sources
if (enabled_extensions.contains(e))
install_data (extension_sources + extension_data,
install_dir: join_paths(extensiondir, uuid)
)
endif
install_data (extension_sources + extension_data,
install_dir: join_paths(extensiondir, uuid)
)
endforeach
install_data (extension_schemas,
install_dir: schemadir
)
foreach js_source : js_sources
if (js60.found())
path_array = '@0@'.format(js_source).split('/')
name = join_paths(path_array[-2], path_array[-1])
test('Checking syntax of ' + name, js60,
args: ['-s', '-c', js_source],
workdir: meson.current_source_dir()
)
endif
endforeach

View File

@@ -1,8 +1,11 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported enable disable */
const Workspace = imports.ui.workspace;
const { Clutter } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const { WindowPreview } = imports.ui.windowPreview;
const Workspace = imports.ui.workspace;
// testing settings for natural window placement strategy:
const WINDOW_PLACEMENT_NATURAL_ACCURACY = 20; // accuracy of window translate moves (KDE-default: 20)
@@ -14,9 +17,7 @@ class Rect {
[this.x, this.y, this.width, this.height] = [x, y, width, height];
}
/**
* used in _calculateWindowTransformationsNatural to replace Meta.Rectangle that is too slow.
*/
// used in _calculateWindowTransformationsNatural to replace Meta.Rectangle that is too slow.
copy() {
return new Rect(this.x, this.y, this.width, this.height);
}
@@ -49,10 +50,10 @@ class Rect {
}
overlap(rect2) {
return !((this.x + this.width <= rect2.x) ||
(rect2.x + rect2.width <= this.x) ||
(this.y + this.height <= rect2.y) ||
(rect2.y + rect2.height <= this.y));
return !(this.x + this.width <= rect2.x ||
rect2.x + rect2.width <= this.x ||
this.y + this.height <= rect2.y ||
rect2.y + rect2.height <= this.y);
}
center() {
@@ -66,16 +67,18 @@ class Rect {
}
class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
constructor(settings) {
super();
constructor(params, settings) {
super(params);
this._settings = settings;
}
computeLayout(windows, layout) {
layout.windows = windows;
computeLayout(windows, _params) {
return {
windows,
};
}
/**
/*
* Returns clones with matching target coordinates and scales to arrange windows in a natural way that no overlap exists and relative window size is preserved.
* This function is almost a 1:1 copy of the function
* PresentWindowsEffect::calculateWindowTransformationsNatural() from KDE, see:
@@ -101,9 +104,8 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
// This is used when the window is on the edge of the screen to try to use as much screen real estate as possible.
directions[i] = direction;
direction++;
if (direction == 4) {
if (direction === 4)
direction = 0;
}
}
let loopCounter = 0;
@@ -113,10 +115,10 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
for (let i = 0; i < rects.length; i++) {
for (let j = 0; j < rects.length; j++) {
let adjustments = [-1, -1, 1, 1]
.map(v => v *= WINDOW_PLACEMENT_NATURAL_GAPS);
.map(v => (v *= WINDOW_PLACEMENT_NATURAL_GAPS));
let iAdjusted = rects[i].adjusted(...adjustments);
let jAdjusted = rects[j].adjusted(...adjustments);
if (i != j && iAdjusted.overlap(jAdjusted)) {
if (i !== j && iAdjusted.overlap(jAdjusted)) {
loopCounter++;
overlap = true;
@@ -128,10 +130,10 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
let diff = [jCenter[0] - iCenter[0], jCenter[1] - iCenter[1]];
// Prevent dividing by zero and non-movement
if (diff[0] == 0 && diff[1] == 0)
if (diff[0] === 0 && diff[1] === 0)
diff[0] = 1;
// Try to keep screen/workspace aspect ratio
if ( bounds.height / bounds.width > areaRect.height / areaRect.width )
if (bounds.height / bounds.width > areaRect.height / areaRect.width)
diff[0] *= 2;
else
diff[1] *= 2;
@@ -160,33 +162,33 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
let xSection = Math.round((rects[i].x - bounds.x) / (bounds.width / 3));
let ySection = Math.round((rects[i].y - bounds.y) / (bounds.height / 3));
let iCenter = rects[i].center();
iCenter = rects[i].center();
diff[0] = 0;
diff[1] = 0;
if (xSection != 1 || ySection != 1) { // Remove this if you want the center to pull as well
if (xSection == 1)
xSection = (directions[i] / 2 ? 2 : 0);
if (ySection == 1)
ySection = (directions[i] % 2 ? 2 : 0);
if (xSection !== 1 || ySection !== 1) { // Remove this if you want the center to pull as well
if (xSection === 1)
xSection = directions[i] / 2 ? 2 : 0;
if (ySection === 1)
ySection = directions[i] % 2 ? 2 : 0;
}
if (xSection == 0 && ySection == 0) {
if (xSection === 0 && ySection === 0) {
diff[0] = bounds.x - iCenter[0];
diff[1] = bounds.y - iCenter[1];
}
if (xSection == 2 && ySection == 0) {
if (xSection === 2 && ySection === 0) {
diff[0] = bounds.x + bounds.width - iCenter[0];
diff[1] = bounds.y - iCenter[1];
}
if (xSection == 2 && ySection == 2) {
if (xSection === 2 && ySection === 2) {
diff[0] = bounds.x + bounds.width - iCenter[0];
diff[1] = bounds.y + bounds.height - iCenter[1];
}
if (xSection == 0 && ySection == 2) {
if (xSection === 0 && ySection === 2) {
diff[0] = bounds.x - iCenter[0];
diff[1] = bounds.y + bounds.height - iCenter[1];
}
if (diff[0] != 0 || diff[1] != 0) {
let length = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]);
if (diff[0] !== 0 || diff[1] !== 0) {
length = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]);
diff[0] *= WINDOW_PLACEMENT_NATURAL_ACCURACY / length / 2; // /2 to make it less influencing than the normal center-move above
diff[1] *= WINDOW_PLACEMENT_NATURAL_ACCURACY / length / 2;
rects[i].translate(diff[0], diff[1]);
@@ -203,28 +205,31 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
// Work out scaling by getting the most top-left and most bottom-right window coords.
let scale;
scale = Math.min(areaRect.width / bounds.width,
areaRect.height / bounds.height,
1.0);
scale = Math.min(
areaRect.width / bounds.width,
areaRect.height / bounds.height,
1.0);
// Make bounding rect fill the screen size for later steps
bounds.x = bounds.x - (areaRect.width - bounds.width * scale) / 2;
bounds.y = bounds.y - (areaRect.height - bounds.height * scale) / 2;
bounds.x -= (areaRect.width - bounds.width * scale) / 2;
bounds.y -= (areaRect.height - bounds.height * scale) / 2;
bounds.width = areaRect.width / scale;
bounds.height = areaRect.height / scale;
// Move all windows back onto the screen and set their scale
for (let i = 0; i < rects.length; i++) {
for (let i = 0; i < rects.length; i++)
rects[i].translate(-bounds.x, -bounds.y);
}
// rescale to workspace
let slots = [];
for (let i = 0; i < rects.length; i++) {
rects[i].x = rects[i].x * scale + areaRect.x;
rects[i].y = rects[i].y * scale + areaRect.y;
rects[i].width *= scale;
rects[i].height *= scale;
slots.push([rects[i].x, rects[i].y, scale, clones[i]]);
slots.push([rects[i].x, rects[i].y, rects[i].width, rects[i].height, clones[i]]);
}
return slots;
@@ -243,24 +248,37 @@ function enable() {
let settings = ExtensionUtils.getSettings();
workspaceInjections['_getBestLayout'] = Workspace.Workspace.prototype._getBestLayout;
Workspace.Workspace.prototype._getBestLayout = function(windows) {
let strategy = new NaturalLayoutStrategy(settings);
let layout = { strategy };
strategy.computeLayout(windows, layout);
return layout;
workspaceInjections['_createBestLayout'] = Workspace.WorkspaceLayout.prototype._createBestLayout;
Workspace.WorkspaceLayout.prototype._createBestLayout = function (_area) {
this._layoutStrategy = new NaturalLayoutStrategy({
monitor: Main.layoutManager.monitors[this._monitorIndex],
}, settings);
return this._layoutStrategy.computeLayout(this._sortedWindows);
};
/// position window titles on top of windows in overlay ////
winInjections['relayout'] = Workspace.WindowOverlay.prototype.relayout;
Workspace.WindowOverlay.prototype.relayout = function(animate) {
if (settings.get_boolean('window-captions-on-top')) {
let [, , , cloneHeight] = this._windowClone.slot;
this.title.translation_y = -cloneHeight;
}
// position window titles on top of windows in overlay
winInjections['_init'] = WindowPreview.prototype._init;
WindowPreview.prototype._init = function (...args) {
winInjections['_init'].call(this, ...args);
winInjections['relayout'].call(this, animate);
if (!settings.get_boolean('window-captions-on-top'))
return;
const alignConstraint = this._title.get_constraints().find(
c => c.align_axis && c.align_axis === Clutter.AlignAxis.Y_AXIS);
alignConstraint.factor = 0;
const bindConstraint = this._title.get_constraints().find(
c => c.coordinate && c.coordinate === Clutter.BindCoordinate.Y);
bindConstraint.offset = 0;
};
winInjections['_adjustOverlayOffsets'] =
WindowPreview.prototype._adjustOverlayOffsets;
WindowPreview.prototype._adjustOverlayOffsets = function (...args) {
winInjections['_adjustOverlayOffsets'].call(this, ...args);
if (settings.get_boolean('window-captions-on-top'))
this._title.translation_y = -this._title.translation_y;
};
}
@@ -275,9 +293,9 @@ function disable() {
var i;
for (i in workspaceInjections)
removeInjection(Workspace.Workspace.prototype, workspaceInjections, i);
removeInjection(Workspace.WorkspaceLayout.prototype, workspaceInjections, i);
for (i in winInjections)
removeInjection(Workspace.WindowOverlay.prototype, winInjections, i);
removeInjection(WindowPreview.prototype, winInjections, i);
global.stage.queue_relayout();
resetState();

View File

@@ -3,6 +3,7 @@
const { Clutter, GObject, St } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
@@ -11,38 +12,47 @@ const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const N_ = x => x;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const PlaceDisplay = Me.imports.placeDisplay;
const PLACE_ICON_SIZE = 16;
var PlaceMenuItem = GObject.registerClass(
class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(info) {
super();
_init(info) {
super._init({
style_class: 'place-menu-item',
});
this._info = info;
this._icon = new St.Icon({
gicon: info.icon,
icon_size: PLACE_ICON_SIZE
icon_size: PLACE_ICON_SIZE,
});
this.actor.add_child(this._icon);
this.add_child(this._icon);
this._label = new St.Label({ text: info.name, x_expand: true });
this.actor.add_child(this._label);
this._label = new St.Label({
text: info.name,
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this._label);
if (info.isRemovable()) {
this._ejectIcon = new St.Icon({
icon_name: 'media-eject-symbolic',
style_class: 'popup-menu-icon'
style_class: 'popup-menu-icon',
});
this._ejectButton = new St.Button({
child: this._ejectIcon,
style_class: 'button',
});
this._ejectButton = new St.Button({ child: this._ejectIcon });
this._ejectButton.connect('clicked', info.eject.bind(info));
this.actor.add_child(this._ejectButton);
this.add_child(this._ejectButton);
}
this._changedId = info.connect('changed',
this._propertiesChanged.bind(this));
this._propertiesChanged.bind(this));
}
destroy() {
@@ -64,13 +74,13 @@ class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem {
this._icon.gicon = info.icon;
this._label.text = info.name;
}
}
});
const SECTIONS = [
'special',
'devices',
'bookmarks',
'network'
'network',
];
let PlacesMenu = GObject.registerClass(
@@ -78,15 +88,12 @@ class PlacesMenu extends PanelMenu.Button {
_init() {
super._init(0.0, _('Places'));
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
let label = new St.Label({
text: _('Places'),
y_expand: true,
y_align: Clutter.ActorAlign.CENTER
y_align: Clutter.ActorAlign.CENTER,
});
hbox.add_child(label);
hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
this.add_actor(hbox);
this.add_actor(label);
this.placesManager = new PlaceDisplay.PlacesManager();
@@ -133,11 +140,11 @@ function init() {
let _indicator;
function enable() {
_indicator = new PlacesMenu;
_indicator = new PlacesMenu();
let pos = 1;
let pos = Main.sessionMode.panel.left.indexOf('appMenu');
if ('apps-menu' in Main.panel.statusArea)
pos = 2;
pos++;
Main.panel.addToStatusArea('places-menu', _indicator, pos, 'left');
}

View File

@@ -20,8 +20,8 @@ const Hostname1Iface = '<node> \
const Hostname1 = Gio.DBusProxy.makeProxyWrapper(Hostname1Iface);
class PlaceInfo {
constructor() {
this._init.apply(this, arguments);
constructor(...params) {
this._init(...params);
}
_init(kind, file, name, icon) {
@@ -41,14 +41,14 @@ class PlaceInfo {
async _ensureMountAndLaunch(context, tryMount) {
try {
await this._launchDefaultForUri(this.file.get_uri(), context, null);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_MOUNTED)) {
Main.notifyError(_('Failed to launch “%s”').format(this.name), e.message);
} catch (err) {
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_MOUNTED)) {
Main.notifyError(_('Failed to launch “%s”').format(this.name), err.message);
return;
}
let source = {
get_icon: () => this.icon
get_icon: () => this.icon,
};
let op = new ShellMountOperation.ShellMountOperation(source);
try {
@@ -71,18 +71,21 @@ class PlaceInfo {
}
getIcon() {
this.file.query_info_async('standard::symbolic-icon', 0, 0, null,
(file, result) => {
try {
let info = file.query_info_finish(result);
this.icon = info.get_symbolic_icon();
this.emit('changed');
} catch (e) {
if (e instanceof Gio.IOErrorEnum)
return;
throw e;
}
});
this.file.query_info_async('standard::symbolic-icon',
Gio.FileQueryInfoFlags.NONE,
0,
null,
(file, result) => {
try {
let info = file.query_info_finish(result);
this.icon = info.get_symbolic_icon();
this.emit('changed');
} catch (e) {
if (e instanceof Gio.IOErrorEnum)
return;
throw e;
}
});
// return a generic icon for this kind for now, until we have the
// icon from the query info above
@@ -152,7 +155,7 @@ class RootInfo extends PlaceInfo {
this._proxy = obj;
this._proxy.connect('g-properties-changed',
this._propertiesChanged.bind(this));
this._propertiesChanged.bind(this));
this._propertiesChanged(obj);
});
}
@@ -191,22 +194,23 @@ class PlaceDeviceInfo extends PlaceInfo {
}
isRemovable() {
return this._mount.can_eject();
return this._mount.can_eject() || this._mount.can_unmount();
}
eject() {
let unmountArgs = [
Gio.MountUnmountFlags.NONE,
(new ShellMountOperation.ShellMountOperation(this._mount)).mountOp,
null // Gio.Cancellable
new ShellMountOperation.ShellMountOperation(this._mount).mountOp,
null, // Gio.Cancellable
];
if (this._mount.can_eject())
if (this._mount.can_eject()) {
this._mount.eject_with_operation(...unmountArgs,
this._ejectFinish.bind(this));
else
this._ejectFinish.bind(this));
} else {
this._mount.unmount_with_operation(...unmountArgs,
this._unmountFinish.bind(this));
this._unmountFinish.bind(this));
}
}
_ejectFinish(mount, result) {
@@ -275,9 +279,8 @@ var PlacesManager = class {
};
this._settings = new Gio.Settings({ schema_id: BACKGROUND_SCHEMA });
this._showDesktopIconsChangedId =
this._settings.connect('changed::show-desktop-icons',
this._updateSpecials.bind(this));
this._showDesktopIconsChangedId = this._settings.connect(
'changed::show-desktop-icons', this._updateSpecials.bind(this));
this._updateSpecials();
/*
@@ -319,7 +322,7 @@ var PlacesManager = class {
'mount-changed',
'drive-connected',
'drive-disconnected',
'drive-changed'
'drive-changed',
];
this._volumeMonitorSignals = [];
@@ -350,9 +353,10 @@ var PlacesManager = class {
let homePath = GLib.get_home_dir();
this._places.special.push(new PlaceInfo('special',
Gio.File.new_for_path(homePath),
_('Home')));
this._places.special.push(new PlaceInfo(
'special',
Gio.File.new_for_path(homePath),
_('Home')));
let specials = [];
let dirs = DEFAULT_DIRECTORIES.slice();
@@ -362,7 +366,7 @@ var PlacesManager = class {
for (let i = 0; i < dirs.length; i++) {
let specialPath = GLib.get_user_special_dir(dirs[i]);
if (specialPath == null || specialPath == homePath)
if (!specialPath || specialPath === homePath)
continue;
let file = Gio.File.new_for_path(specialPath), info;
@@ -394,10 +398,11 @@ var PlacesManager = class {
/* Add standard places */
this._places.devices.push(new RootInfo());
this._places.network.push(new PlaceInfo('network',
Gio.File.new_for_uri('network:///'),
_('Browse Network'),
'network-workgroup-symbolic'));
this._places.network.push(new PlaceInfo(
'network',
Gio.File.new_for_uri('network:///'),
_('Browse Network'),
'network-workgroup-symbolic'));
/* first go through all connected drives */
let drives = this._volumeMonitor.get_connected_drives();
@@ -410,7 +415,7 @@ var PlacesManager = class {
networkVolumes.push(volumes[j]);
} else {
let mount = volumes[j].get_mount();
if (mount != null)
if (mount)
this._addMount('devices', mount);
}
}
@@ -419,7 +424,7 @@ var PlacesManager = class {
/* add all volumes that is not associated with a drive */
let volumes = this._volumeMonitor.get_volumes();
for (let i = 0; i < volumes.length; i++) {
if (volumes[i].get_drive() != null)
if (volumes[i].get_drive())
continue;
let identifier = volumes[i].get_identifier('class');
@@ -427,7 +432,7 @@ var PlacesManager = class {
networkVolumes.push(volumes[i]);
} else {
let mount = volumes[i].get_mount();
if (mount != null)
if (mount)
this._addMount('devices', mount);
}
}
@@ -458,9 +463,9 @@ var PlacesManager = class {
this._addVolume('network', networkVolumes[i]);
}
for (let i = 0; i < networkMounts.length; i++) {
for (let i = 0; i < networkMounts.length; i++)
this._addMount('network', networkMounts[i]);
}
this.emit('devices-updated');
this.emit('network-updated');
@@ -481,7 +486,6 @@ var PlacesManager = class {
}
_reloadBookmarks() {
this._bookmarks = [];
let content = Shell.get_file_contents_utf8_sync(this._bookmarksFile.get_path());
@@ -491,7 +495,7 @@ var PlacesManager = class {
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
let components = line.split(' ');
let bookmark = components[0];
let [bookmark] = components;
if (!bookmark)
continue;
@@ -501,16 +505,16 @@ var PlacesManager = class {
continue;
let duplicate = false;
for (let i = 0; i < this._places.special.length; i++) {
if (file.equal(this._places.special[i].file)) {
for (let j = 0; j < this._places.special.length; j++) {
if (file.equal(this._places.special[j].file)) {
duplicate = true;
break;
}
}
if (duplicate)
continue;
for (let i = 0; i < bookmarks.length; i++) {
if (file.equal(bookmarks[i].file)) {
for (let j = 0; j < bookmarks.length; j++) {
if (file.equal(bookmarks[j].file)) {
duplicate = true;
break;
}

View File

@@ -1 +1,8 @@
/* none used*/
.place-menu-item .button {
border-radius: 99px;
padding: 3px;
min-height: auto;
}
.place-menu-item .button:ltr { margin-left: 6px; }
.place-menu-item .button:rtl { margin-right: 6px; }

View File

@@ -19,14 +19,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
const { Meta, Shell, St } = imports.gi;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const { Clutter, Meta, Shell, St } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const MESSAGE_FADE_TIME = 2;
const MESSAGE_FADE_TIME = 2000;
let text;
@@ -41,20 +39,21 @@ function flashMessage(message) {
Main.uiGroup.add_actor(text);
}
Tweener.removeTweens(text);
text.remove_all_transitions();
text.text = message;
text.opacity = 255;
let monitor = Main.layoutManager.primaryMonitor;
text.set_position(monitor.x + Math.floor(monitor.width / 2 - text.width / 2),
monitor.y + Math.floor(monitor.height / 2 - text.height / 2));
text.set_position(
monitor.x + Math.floor(monitor.width / 2 - text.width / 2),
monitor.y + Math.floor(monitor.height / 2 - text.height / 2));
Tweener.addTween(text, {
text.ease({
opacity: 0,
time: MESSAGE_FADE_TIME,
transition: 'easeOutQuad',
onComplete: hideMessage
duration: MESSAGE_FADE_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: hideMessage,
});
}
@@ -63,17 +62,19 @@ let SIZES = [
[800, 450],
[1024, 576],
[1200, 675],
[1600, 900]
[1600, 900],
[360, 654], // Phone portrait maximized
[720, 360], // Phone landscape fullscreen
];
function cycleScreenshotSizes(display, window, binding) {
// Probably this isn't useful with 5 sizes, but you can decrease instead
// of increase by holding down shift.
let modifiers = binding.get_modifiers();
let backwards = (modifiers & Meta.VirtualModifier.SHIFT_MASK) != 0;
let backwards = (modifiers & Meta.VirtualModifier.SHIFT_MASK) !== 0;
// Unmaximize first
if (window.get_maximized() != 0)
if (window.get_maximized() !== 0)
window.unmaximize(Meta.MaximizeFlags.BOTH);
let workArea = window.get_work_area_current_monitor();
@@ -81,7 +82,8 @@ function cycleScreenshotSizes(display, window, binding) {
// Double both axes if on a hidpi display
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let scaledSizes = SIZES.map(size => size.map(wh => wh * scaleFactor));
let scaledSizes = SIZES.map(size => size.map(wh => wh * scaleFactor))
.filter(([w, h]) => w <= workArea.width && h <= workArea.height);
// Find the nearest 16:9 size for the current window size
let nearestIndex;
@@ -96,7 +98,7 @@ function cycleScreenshotSizes(display, window, binding) {
// get the best initial window size
let error = Math.abs(width - outerRect.width) + Math.abs(height - outerRect.height);
if (nearestIndex == null || error < nearestError) {
if (nearestIndex === undefined || error < nearestError) {
nearestIndex = i;
nearestError = error;
}
@@ -104,10 +106,7 @@ function cycleScreenshotSizes(display, window, binding) {
// get the next size up or down from ideal
let newIndex = (nearestIndex + (backwards ? -1 : 1)) % scaledSizes.length;
let newWidth, newHeight;
[newWidth, newHeight] = scaledSizes[newIndex];
if (newWidth > workArea.width || newHeight > workArea.height)
[newWidth, newHeight] = scaledSizes[0];
let [newWidth, newHeight] = scaledSizes[newIndex];
// Push the window onscreen if it would be resized offscreen
let newX = outerRect.x;
@@ -121,13 +120,13 @@ function cycleScreenshotSizes(display, window, binding) {
let newOuterRect = window.get_frame_rect();
let message = '%d×%d'.format(
(newOuterRect.width / scaleFactor),
(newOuterRect.height / scaleFactor));
newOuterRect.width / scaleFactor,
newOuterRect.height / scaleFactor);
// The new size might have been constrained by geometry hints (e.g. for
// a terminal) - in that case, include the actual ratio to the message
// we flash
let actualNumerator = (newOuterRect.width / newOuterRect.height) * 9;
let actualNumerator = 9 * newOuterRect.width / newOuterRect.height;
if (Math.abs(actualNumerator - 16) > 0.01)
message += ' (%.2f:9)'.format(actualNumerator);
@@ -135,17 +134,18 @@ function cycleScreenshotSizes(display, window, binding) {
}
function enable() {
Main.wm.addKeybinding('cycle-screenshot-sizes',
ExtensionUtils.getSettings(),
Meta.KeyBindingFlags.PER_WINDOW,
Shell.ActionMode.NORMAL,
cycleScreenshotSizes);
Main.wm.addKeybinding('cycle-screenshot-sizes-backward',
ExtensionUtils.getSettings(),
Meta.KeyBindingFlags.PER_WINDOW |
Meta.KeyBindingFlags.IS_REVERSED,
Shell.ActionMode.NORMAL,
cycleScreenshotSizes);
Main.wm.addKeybinding(
'cycle-screenshot-sizes',
ExtensionUtils.getSettings(),
Meta.KeyBindingFlags.PER_WINDOW,
Shell.ActionMode.NORMAL,
cycleScreenshotSizes);
Main.wm.addKeybinding(
'cycle-screenshot-sizes-backward',
ExtensionUtils.getSettings(),
Meta.KeyBindingFlags.PER_WINDOW | Meta.KeyBindingFlags.IS_REVERSED,
Shell.ActionMode.NORMAL,
cycleScreenshotSizes);
}
function disable() {

View File

@@ -2,12 +2,15 @@
// Load shell theme from ~/.local/share/themes/name/gnome-shell
/* exported init */
const { Gio, GLib } = imports.gi;
const Main = imports.ui.main;
const SETTINGS_KEY = 'name';
const { Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;
const SETTINGS_KEY = 'name';
class ThemeManager {
constructor() {
@@ -34,13 +37,11 @@ class ThemeManager {
let themeName = this._settings.get_string(SETTINGS_KEY);
if (themeName) {
let stylesheetPaths = [
[GLib.get_home_dir(), '.themes'],
[GLib.get_user_data_dir(), 'themes'],
...GLib.get_system_data_dirs().map(dir => [dir, 'themes'])
].map(themeDir => GLib.build_filenamev([
...themeDir, themeName, 'gnome-shell', 'gnome-shell.css'
]));
const stylesheetPaths = Util.getThemeDirs()
.map(dir => `${dir}/${themeName}/gnome-shell/gnome-shell.css`);
stylesheetPaths.push(...Util.getModeThemeDirs()
.map(dir => `${dir}/${themeName}.css`));
stylesheet = stylesheetPaths.find(path => {
let file = Gio.file_new_for_path(path);

View File

@@ -4,4 +4,5 @@ extension_data += configure_file(
configuration: metadata_conf
)
extension_sources += files('prefs.js', 'util.js')
extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')

View File

@@ -0,0 +1,182 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */
// we use async/await here to not block the mainloop, not to parallelize
/* eslint-disable no-await-in-loop */
const { Gio, GLib, GObject, Gtk } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;
Gio._promisify(Gio._LocalFilePrototype,
'enumerate_children_async', 'enumerate_children_finish');
Gio._promisify(Gio._LocalFilePrototype,
'query_info_async', 'query_info_finish');
Gio._promisify(Gio.FileEnumerator.prototype,
'next_files_async', 'next_files_finish');
const UserThemePrefsWidget = GObject.registerClass(
class UserThemePrefsWidget extends Gtk.ScrolledWindow {
_init() {
super._init({
hscrollbar_policy: Gtk.PolicyType.NEVER,
});
const box = new Gtk.Box();
this.set_child(box);
this._list = new Gtk.ListBox({
selection_mode: Gtk.SelectionMode.NONE,
show_separators: true,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
hexpand: true,
margin_start: 60,
margin_end: 60,
margin_top: 60,
margin_bottom: 60,
});
this._list.get_style_context().add_class('frame');
box.append(this._list);
this._actionGroup = new Gio.SimpleActionGroup();
this._list.insert_action_group('theme', this._actionGroup);
this._settings = ExtensionUtils.getSettings();
this._actionGroup.add_action(
this._settings.create_action('name'));
this.connect('destroy', () => this._settings.run_dispose());
this._rows = new Map();
this._addTheme(''); // default
this._collectThemes();
}
async _collectThemes() {
for (const dirName of Util.getThemeDirs()) {
const dir = Gio.File.new_for_path(dirName);
for (const name of await this._enumerateDir(dir)) {
if (this._rows.has(name))
continue;
const file = dir.resolve_relative_path(
`${name}/gnome-shell/gnome-shell.css`);
try {
await file.query_info_async(
Gio.FILE_ATTRIBUTE_STANDARD_NAME,
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT, null);
this._addTheme(name);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
logError(e);
}
}
}
for (const dirName of Util.getModeThemeDirs()) {
const dir = Gio.File.new_for_path(dirName);
for (const filename of await this._enumerateDir(dir)) {
if (!filename.endsWith('.css'))
continue;
const name = filename.slice(0, -4);
if (!this._rows.has(name))
this._addTheme(name);
}
}
}
_addTheme(name) {
const row = new ThemeRow(name, this._settings);
this._rows.set(name, row);
this._list.append(row);
}
async _enumerateDir(dir) {
const fileInfos = [];
let fileEnum;
try {
fileEnum = await dir.enumerate_children_async(
Gio.FILE_ATTRIBUTE_STANDARD_NAME,
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT, null);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
logError(e);
return [];
}
let infos;
do {
infos = await fileEnum.next_files_async(100,
GLib.PRIORITY_DEFAULT, null);
fileInfos.push(...infos);
} while (infos.length > 0);
return fileInfos.map(info => info.get_name());
}
});
const ThemeRow = GObject.registerClass(
class ThemeRow extends Gtk.ListBoxRow {
_init(name, settings) {
this._name = name;
this._settings = settings;
const box = new Gtk.Box({
spacing: 12,
margin_start: 12,
margin_end: 12,
margin_top: 12,
margin_bottom: 12,
});
super._init({
action_name: 'theme.name',
action_target: new GLib.Variant('s', name),
child: box,
});
box.append(new Gtk.Label({
label: name || 'Default',
hexpand: true,
xalign: 0,
max_width_chars: 25,
width_chars: 25,
}));
this._checkmark = new Gtk.Image({
icon_name: 'emblem-ok-symbolic',
pixel_size: 16,
});
box.append(this._checkmark);
const id = this._settings.connect('changed::name',
this._syncCheckmark.bind(this));
this._syncCheckmark();
this.connect('destroy', () => {
this._settings.disconnect(id);
this._settings = null;
});
}
_syncCheckmark() {
const visible = this._name === this._settings.get_string('name');
this._checkmark.opacity = visible ? 1. : 0;
}
});
function init() {
}
function buildPrefsWidget() {
return new UserThemePrefsWidget();
}

View File

@@ -0,0 +1,17 @@
/* exported getThemeDirs getModeThemeDirs */
const { GLib } = imports.gi;
const fn = (...args) => GLib.build_filenamev(args);
function getThemeDirs() {
return [
fn(GLib.get_home_dir(), '.themes'),
fn(GLib.get_user_data_dir(), 'themes'),
...GLib.get_system_data_dirs().map(dir => fn(dir, 'themes')),
];
}
function getModeThemeDirs() {
return GLib.get_system_data_dirs()
.map(dir => fn(dir, 'gnome-shell', 'theme'));
}

View File

@@ -4,36 +4,39 @@
border-top-width: 1px;
border-bottom-width: 0px;
height: 2.25em ;
padding: 2px;
}
.bottom-panel .window-button > StWidget,
.bottom-panel .window-picker-toggle > StWidget {
color: #2e3436;
background-color: #eee;
border-radius: 3px;
padding: 3px 6px 1px;
box-shadow: none;
text-shadow: none;
border: 1px solid rgba(0,0,0,0.2);
}
.bottom-panel .window-button > StWidget {
background-gradient-drection: vertical;
background-color: #fff;
background-gradient-start: #fff;
background-gradient-end: #eee;
color: #000;
-st-natural-width: 18.7em;
max-width: 18.75em;
color: #2e3436;
background-color: #eee;
border-radius: 2px;
padding: 3px 6px 1px;
box-shadow: inset -1px -1px 1px rgba(0,0,0,0.5);
text-shadow: 0 0 transparent;
}
.bottom-panel .window-button:hover > StWidget {
.bottom-panel .window-button:hover > StWidget,
.bottom-panel .window-picker-toggle:hover > StWidget {
background-color: #f9f9f9;
}
.bottom-panel .window-button:active > StWidget,
.bottom-panel .window-button:focus > StWidget {
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.5);
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.bottom-panel .window-button.focused > StWidget {
background-color: #ddd;
box-shadow: inset 1px 1px 1px rgba(0,0,0,0.5);
.bottom-panel .window-button.focused > StWidget,
.bottom-panel .window-picker-toggle:checked > StWidget {
background-color: #ccc;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.bottom-panel .window-button.focused:hover > StWidget {
@@ -42,5 +45,24 @@
.bottom-panel .window-button.minimized > StWidget {
color: #888;
box-shadow: inset -1px -1px 1px rgba(0,0,0,0.5);
box-shadow: none;
}
/* workspace switcher */
.window-list-workspace-indicator .workspace {
border: 2px solid #f6f5f4;
background-color: #ccc;
}
.window-list-workspace-indicator .workspace.active {
border-color: #888;
}
.window-list-window-preview {
background-color: #ededed;
border: 1px solid #ccc;
}
.window-list-window-preview.active {
background-color: #f6f5f4;
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ extension_data += configure_file(
configuration: metadata_conf
)
extension_sources += files('prefs.js')
extension_sources += files('prefs.js', 'windowPicker.js', 'workspaceIndicator.js')
extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
if classic_mode_enabled

View File

@@ -15,6 +15,13 @@
window list. Possible values are “never”, “auto” and “always”.
</description>
</key>
<key name="display-all-workspaces" type="b">
<default>false</default>
<summary>Show windows from all workspaces</summary>
<description>
Whether to show windows from all workspaces or only the current one.
</description>
</key>
<key name="show-on-all-monitors" type="b">
<default>false</default>
<summary>Show the window list on all monitors</summary>

View File

@@ -14,29 +14,40 @@ function init() {
}
const WindowListPrefsWidget = GObject.registerClass(
class WindowListPrefsWidget extends Gtk.Grid {
_init(params) {
super._init(params);
this.margin = 24;
this.row_spacing = 6;
this.orientation = Gtk.Orientation.VERTICAL;
class WindowListPrefsWidget extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 6,
margin_top: 36,
margin_bottom: 36,
margin_start: 36,
margin_end: 36,
halign: Gtk.Align.CENTER,
});
let groupingLabel = '<b>%s</b>'.format(_('Window Grouping'));
this.add(new Gtk.Label({
this.append(new Gtk.Label({
label: groupingLabel, use_markup: true,
halign: Gtk.Align.START
halign: Gtk.Align.START,
}));
let align = new Gtk.Alignment({ left_padding: 12 });
this.add(align);
let grid = new Gtk.Grid({
const box = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
row_spacing: 6,
column_spacing: 6
spacing: 12,
margin_bottom: 12,
});
align.add(grid);
this.append(box);
const context = box.get_style_context();
const cssProvider = new Gtk.CssProvider();
cssProvider.load_from_data(
'box { padding: 12px; }');
context.add_provider(cssProvider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
context.add_class('frame');
context.add_class('view');
this._settings = ExtensionUtils.getSettings();
let currentMode = this._settings.get_string('grouping-mode');
@@ -46,10 +57,11 @@ class WindowListPrefsWidget extends Gtk.Grid {
let modeLabels = {
'never': _('Never group windows'),
'auto': _('Group windows when space is limited'),
'always': _('Always group windows')
'always': _('Always group windows'),
};
let radio = null;
let currentRadio = null;
for (let i = 0; i < modes.length; i++) {
let mode = modes[i];
let label = modeLabels[mode];
@@ -58,12 +70,16 @@ class WindowListPrefsWidget extends Gtk.Grid {
continue;
}
radio = new Gtk.RadioButton({
active: currentMode == mode,
label: label,
group: radio
radio = new Gtk.CheckButton({
active: !i,
label,
group: radio,
margin_end: 12,
});
grid.add(radio);
box.append(radio);
if (currentMode === mode)
currentRadio = radio;
radio.connect('toggled', button => {
if (button.active)
@@ -71,18 +87,23 @@ class WindowListPrefsWidget extends Gtk.Grid {
});
}
if (currentRadio)
currentRadio.active = true;
let check = new Gtk.CheckButton({
label: _('Show on all monitors'),
margin_top: 6
});
this._settings.bind('show-on-all-monitors', check, 'active', Gio.SettingsBindFlags.DEFAULT);
this.add(check);
this.append(check);
check = new Gtk.CheckButton({
label: _('Show windows from all workspaces'),
});
this._settings.bind('display-all-workspaces', check, 'active', Gio.SettingsBindFlags.DEFAULT);
this.append(check);
}
});
function buildPrefsWidget() {
let widget = new WindowListPrefsWidget();
widget.show_all();
return widget;
return new WindowListPrefsWidget();
}

View File

@@ -1,10 +1,3 @@
.bottom-panel {
/* .window-button-icon height +
.window-button vertical padding +
.window-button > StWidget vertical padding) */
height: 2.25em;
}
.window-list {
spacing: 2px;
font-size: 10pt;
@@ -26,18 +19,31 @@
spacing: 4px;
}
.window-button > StWidget {
-st-natural-width: 18.75em;
max-width: 18.75em;
.window-button > StWidget,
.window-picker-toggle > StWidget {
color: #bbb;
background-color: black;
border-radius: 4px;
border-radius: 2px;
padding: 3px 6px 1px;
box-shadow: inset 1px 1px 4px rgba(255,255,255,0.5);
text-shadow: 1px 1px 4px rgba(0,0,0,0.8);
}
.window-button:hover > StWidget {
.window-picker-toggle {
padding: 3px;
}
.window-picker-toggle > StWidet {
border: 1px solid rgba(255,255,255,0.3);
}
.window-button > StWidget {
-st-natural-width: 18.75em;
max-width: 18.75em;
}
.window-button:hover > StWidget,
.window-picker-toggle:hover > StWidget {
color: white;
background-color: #1f1f1f;
}
@@ -47,12 +53,14 @@
box-shadow: inset 2px 2px 4px rgba(255,255,255,0.5);
}
.window-button.focused > StWidget {
.window-button.focused > StWidget,
.window-picker-toggle:checked > StWidget {
color: white;
box-shadow: inset 1px 1px 4px rgba(255,255,255,0.7);
}
.window-button.focused:active > StWidget {
.window-button.focused:active > StWidget,
.window-picker-toggle:checked:active > StWidget {
box-shadow: inset 2px 2px 4px rgba(255,255,255,0.7);
}
@@ -70,13 +78,36 @@
height: 24px;
}
.window-list-workspace-indicator {
.window-list-workspace-indicator .status-label-bin {
background-color: rgba(200, 200, 200, .3);
border: 1px solid #cccccc;
padding: 0 3px;
margin: 3px 0;
}
.window-list-workspace-indicator .workspaces-box {
spacing: 3px;
padding: 3px;
}
.window-list-workspace-indicator > StWidget {
background-color: rgba(200, 200, 200, .3);
border: 1px solid #cccccc;
.window-list-workspace-indicator .workspace {
border: 2px solid #000;
width: 52px;
border-radius: 4px;
background-color: #595959;
}
.window-list-workspace-indicator .workspace.active {
border-color: #fff;
}
.window-list-window-preview {
background-color: #bebebe;
border: 1px solid #828282;
}
.window-list-window-preview.active {
background-color: #d4d4d4;
}
.notification {

View File

@@ -0,0 +1,344 @@
/* exported WindowPicker, WindowPickerToggle */
const { Clutter, GObject, Shell, St } = imports.gi;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const { WorkspacesDisplay } = imports.ui.workspacesView;
const Workspace = imports.ui.workspace;
const { VIGNETTE_BRIGHTNESS } = imports.ui.lightbox;
const {
SIDE_CONTROLS_ANIMATION_TIME,
OverviewAdjustment,
ControlsState,
} = imports.ui.overviewControls;
let MyWorkspacesDisplay = GObject.registerClass(
class MyWorkspacesDisplay extends WorkspacesDisplay {
_init(controls, overviewAdjustment) {
let workspaceManager = global.workspace_manager;
this._overviewAdjustment = overviewAdjustment;
this._workspaceAdjustment = new St.Adjustment({
value: workspaceManager.get_active_workspace_index(),
lower: 0,
page_increment: 1,
page_size: 1,
step_increment: 0,
upper: workspaceManager.n_workspaces,
});
this._nWorkspacesChangedId =
workspaceManager.connect('notify::n-workspaces',
this._updateAdjustment.bind(this));
super._init(controls, this._workspaceAdjustment, this._overviewAdjustment);
this._workspaceAdjustment.actor = this;
this.add_constraint(
new Layout.MonitorConstraint({
primary: true,
work_area: true,
}));
}
prepareToEnterOverview(...args) {
if (!this._scrollEventId) {
this._scrollEventId = Main.windowPicker.connect('scroll-event',
this._onScrollEvent.bind(this));
}
super.prepareToEnterOverview(...args);
}
vfunc_hide(...args) {
if (this._scrollEventId > 0)
Main.windowPicker.disconnect(this._scrollEventId);
this._scrollEventId = 0;
super.vfunc_hide(...args);
}
_updateAdjustment() {
let workspaceManager = global.workspace_manager;
this._workspaceAdjustment.set({
upper: workspaceManager.n_workspaces,
value: workspaceManager.get_active_workspace_index(),
});
}
_onDestroy() {
if (this._nWorkspacesChangedId)
global.workspace_manager.disconnect(this._nWorkspacesChangedId);
this._nWorkspacesChangedId = 0;
super._onDestroy();
}
});
const MyWorkspace = GObject.registerClass(
class MyWorkspace extends Workspace.Workspace {
_init(...args) {
super._init(...args);
this._adjChangedId =
this._overviewAdjustment.connect('notify::value', () => {
const { value: progress } = this._overviewAdjustment;
const brightness = 1 - (1 - VIGNETTE_BRIGHTNESS) * progress;
for (const bg of this._background?._backgroundGroup ?? []) {
bg.content.set({
vignette: true,
brightness,
});
}
});
}
_onDestroy() {
super._onDestroy();
if (this._adjChangedId)
this._overviewAdjustment.disconnect(this._adjChangedId);
this._adjChangedId = 0;
}
});
const MyWorkspaceBackground = GObject.registerClass(
class MyWorkspaceBackground extends Workspace.WorkspaceBackground {
_updateBorderRadius() {
}
vfunc_allocate(box) {
this.set_allocation(box);
const themeNode = this.get_theme_node();
const contentBox = themeNode.get_content_box(box);
this._bin.allocate(contentBox);
const [contentWidth, contentHeight] = contentBox.get_size();
const monitor = Main.layoutManager.monitors[this._monitorIndex];
const xRatio = contentWidth / this._workarea.width;
const yRatio = contentHeight / this._workarea.height;
const right = area => area.x + area.width;
const bottom = area => area.y + area.height;
const offsets = {
left: xRatio * (this._workarea.x - monitor.x),
right: xRatio * (right(monitor) - right(this._workarea)),
top: yRatio * (this._workarea.y - monitor.y),
bottom: yRatio * (bottom(monitor) - bottom(this._workarea)),
};
contentBox.set_origin(-offsets.left, -offsets.top);
contentBox.set_size(
offsets.left + contentWidth + offsets.right,
offsets.top + contentHeight + offsets.bottom);
this._backgroundGroup.allocate(contentBox);
}
});
var WindowPicker = GObject.registerClass({
Signals: {
'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
},
}, class extends Clutter.Actor {
_init() {
this._visible = false;
this._modal = false;
this._overlayKeyId = 0;
this._stageKeyPressId = 0;
super._init({ reactive: true });
this._adjustment = new OverviewAdjustment(this);
this.connect('destroy', this._onDestroy.bind(this));
global.bind_property('screen-width',
this, 'width',
GObject.BindingFlags.SYNC_CREATE);
global.bind_property('screen-height',
this, 'height',
GObject.BindingFlags.SYNC_CREATE);
this._workspacesDisplay = new MyWorkspacesDisplay(this, this._adjustment);
this.add_child(this._workspacesDisplay);
Main.uiGroup.insert_child_below(this, global.window_group);
if (!Main.sessionMode.hasOverview) {
this._injectBackgroundShade();
this._overlayKeyId = global.display.connect('overlay-key', () => {
if (!this._visible)
this.open();
else
this.close();
});
}
}
_injectBackgroundShade() {
this._origWorkspace = Workspace.Workspace;
this._origWorkspaceBackground = Workspace.WorkspaceBackground;
Workspace.Workspace = MyWorkspace;
Workspace.WorkspaceBackground = MyWorkspaceBackground;
}
get visible() {
return this._visible;
}
open() {
if (this._visible)
return;
this._visible = true;
if (!this._syncGrab())
return;
this._fakeOverviewVisible(true);
this._workspacesDisplay.prepareToEnterOverview();
Main.overview._animationInProgress = true;
this._adjustment.value = ControlsState.HIDDEN;
this._adjustment.ease(ControlsState.WINDOW_PICKER, {
duration: SIDE_CONTROLS_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => (Main.overview._animationInProgress = false),
});
this._stageKeyPressId = global.stage.connect('key-press-event',
(a, event) => {
let sym = event.get_key_symbol();
if (sym === Clutter.KEY_Escape) {
this.close();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
});
this.emit('open-state-changed', this._visible);
}
close() {
if (!this._visible)
return;
this._visible = false;
if (!this._syncGrab())
return;
this._workspacesDisplay.prepareToLeaveOverview();
Main.overview._animationInProgress = true;
this._adjustment.ease(ControlsState.HIDDEN, {
duration: SIDE_CONTROLS_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
Main.overview._animationInProgress = false;
this._workspacesDisplay.hide();
this._fakeOverviewVisible(false);
},
});
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
this.emit('open-state-changed', this._visible);
}
getWorkspacesBoxForState() {
return this.allocation;
}
_fakeOverviewVisible(visible) {
// Fake overview state for WorkspacesDisplay
Main.overview._visible = visible;
// Hide real windows
Main.layoutManager._inOverview = visible;
Main.layoutManager._updateVisibility();
}
_syncGrab() {
if (this._visible) {
if (this._modal)
return true;
this._modal = Main.pushModal(this, {
actionMode: Shell.ActionMode.OVERVIEW,
});
if (!this._modal) {
this.hide();
return false;
}
} else if (this._modal) {
Main.popModal(this);
this._modal = false;
}
return true;
}
_onDestroy() {
if (this._origWorkspace)
Workspace.Workspace = this._origWorkspace;
if (this._origWorkspaceBackground)
Workspace.WorkspaceBackground = this._origWorkspaceBackground;
if (this._monitorsChangedId)
Main.layoutManager.disconnect(this._monitorsChangedId);
this._monitorsChangedId = 0;
if (this._overlayKeyId)
global.display.disconnect(this._overlayKeyId);
this._overlayKeyId = 0;
if (this._stageKeyPressId)
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
}
});
var WindowPickerToggle = GObject.registerClass(
class WindowPickerToggle extends St.Button {
_init() {
let iconBin = new St.Widget({
layout_manager: new Clutter.BinLayout(),
});
iconBin.add_child(new St.Icon({
icon_name: 'focus-windows-symbolic',
icon_size: 16,
x_expand: true,
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
}));
super._init({
style_class: 'window-picker-toggle',
child: iconBin,
visible: !Main.sessionMode.hasOverview,
toggle_mode: true,
});
this.connect('notify::checked', () => {
if (this.checked)
Main.windowPicker.open();
else
Main.windowPicker.close();
});
Main.windowPicker.connect('open-state-changed', () => {
this.checked = Main.windowPicker.visible;
});
}
});

View File

@@ -0,0 +1,438 @@
/* exported WorkspaceIndicator */
const { Clutter, Gio, GObject, Meta, St } = imports.gi;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const TOOLTIP_OFFSET = 6;
const TOOLTIP_ANIMATION_TIME = 150;
const MAX_THUMBNAILS = 6;
let WindowPreview = GObject.registerClass(
class WindowPreview extends St.Button {
_init(window) {
super._init({
style_class: 'window-list-window-preview',
});
this._delegate = this;
DND.makeDraggable(this, { restoreOnSuccess: true });
this._window = window;
this.connect('destroy', this._onDestroy.bind(this));
this._sizeChangedId = this._window.connect('size-changed',
() => this.queue_relayout());
this._positionChangedId = this._window.connect('position-changed',
() => {
this._updateVisible();
this.queue_relayout();
});
this._minimizedChangedId = this._window.connect('notify::minimized',
this._updateVisible.bind(this));
this._focusChangedId = global.display.connect('notify::focus-window',
this._onFocusChanged.bind(this));
this._onFocusChanged();
}
// needed for DND
get metaWindow() {
return this._window;
}
_onDestroy() {
this._window.disconnect(this._sizeChangedId);
this._window.disconnect(this._positionChangedId);
this._window.disconnect(this._minimizedChangedId);
global.display.disconnect(this._focusChangedId);
}
_onFocusChanged() {
if (global.display.focus_window === this._window)
this.add_style_class_name('active');
else
this.remove_style_class_name('active');
}
_updateVisible() {
const monitor = Main.layoutManager.findIndexForActor(this);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
this.visible = this._window.get_frame_rect().overlap(workArea) &&
this._window.window_type !== Meta.WindowType.DESKTOP &&
this._window.showing_on_its_workspace();
}
});
let WorkspaceLayout = GObject.registerClass(
class WorkspaceLayout extends Clutter.LayoutManager {
vfunc_get_preferred_width() {
return [0, 0];
}
vfunc_get_preferred_height() {
return [0, 0];
}
vfunc_allocate(container, box) {
const monitor = Main.layoutManager.findIndexForActor(container);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
const hscale = box.get_width() / workArea.width;
const vscale = box.get_height() / workArea.height;
for (const child of container) {
const childBox = new Clutter.ActorBox();
const frameRect = child.metaWindow.get_frame_rect();
childBox.set_size(
Math.round(Math.min(frameRect.width, workArea.width) * hscale),
Math.round(Math.min(frameRect.height, workArea.height) * vscale));
childBox.set_origin(
Math.round((frameRect.x - workArea.x) * hscale),
Math.round((frameRect.y - workArea.y) * vscale));
child.allocate(childBox);
}
}
});
let WorkspaceThumbnail = GObject.registerClass(
class WorkspaceThumbnail extends St.Button {
_init(index) {
super._init({
style_class: 'workspace',
child: new Clutter.Actor({
layout_manager: new WorkspaceLayout(),
clip_to_allocation: true,
}),
});
this._tooltip = new St.Label({
style_class: 'dash-label',
visible: false,
});
Main.uiGroup.add_child(this._tooltip);
this.connect('destroy', this._onDestroy.bind(this));
this.connect('notify::hover', this._syncTooltip.bind(this));
this._index = index;
this._delegate = this; // needed for DND
this._windowPreviews = new Map();
let workspaceManager = global.workspace_manager;
this._workspace = workspaceManager.get_workspace_by_index(index);
this._windowAddedId = this._workspace.connect('window-added',
(ws, window) => {
this._addWindow(window);
});
this._windowRemovedId = this._workspace.connect('window-removed',
(ws, window) => {
this._removeWindow(window);
});
this._restackedId = global.display.connect('restacked',
this._onRestacked.bind(this));
this._workspace.list_windows().forEach(w => this._addWindow(w));
this._onRestacked();
}
acceptDrop(source) {
if (!source.metaWindow)
return false;
this._moveWindow(source.metaWindow);
return true;
}
handleDragOver(source) {
if (source.metaWindow)
return DND.DragMotionResult.MOVE_DROP;
else
return DND.DragMotionResult.CONTINUE;
}
_addWindow(window) {
if (this._windowPreviews.has(window))
return;
let preview = new WindowPreview(window);
preview.connect('clicked', (a, btn) => this.emit('clicked', btn));
this._windowPreviews.set(window, preview);
this.child.add_child(preview);
}
_removeWindow(window) {
let preview = this._windowPreviews.get(window);
if (!preview)
return;
this._windowPreviews.delete(window);
preview.destroy();
}
_onRestacked() {
let lastPreview = null;
let windows = global.get_window_actors().map(a => a.meta_window);
for (let i = 0; i < windows.length; i++) {
let preview = this._windowPreviews.get(windows[i]);
if (!preview)
continue;
this.child.set_child_above_sibling(preview, lastPreview);
lastPreview = preview;
}
}
_moveWindow(window) {
let monitorIndex = Main.layoutManager.findIndexForActor(this);
if (monitorIndex !== window.get_monitor())
window.move_to_monitor(monitorIndex);
window.change_workspace_by_index(this._index, false);
}
on_clicked() {
let ws = global.workspace_manager.get_workspace_by_index(this._index);
if (ws)
ws.activate(global.get_current_time());
}
_syncTooltip() {
if (this.hover) {
this._tooltip.set({
text: Meta.prefs_get_workspace_name(this._index),
visible: true,
opacity: 0,
});
const [stageX, stageY] = this.get_transformed_position();
const thumbWidth = this.allocation.get_width();
const tipWidth = this._tooltip.width;
const tipHeight = this._tooltip.height;
const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
const monitor = Main.layoutManager.findMonitorForActor(this);
const x = Math.clamp(
stageX + xOffset,
monitor.x,
monitor.x + monitor.width - tipWidth);
const y = stageY - tipHeight - TOOLTIP_OFFSET;
this._tooltip.set_position(x, y);
}
this._tooltip.ease({
opacity: this.hover ? 255 : 0,
duration: TOOLTIP_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => (this._tooltip.visible = this.hover),
});
}
_onDestroy() {
this._tooltip.destroy();
this._workspace.disconnect(this._windowAddedId);
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
}
});
var WorkspaceIndicator = GObject.registerClass(
class WorkspaceIndicator extends PanelMenu.Button {
_init() {
super._init(0.0, _('Workspace Indicator'), true);
this.setMenu(new PopupMenu.PopupMenu(this, 0.0, St.Side.BOTTOM));
this.add_style_class_name('window-list-workspace-indicator');
this.menu.actor.remove_style_class_name('panel-menu');
let container = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true,
});
this.add_actor(container);
let workspaceManager = global.workspace_manager;
this._currentWorkspace = workspaceManager.get_active_workspace_index();
this._statusLabel = new St.Label({ text: this._getStatusText() });
this._statusBin = new St.Bin({
style_class: 'status-label-bin',
x_expand: true,
y_expand: true,
child: this._statusLabel,
});
container.add_actor(this._statusBin);
this._thumbnailsBox = new St.BoxLayout({
style_class: 'workspaces-box',
y_expand: true,
reactive: true,
});
this._thumbnailsBox.connect('scroll-event',
this._onScrollEvent.bind(this));
container.add_actor(this._thumbnailsBox);
this._workspacesItems = [];
this._workspaceManagerSignals = [
workspaceManager.connect('notify::n-workspaces',
this._nWorkspacesChanged.bind(this)),
workspaceManager.connect_after('workspace-switched',
this._onWorkspaceSwitched.bind(this)),
workspaceManager.connect('notify::layout-rows',
this._updateThumbnailVisibility.bind(this)),
];
this.connect('scroll-event', this._onScrollEvent.bind(this));
this._updateMenu();
this._updateThumbnails();
this._updateThumbnailVisibility();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' });
this._settingsChangedId = this._settings.connect(
'changed::workspace-names', this._updateMenuLabels.bind(this));
}
_onDestroy() {
for (let i = 0; i < this._workspaceManagerSignals.length; i++)
global.workspace_manager.disconnect(this._workspaceManagerSignals[i]);
if (this._settingsChangedId) {
this._settings.disconnect(this._settingsChangedId);
this._settingsChangedId = 0;
}
super._onDestroy();
}
_updateThumbnailVisibility() {
const { workspaceManager } = global;
const vertical = workspaceManager.layout_rows === -1;
const useMenu =
vertical || workspaceManager.n_workspaces > MAX_THUMBNAILS;
this.reactive = useMenu;
this._statusBin.visible = useMenu;
this._thumbnailsBox.visible = !useMenu;
}
_onWorkspaceSwitched() {
let workspaceManager = global.workspace_manager;
this._currentWorkspace = workspaceManager.get_active_workspace_index();
this._updateMenuOrnament();
this._updateActiveThumbnail();
this._statusLabel.set_text(this._getStatusText());
}
_nWorkspacesChanged() {
this._updateMenu();
this._updateThumbnails();
this._updateThumbnailVisibility();
}
_updateMenuOrnament() {
for (let i = 0; i < this._workspacesItems.length; i++) {
this._workspacesItems[i].setOrnament(i === this._currentWorkspace
? PopupMenu.Ornament.DOT
: PopupMenu.Ornament.NONE);
}
}
_updateActiveThumbnail() {
let thumbs = this._thumbnailsBox.get_children();
for (let i = 0; i < thumbs.length; i++) {
if (i === this._currentWorkspace)
thumbs[i].add_style_class_name('active');
else
thumbs[i].remove_style_class_name('active');
}
}
_getStatusText() {
let workspaceManager = global.workspace_manager;
let current = workspaceManager.get_active_workspace_index();
let total = workspaceManager.n_workspaces;
return '%d / %d'.format(current + 1, total);
}
_updateMenuLabels() {
for (let i = 0; i < this._workspacesItems.length; i++) {
let item = this._workspacesItems[i];
let name = Meta.prefs_get_workspace_name(i);
item.label.text = name;
}
}
_updateMenu() {
let workspaceManager = global.workspace_manager;
this.menu.removeAll();
this._workspacesItems = [];
this._currentWorkspace = workspaceManager.get_active_workspace_index();
for (let i = 0; i < workspaceManager.n_workspaces; i++) {
let name = Meta.prefs_get_workspace_name(i);
let item = new PopupMenu.PopupMenuItem(name);
item.workspaceId = i;
item.connect('activate', () => {
this._activate(item.workspaceId);
});
if (i === this._currentWorkspace)
item.setOrnament(PopupMenu.Ornament.DOT);
this.menu.addMenuItem(item);
this._workspacesItems[i] = item;
}
this._statusLabel.set_text(this._getStatusText());
}
_updateThumbnails() {
let workspaceManager = global.workspace_manager;
this._thumbnailsBox.destroy_all_children();
for (let i = 0; i < workspaceManager.n_workspaces; i++) {
let thumb = new WorkspaceThumbnail(i);
this._thumbnailsBox.add_actor(thumb);
}
this._updateActiveThumbnail();
}
_activate(index) {
let workspaceManager = global.workspace_manager;
if (index >= 0 && index < workspaceManager.n_workspaces) {
let metaWorkspace = workspaceManager.get_workspace_by_index(index);
metaWorkspace.activate(global.get_current_time());
}
}
_onScrollEvent(actor, event) {
let direction = event.get_scroll_direction();
let diff = 0;
if (direction === Clutter.ScrollDirection.DOWN)
diff = 1;
else if (direction === Clutter.ScrollDirection.UP)
diff = -1;
else
return;
let newIndex = this._currentWorkspace + diff;
this._activate(newIndex);
}
});

View File

@@ -1,144 +1,178 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* exported enable disable */
const { Clutter, St } = imports.gi;
/* exported init */
const { Clutter, Graphene, GObject, St } = imports.gi;
const Main = imports.ui.main;
const OverviewControls = imports.ui.overviewControls;
const Workspace = imports.ui.workspace;
const WorkspacesView = imports.ui.workspacesView;
function injectToFunction(parent, name, func) {
let origin = parent[name];
parent[name] = function() {
let ret;
ret = origin.apply(this, arguments);
if (ret === undefined)
ret = func.apply(this, arguments);
return ret;
};
return origin;
}
const WINDOW_SLOT = 4;
let winInjections, workspaceInjections, workViewInjections, createdActors, connectedSignals;
var MyWorkspace = GObject.registerClass(
class MyWorkspace extends Workspace.Workspace {
_init(...args) {
super._init(...args);
function resetState() {
winInjections = {};
workspaceInjections = {};
workViewInjections = {};
createdActors = [];
connectedSignals = [];
}
if (this.metaWorkspace && this.metaWorkspace.index() < 9) {
this._tip = new St.Label({
style_class: 'extension-windowsNavigator-window-tooltip',
visible: false,
});
this.add_actor(this._tip);
function enable() {
resetState();
this.connect('notify::scale-x', () => {
this._tip.set_scale(1 / this.scale_x, 1 / this.scale_x);
});
} else {
this._tip = null;
}
}
Workspace.WindowOverlay.prototype.showTooltip = function() {
this._text.raise_top();
this._text.show();
this._text.text = (this._windowClone.slotId + 1).toString();
};
winInjections['showTooltip'] = undefined;
vfunc_allocate(box) {
super.vfunc_allocate(box);
Workspace.WindowOverlay.prototype.hideTooltip = function() {
if (this._text && this._text.visible)
this._text.hide();
};
winInjections['hideTooltip'] = undefined;
if (this._tip)
this._tip.allocate_preferred_size(0, 0);
}
Workspace.Workspace.prototype.showTooltip = function() {
if (this._tip == null || this._actualGeometry == null)
showTooltip() {
if (!this._tip)
return;
this._tip.text = (this.metaWorkspace.index() + 1).toString();
this._tip.show();
this.set_child_below_sibling(this._tip, null);
}
// Hand code this instead of using _getSpacingAndPadding
// because that fails on empty workspaces
let node = this.actor.get_theme_node();
let padding = {
left: node.get_padding(St.Side.LEFT),
top: node.get_padding(St.Side.TOP),
bottom: node.get_padding(St.Side.BOTTOM),
right: node.get_padding(St.Side.RIGHT),
hideTooltip() {
if (this._tip)
this._tip.hide();
}
getWindowWithTooltip(id) {
const { layoutManager } = this._container;
const slot = layoutManager._windowSlots[id - 1];
return slot ? slot[WINDOW_SLOT].metaWindow : null;
}
showWindowsTooltips() {
const { layoutManager } = this._container;
for (let i = 0; i < layoutManager._windowSlots.length; i++) {
if (layoutManager._windowSlots[i])
layoutManager._windowSlots[i][WINDOW_SLOT].showTooltip(`${i + 1}`);
}
}
hideWindowsTooltips() {
const { layoutManager } = this._container;
for (let i in layoutManager._windowSlots) {
if (layoutManager._windowSlots[i])
layoutManager._windowSlots[i][WINDOW_SLOT].hideTooltip();
}
}
// overriding _addWindowClone to apply the tooltip patch on the cloned
// windowPreview
_addWindowClone(metaWindow) {
const clone = super._addWindowClone(metaWindow);
// appling the tooltip patch
(function patchPreview() {
this._text = new St.Label({
style_class: 'extension-windowsNavigator-window-tooltip',
visible: false,
});
this._text.add_constraint(new Clutter.BindConstraint({
source: this.windowContainer,
coordinate: Clutter.BindCoordinate.POSITION,
}));
this._text.add_constraint(new Clutter.AlignConstraint({
source: this.windowContainer,
align_axis: Clutter.AlignAxis.X_AXIS,
pivot_point: new Graphene.Point({ x: 0.5, y: -1 }),
factor: this._closeButtonSide === St.Side.LEFT ? 1 : 0,
}));
this._text.add_constraint(new Clutter.AlignConstraint({
source: this.windowContainer,
align_axis: Clutter.AlignAxis.Y_AXIS,
pivot_point: new Graphene.Point({ x: -1, y: 0.5 }),
factor: 0,
}));
this.add_child(this._text);
}).call(clone);
clone.showTooltip = function (text) {
this._text.set({ text });
this._text.show();
};
let area = Workspace.padArea(this._actualGeometry, padding);
this._tip.x = area.x;
this._tip.y = area.y;
this._tip.show();
this._tip.raise_top();
};
workspaceInjections['showTooltip'] = undefined;
clone.hideTooltip = function () {
if (this._text && this._text.visible)
this._text.hide();
};
Workspace.Workspace.prototype.hideTooltip = function() {
if (this._tip == null)
return;
if (!this._tip.get_parent())
return;
this._tip.hide();
};
workspaceInjections['hideTooltip'] = undefined;
return clone;
}
});
Workspace.Workspace.prototype.getWindowWithTooltip = function(id) {
for (let i = 0; i < this._windows.length; i++) {
if ((this._windows[i].slotId + 1) == id)
return this._windows[i].metaWindow;
}
return null;
};
workspaceInjections['getWindowWithTooltip'] = undefined;
var MyWorkspacesView = GObject.registerClass(
class MyWorkspacesView extends WorkspacesView.WorkspacesView {
_init(...args) {
super._init(...args);
Workspace.Workspace.prototype.showWindowsTooltips = function() {
for (let i in this._windowOverlays) {
if (this._windowOverlays[i] != null)
this._windowOverlays[i].showTooltip();
}
};
workspaceInjections['showWindowsTooltips'] = undefined;
this._pickWorkspace = false;
this._pickWindow = false;
this._keyPressEventId =
global.stage.connect('key-press-event', this._onKeyPress.bind(this));
this._keyReleaseEventId =
global.stage.connect('key-release-event', this._onKeyRelease.bind(this));
}
Workspace.Workspace.prototype.hideWindowsTooltips = function() {
for (let i in this._windowOverlays) {
if (this._windowOverlays[i] != null)
this._windowOverlays[i].hideTooltip();
}
};
workspaceInjections['hideWindowsTooltips'] = undefined;
_onDestroy() {
super._onDestroy();
WorkspacesView.WorkspacesView.prototype._hideTooltips = function() {
if (global.stage.get_key_focus() == global.stage)
global.stage.disconnect(this._keyPressEventId);
global.stage.disconnect(this._keyReleaseEventId);
}
_hideTooltips() {
if (global.stage.get_key_focus() === global.stage)
global.stage.set_key_focus(this._prevFocusActor);
this._pickWindow = false;
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].hideWindowsTooltips();
};
workViewInjections['_hideTooltips'] = undefined;
}
WorkspacesView.WorkspacesView.prototype._hideWorkspacesTooltips = function() {
_hideWorkspacesTooltips() {
global.stage.set_key_focus(this._prevFocusActor);
this._pickWorkspace = false;
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].hideTooltip();
};
workViewInjections['_hideWorkspacesTooltips'] = undefined;
}
WorkspacesView.WorkspacesView.prototype._onKeyRelease = function(s, o) {
_onKeyRelease(s, o) {
if (this._pickWindow &&
(o.get_key_symbol() == Clutter.KEY_Alt_L ||
o.get_key_symbol() == Clutter.KEY_Alt_R))
(o.get_key_symbol() === Clutter.KEY_Alt_L ||
o.get_key_symbol() === Clutter.KEY_Alt_R))
this._hideTooltips();
if (this._pickWorkspace &&
(o.get_key_symbol() == Clutter.KEY_Control_L ||
o.get_key_symbol() == Clutter.KEY_Control_R))
(o.get_key_symbol() === Clutter.KEY_Control_L ||
o.get_key_symbol() === Clutter.KEY_Control_R))
this._hideWorkspacesTooltips();
};
workViewInjections['_onKeyRelease'] = undefined;
}
WorkspacesView.WorkspacesView.prototype._onKeyPress = function(s, o) {
if (Main.overview.viewSelector._activePage != Main.overview.viewSelector._workspacesPage)
_onKeyPress(s, o) {
const { ControlsState } = OverviewControls;
if (this._overviewAdjustment.value !== ControlsState.WINDOW_PICKER)
return false;
let workspaceManager = global.workspace_manager;
if ((o.get_key_symbol() == Clutter.KEY_Alt_L ||
o.get_key_symbol() == Clutter.KEY_Alt_R)
&& !this._pickWorkspace) {
if ((o.get_key_symbol() === Clutter.KEY_Alt_L ||
o.get_key_symbol() === Clutter.KEY_Alt_R) &&
!this._pickWorkspace) {
this._prevFocusActor = global.stage.get_key_focus();
global.stage.set_key_focus(null);
this._active = workspaceManager.get_active_workspace_index();
@@ -146,9 +180,9 @@ function enable() {
this._workspaces[workspaceManager.get_active_workspace_index()].showWindowsTooltips();
return true;
}
if ((o.get_key_symbol() == Clutter.KEY_Control_L ||
o.get_key_symbol() == Clutter.KEY_Control_R)
&& !this._pickWindow) {
if ((o.get_key_symbol() === Clutter.KEY_Control_L ||
o.get_key_symbol() === Clutter.KEY_Control_R) &&
!this._pickWindow) {
this._prevFocusActor = global.stage.get_key_focus();
global.stage.set_key_focus(null);
this._pickWorkspace = true;
@@ -157,17 +191,17 @@ function enable() {
return true;
}
if (global.stage.get_key_focus() != global.stage)
if (global.stage.get_key_focus() !== global.stage)
return false;
// ignore shift presses, they're required to get numerals in azerty keyboards
if ((this._pickWindow || this._pickWorkspace) &&
(o.get_key_symbol() == Clutter.KEY_Shift_L ||
o.get_key_symbol() == Clutter.KEY_Shift_R))
(o.get_key_symbol() === Clutter.KEY_Shift_L ||
o.get_key_symbol() === Clutter.KEY_Shift_R))
return true;
if (this._pickWindow) {
if (this._active != workspaceManager.get_active_workspace_index()) {
if (this._active !== workspaceManager.get_active_workspace_index()) {
this._hideTooltips();
return false;
}
@@ -208,81 +242,26 @@ function enable() {
return true;
}
return false;
};
workViewInjections['_onKeyPress'] = undefined;
}
});
winInjections['_init'] = injectToFunction(Workspace.WindowOverlay.prototype, '_init', function(windowClone, parentActor) {
this._id = null;
createdActors.push(this._text = new St.Label({ style_class: 'extension-windowsNavigator-window-tooltip' }));
this._text.hide();
parentActor.add_actor(this._text);
});
class Extension {
constructor() {
this._origWorkspace = Workspace.Workspace;
this._origWorkspacesView = WorkspacesView.WorkspacesView;
}
winInjections['relayout'] = injectToFunction(Workspace.WindowOverlay.prototype, 'relayout', function(_animate) {
let [cloneX, cloneY, cloneWidth_, cloneHeight_] = this._windowClone.slot;
enable() {
Workspace.Workspace = MyWorkspace;
WorkspacesView.WorkspacesView = MyWorkspacesView;
}
let textX = cloneX - 2;
let textY = cloneY - 2;
this._text.set_position(Math.floor(textX) + 5, Math.floor(textY) + 5);
this._text.raise_top();
});
workspaceInjections['_init'] = injectToFunction(Workspace.Workspace.prototype, '_init', function(metaWorkspace) {
if (metaWorkspace && metaWorkspace.index() < 9) {
createdActors.push(this._tip = new St.Label({
style_class: 'extension-windowsNavigator-window-tooltip',
visible: false
}));
this.actor.add_actor(this._tip);
let signalId = this.actor.connect('notify::scale-x', () => {
this._tip.set_scale(1 / this.actor.scale_x, 1 / this.actor.scale_x);
});
connectedSignals.push({ obj: this.actor, id: signalId });
} else
this._tip = null;
});
workViewInjections['_init'] = injectToFunction(WorkspacesView.WorkspacesView.prototype, '_init', function(_width, _height, _x, _y, _workspaces) {
this._pickWorkspace = false;
this._pickWindow = false;
this._keyPressEventId =
global.stage.connect('key-press-event', this._onKeyPress.bind(this));
this._keyReleaseEventId =
global.stage.connect('key-release-event', this._onKeyRelease.bind(this));
connectedSignals.push({ obj: global.stage, id: this._keyPressEventId });
connectedSignals.push({ obj: global.stage, id: this._keyReleaseEventId });
});
workViewInjections['_onDestroy'] = injectToFunction(WorkspacesView.WorkspacesView.prototype, '_onDestroy', function() {
global.stage.disconnect(this._keyPressEventId);
global.stage.disconnect(this._keyReleaseEventId);
connectedSignals = [];
});
disable() {
Workspace.Workspace = this._origWorkspace;
WorkspacesView.WorkspacesView = this._origWorkspacesView;
}
}
function removeInjection(object, injection, name) {
if (injection[name] === undefined)
delete object[name];
else
object[name] = injection[name];
}
function disable() {
let i;
for (i in workspaceInjections)
removeInjection(Workspace.Workspace.prototype, workspaceInjections, i);
for (i in winInjections)
removeInjection(Workspace.WindowOverlay.prototype, winInjections, i);
for (i in workViewInjections)
removeInjection(WorkspacesView.WorkspacesView.prototype, workViewInjections, i);
for (i of connectedSignals)
i.obj.disconnect(i.id);
for (i of createdActors)
i.destroy();
resetState();
function init() {
return new Extension();
}

View File

@@ -2,56 +2,307 @@
/* exported init enable disable */
const { Clutter, Gio, GObject, Meta, St } = imports.gi;
const DND = imports.ui.dnd;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const Main = imports.ui.main;
const ExtensionUtils = imports.misc.extensionUtils;
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
const WORKSPACE_KEY = 'workspace-names';
const TOOLTIP_OFFSET = 6;
const TOOLTIP_ANIMATION_TIME = 150;
const MAX_THUMBNAILS = 6;
let WindowPreview = GObject.registerClass(
class WindowPreview extends St.Button {
_init(window) {
super._init({
style_class: 'workspace-indicator-window-preview',
});
this._delegate = this;
DND.makeDraggable(this, { restoreOnSuccess: true });
this._window = window;
this.connect('destroy', this._onDestroy.bind(this));
this._sizeChangedId = this._window.connect('size-changed',
() => this.queue_relayout());
this._positionChangedId = this._window.connect('position-changed',
() => {
this._updateVisible();
this.queue_relayout();
});
this._minimizedChangedId = this._window.connect('notify::minimized',
this._updateVisible.bind(this));
this._focusChangedId = global.display.connect('notify::focus-window',
this._onFocusChanged.bind(this));
this._onFocusChanged();
}
// needed for DND
get metaWindow() {
return this._window;
}
_onDestroy() {
this._window.disconnect(this._sizeChangedId);
this._window.disconnect(this._positionChangedId);
this._window.disconnect(this._minimizedChangedId);
global.display.disconnect(this._focusChangedId);
}
_onFocusChanged() {
if (global.display.focus_window === this._window)
this.add_style_class_name('active');
else
this.remove_style_class_name('active');
}
_updateVisible() {
const monitor = Main.layoutManager.findIndexForActor(this);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
this.visible = this._window.get_frame_rect().overlap(workArea) &&
this._window.window_type !== Meta.WindowType.DESKTOP &&
this._window.showing_on_its_workspace();
}
});
let WorkspaceLayout = GObject.registerClass(
class WorkspaceLayout extends Clutter.LayoutManager {
vfunc_get_preferred_width() {
return [0, 0];
}
vfunc_get_preferred_height() {
return [0, 0];
}
vfunc_allocate(container, box) {
const monitor = Main.layoutManager.findIndexForActor(container);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
const hscale = box.get_width() / workArea.width;
const vscale = box.get_height() / workArea.height;
for (const child of container) {
const childBox = new Clutter.ActorBox();
const frameRect = child.metaWindow.get_frame_rect();
childBox.set_size(
Math.round(Math.min(frameRect.width, workArea.width) * hscale),
Math.round(Math.min(frameRect.height, workArea.height) * vscale));
childBox.set_origin(
Math.round((frameRect.x - workArea.x) * hscale),
Math.round((frameRect.y - workArea.y) * vscale));
child.allocate(childBox);
}
}
});
let WorkspaceThumbnail = GObject.registerClass(
class WorkspaceThumbnail extends St.Button {
_init(index) {
super._init({
style_class: 'workspace',
child: new Clutter.Actor({
layout_manager: new WorkspaceLayout(),
clip_to_allocation: true,
}),
});
this._tooltip = new St.Label({
style_class: 'dash-label',
visible: false,
});
Main.uiGroup.add_child(this._tooltip);
this.connect('destroy', this._onDestroy.bind(this));
this.connect('notify::hover', this._syncTooltip.bind(this));
this._index = index;
this._delegate = this; // needed for DND
this._windowPreviews = new Map();
let workspaceManager = global.workspace_manager;
this._workspace = workspaceManager.get_workspace_by_index(index);
this._windowAddedId = this._workspace.connect('window-added',
(ws, window) => {
this._addWindow(window);
});
this._windowRemovedId = this._workspace.connect('window-removed',
(ws, window) => {
this._removeWindow(window);
});
this._restackedId = global.display.connect('restacked',
this._onRestacked.bind(this));
this._workspace.list_windows().forEach(w => this._addWindow(w));
this._onRestacked();
}
acceptDrop(source) {
if (!source.metaWindow)
return false;
this._moveWindow(source.metaWindow);
return true;
}
handleDragOver(source) {
if (source.metaWindow)
return DND.DragMotionResult.MOVE_DROP;
else
return DND.DragMotionResult.CONTINUE;
}
_addWindow(window) {
if (this._windowPreviews.has(window))
return;
let preview = new WindowPreview(window);
preview.connect('clicked', (a, btn) => this.emit('clicked', btn));
this._windowPreviews.set(window, preview);
this.child.add_child(preview);
}
_removeWindow(window) {
let preview = this._windowPreviews.get(window);
if (!preview)
return;
this._windowPreviews.delete(window);
preview.destroy();
}
_onRestacked() {
let lastPreview = null;
let windows = global.get_window_actors().map(a => a.meta_window);
for (let i = 0; i < windows.length; i++) {
let preview = this._windowPreviews.get(windows[i]);
if (!preview)
continue;
this.child.set_child_above_sibling(preview, lastPreview);
lastPreview = preview;
}
}
_moveWindow(window) {
let monitorIndex = Main.layoutManager.findIndexForActor(this);
if (monitorIndex !== window.get_monitor())
window.move_to_monitor(monitorIndex);
window.change_workspace_by_index(this._index, false);
}
on_clicked() {
let ws = global.workspace_manager.get_workspace_by_index(this._index);
if (ws)
ws.activate(global.get_current_time());
}
_syncTooltip() {
if (this.hover) {
this._tooltip.set({
text: Meta.prefs_get_workspace_name(this._index),
visible: true,
opacity: 0,
});
const [stageX, stageY] = this.get_transformed_position();
const thumbWidth = this.allocation.get_width();
const thumbHeight = this.allocation.get_height();
const tipWidth = this._tooltip.width;
const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
const monitor = Main.layoutManager.findMonitorForActor(this);
const x = Math.clamp(
stageX + xOffset,
monitor.x,
monitor.x + monitor.width - tipWidth);
const y = stageY + thumbHeight + TOOLTIP_OFFSET;
this._tooltip.set_position(x, y);
}
this._tooltip.ease({
opacity: this.hover ? 255 : 0,
duration: TOOLTIP_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => (this._tooltip.visible = this.hover),
});
}
_onDestroy() {
this._tooltip.destroy();
this._workspace.disconnect(this._windowAddedId);
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
}
});
let WorkspaceIndicator = GObject.registerClass(
class WorkspaceIndicator extends PanelMenu.Button {
_init() {
super._init(0.0, _('Workspace Indicator'));
let container = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true,
});
this.add_actor(container);
let workspaceManager = global.workspace_manager;
this._currentWorkspace = workspaceManager.get_active_workspace().index();
this.statusLabel = new St.Label({
this._currentWorkspace = workspaceManager.get_active_workspace_index();
this._statusLabel = new St.Label({
style_class: 'panel-workspace-indicator',
y_align: Clutter.ActorAlign.CENTER,
text: this._labelText()
text: this._labelText(),
});
this.add_actor(this.statusLabel);
container.add_actor(this._statusLabel);
this.workspacesItems = [];
this._thumbnailsBox = new St.BoxLayout({
style_class: 'panel-workspace-indicator-box',
y_expand: true,
reactive: true,
});
container.add_actor(this._thumbnailsBox);
this._workspacesItems = [];
this._workspaceSection = new PopupMenu.PopupMenuSection();
this.menu.addMenuItem(this._workspaceSection);
this._workspaceManagerSignals = [];
this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-added',
this._createWorkspacesSection.bind(this)));
this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-removed',
this._createWorkspacesSection.bind(this)));
this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-switched',
this._updateIndicator.bind(this)));
this._workspaceManagerSignals = [
workspaceManager.connect_after('notify::n-workspaces',
this._nWorkspacesChanged.bind(this)),
workspaceManager.connect_after('workspace-switched',
this._onWorkspaceSwitched.bind(this)),
workspaceManager.connect('notify::layout-rows',
this._updateThumbnailVisibility.bind(this)),
];
this.connect('scroll-event', this._onScrollEvent.bind(this));
this._thumbnailsBox.connect('scroll-event', this._onScrollEvent.bind(this));
this._createWorkspacesSection();
//styling
this.statusLabel.add_style_class_name('panel-workspace-indicator');
this._updateThumbnails();
this._updateThumbnailVisibility();
this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA });
this._settingsChangedId =
this._settings.connect(`changed::${WORKSPACE_KEY}`,
this._createWorkspacesSection.bind(this));
this._settingsChangedId = this._settings.connect(
`changed::${WORKSPACE_KEY}`,
this._updateMenuLabels.bind(this));
}
_onDestroy() {
@@ -63,53 +314,114 @@ class WorkspaceIndicator extends PanelMenu.Button {
this._settingsChangedId = 0;
}
Main.panel.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
super._onDestroy();
}
_updateIndicator() {
this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE);
this._currentWorkspace = global.workspace_manager.get_active_workspace().index();
this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT);
_updateThumbnailVisibility() {
const { workspaceManager } = global;
const vertical = workspaceManager.layout_rows === -1;
const useMenu =
vertical || workspaceManager.n_workspaces > MAX_THUMBNAILS;
this.reactive = useMenu;
this.statusLabel.set_text(this._labelText());
this._statusLabel.visible = useMenu;
this._thumbnailsBox.visible = !useMenu;
// Disable offscreen-redirect when showing the workspace switcher
// so that clip-to-allocation works
Main.panel.set_offscreen_redirect(useMenu
? Clutter.OffscreenRedirect.ALWAYS
: Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY);
}
_onWorkspaceSwitched() {
this._currentWorkspace = global.workspace_manager.get_active_workspace_index();
this._updateMenuOrnament();
this._updateActiveThumbnail();
this._statusLabel.set_text(this._labelText());
}
_nWorkspacesChanged() {
this._createWorkspacesSection();
this._updateThumbnails();
this._updateThumbnailVisibility();
}
_updateMenuOrnament() {
for (let i = 0; i < this._workspacesItems.length; i++) {
this._workspacesItems[i].setOrnament(i === this._currentWorkspace
? PopupMenu.Ornament.DOT
: PopupMenu.Ornament.NONE);
}
}
_updateActiveThumbnail() {
let thumbs = this._thumbnailsBox.get_children();
for (let i = 0; i < thumbs.length; i++) {
if (i === this._currentWorkspace)
thumbs[i].add_style_class_name('active');
else
thumbs[i].remove_style_class_name('active');
}
}
_labelText(workspaceIndex) {
if (workspaceIndex == undefined) {
if (workspaceIndex === undefined) {
workspaceIndex = this._currentWorkspace;
return (workspaceIndex + 1).toString();
}
return Meta.prefs_get_workspace_name(workspaceIndex);
}
_updateMenuLabels() {
for (let i = 0; i < this._workspacesItems.length; i++)
this._workspacesItems[i].label.text = this._labelText(i);
}
_createWorkspacesSection() {
let workspaceManager = global.workspace_manager;
this._workspaceSection.removeAll();
this.workspacesItems = [];
this._currentWorkspace = workspaceManager.get_active_workspace().index();
this._workspacesItems = [];
this._currentWorkspace = workspaceManager.get_active_workspace_index();
let i = 0;
for (; i < workspaceManager.n_workspaces; i++) {
this.workspacesItems[i] = new PopupMenu.PopupMenuItem(this._labelText(i));
this._workspaceSection.addMenuItem(this.workspacesItems[i]);
this.workspacesItems[i].workspaceId = i;
this.workspacesItems[i].label_actor = this.statusLabel;
this.workspacesItems[i].connect('activate', (actor, _event) => {
this._workspacesItems[i] = new PopupMenu.PopupMenuItem(this._labelText(i));
this._workspaceSection.addMenuItem(this._workspacesItems[i]);
this._workspacesItems[i].workspaceId = i;
this._workspacesItems[i].label_actor = this._statusLabel;
this._workspacesItems[i].connect('activate', (actor, _event) => {
this._activate(actor.workspaceId);
});
if (i == this._currentWorkspace)
this.workspacesItems[i].setOrnament(PopupMenu.Ornament.DOT);
if (i === this._currentWorkspace)
this._workspacesItems[i].setOrnament(PopupMenu.Ornament.DOT);
}
this.statusLabel.set_text(this._labelText());
this._statusLabel.set_text(this._labelText());
}
_updateThumbnails() {
let workspaceManager = global.workspace_manager;
this._thumbnailsBox.destroy_all_children();
for (let i = 0; i < workspaceManager.n_workspaces; i++) {
let thumb = new WorkspaceThumbnail(i);
this._thumbnailsBox.add_actor(thumb);
}
this._updateActiveThumbnail();
}
_activate(index) {
let workspaceManager = global.workspace_manager;
if (index >= 0 && index < workspaceManager.n_workspaces) {
if (index >= 0 && index < workspaceManager.n_workspaces) {
let metaWorkspace = workspaceManager.get_workspace_by_index(index);
metaWorkspace.activate(global.get_current_time());
}
@@ -118,15 +430,15 @@ class WorkspaceIndicator extends PanelMenu.Button {
_onScrollEvent(actor, event) {
let direction = event.get_scroll_direction();
let diff = 0;
if (direction == Clutter.ScrollDirection.DOWN) {
if (direction === Clutter.ScrollDirection.DOWN)
diff = 1;
} else if (direction == Clutter.ScrollDirection.UP) {
else if (direction === Clutter.ScrollDirection.UP)
diff = -1;
} else {
else
return;
}
let newIndex = global.workspace_manager.get_active_workspace().index() + diff;
let newIndex = global.workspace_manager.get_active_workspace_index() + diff;
this._activate(newIndex);
}
});
@@ -138,7 +450,7 @@ function init() {
let _indicator;
function enable() {
_indicator = new WorkspaceIndicator;
_indicator = new WorkspaceIndicator();
Main.panel.addToStatusArea('workspace-indicator', _indicator);
}

View File

@@ -1,7 +1,7 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */
const { Gio, GObject, Gtk } = imports.gi;
const { Gio, GLib, GObject, Gtk, Pango } = imports.gi;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
@@ -12,191 +12,200 @@ const ExtensionUtils = imports.misc.extensionUtils;
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
const WORKSPACE_KEY = 'workspace-names';
const WorkspaceNameModel = GObject.registerClass(
class WorkspaceNameModel extends Gtk.ListStore {
_init(params) {
super._init(params);
this.set_column_types([GObject.TYPE_STRING]);
const WorkspaceSettingsWidget = GObject.registerClass(
class WorkspaceSettingsWidget extends Gtk.ScrolledWindow {
_init() {
super._init({
hscrollbar_policy: Gtk.PolicyType.NEVER,
});
this.Columns = {
LABEL: 0,
};
const box = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
halign: Gtk.Align.CENTER,
spacing: 12,
margin_top: 36,
margin_bottom: 36,
margin_start: 36,
margin_end: 36,
});
this.set_child(box);
this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA });
//this._settings.connect('changed::workspace-names', this._reloadFromSettings.bind(this));
box.append(new Gtk.Label({
label: '<b>%s</b>'.format(_('Workspace Names')),
use_markup: true,
halign: Gtk.Align.START,
}));
this._reloadFromSettings();
this._list = new Gtk.ListBox({
selection_mode: Gtk.SelectionMode.NONE,
valign: Gtk.Align.START,
show_separators: true,
});
this._list.connect('row-activated', (l, row) => row.edit());
box.append(this._list);
// overriding class closure doesn't work, because GtkTreeModel
// plays tricks with marshallers and class closures
this.connect('row-changed', this._onRowChanged.bind(this));
this.connect('row-inserted', this._onRowInserted.bind(this));
this.connect('row-deleted', this._onRowDeleted.bind(this));
const context = this._list.get_style_context();
const cssProvider = new Gtk.CssProvider();
cssProvider.load_from_data(
'list { min-width: 25em; }');
context.add_provider(cssProvider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
context.add_class('frame');
this._list.append(new NewWorkspaceRow());
this._actionGroup = new Gio.SimpleActionGroup();
this._list.insert_action_group('workspaces', this._actionGroup);
let action;
action = new Gio.SimpleAction({ name: 'add' });
action.connect('activate', () => {
const names = this._settings.get_strv(WORKSPACE_KEY);
this._settings.set_strv(WORKSPACE_KEY, [
...names,
_('Workspace %d').format(names.length + 1),
]);
});
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'remove',
parameter_type: new GLib.VariantType('s'),
});
action.connect('activate', (a, param) => {
const removed = param.deepUnpack();
this._settings.set_strv(WORKSPACE_KEY,
this._settings.get_strv(WORKSPACE_KEY)
.filter(name => name !== removed));
});
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({ name: 'update' });
action.connect('activate', () => {
const names = this._getWorkspaceRows().map(row => row.name);
this._settings.set_strv(WORKSPACE_KEY, names);
});
this._actionGroup.add_action(action);
this._settings = new Gio.Settings({
schema_id: WORKSPACE_SCHEMA,
});
this._settings.connect(`changed::${WORKSPACE_KEY}`,
this._sync.bind(this));
this._sync();
}
_reloadFromSettings() {
if (this._preventChanges)
return;
this._preventChanges = true;
let newNames = this._settings.get_strv(WORKSPACE_KEY);
let i = 0;
let [ok, iter] = this.get_iter_first();
while (ok && i < newNames.length) {
this.set(iter, [this.Columns.LABEL], [newNames[i]]);
ok = this.iter_next(iter);
i++;
}
while (ok)
ok = this.remove(iter);
for ( ; i < newNames.length; i++) {
iter = this.append();
this.set(iter, [this.Columns.LABEL], [newNames[i]]);
}
this._preventChanges = false;
_getWorkspaceRows() {
return [...this._list].filter(row => row.name);
}
_onRowChanged(self, path, iter) {
if (this._preventChanges)
return;
this._preventChanges = true;
_sync() {
const rows = this._getWorkspaceRows();
let index = path.get_indices()[0];
let names = this._settings.get_strv(WORKSPACE_KEY);
const oldNames = rows.map(row => row.name);
const newNames = this._settings.get_strv(WORKSPACE_KEY);
if (index >= names.length) {
// fill with blanks
for (let i = names.length; i <= index; i++)
names[i] = '';
}
const removed = oldNames.filter(n => !newNames.includes(n));
const added = newNames.filter(n => !oldNames.includes(n));
names[index] = this.get_value(iter, this.Columns.LABEL);
this._settings.set_strv(WORKSPACE_KEY, names);
this._preventChanges = false;
}
_onRowInserted(self, path, iter) {
if (this._preventChanges)
return;
this._preventChanges = true;
let index = path.get_indices()[0];
let names = this._settings.get_strv(WORKSPACE_KEY);
let label = this.get_value(iter, this.Columns.LABEL) || '';
names.splice(index, 0, label);
this._settings.set_strv(WORKSPACE_KEY, names);
this._preventChanges = false;
}
_onRowDeleted(self, path) {
if (this._preventChanges)
return;
this._preventChanges = true;
let index = path.get_indices()[0];
let names = this._settings.get_strv(WORKSPACE_KEY);
if (index >= names.length)
return;
names.splice(index, 1);
// compact the array
for (let i = names.length - 1; i >= 0 && !names[i]; i++)
names.pop();
this._settings.set_strv(WORKSPACE_KEY, names);
this._preventChanges = false;
removed.forEach(n => this._list.remove(rows.find(r => r.name === n)));
added.forEach(n => {
this._list.insert(new WorkspaceRow(n), newNames.indexOf(n));
});
}
});
const WorkspaceSettingsWidget = GObject.registerClass(
class WorkspaceSettingsWidget extends Gtk.Grid {
_init(params) {
super._init(params);
this.margin = 12;
this.orientation = Gtk.Orientation.VERTICAL;
const WorkspaceRow = GObject.registerClass(
class WorkspaceRow extends Gtk.ListBoxRow {
_init(name) {
super._init({ name });
this.add(new Gtk.Label({
label: '<b>%s</b>'.format(_('Workspace Names')),
use_markup: true,
margin_bottom: 6,
hexpand: true,
halign: Gtk.Align.START
const controller = new Gtk.ShortcutController();
controller.add_shortcut(new Gtk.Shortcut({
trigger: Gtk.ShortcutTrigger.parse_string('Escape'),
action: Gtk.CallbackAction.new(this._stopEdit.bind(this)),
}));
this.add_controller(controller);
let scrolled = new Gtk.ScrolledWindow({ shadow_type: Gtk.ShadowType.IN });
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.add(scrolled);
const box = new Gtk.Box({
spacing: 12,
margin_top: 6,
margin_bottom: 6,
margin_start: 6,
margin_end: 6,
});
this._store = new WorkspaceNameModel();
this._treeView = new Gtk.TreeView({
model: this._store,
headers_visible: false,
reorderable: true,
const label = new Gtk.Label({
hexpand: true,
vexpand: true
xalign: 0,
max_width_chars: 25,
ellipsize: Pango.EllipsizeMode.END,
});
this.bind_property('name', label, 'label',
GObject.BindingFlags.SYNC_CREATE);
box.append(label);
const button = new Gtk.Button({
action_name: 'workspaces.remove',
action_target: new GLib.Variant('s', name),
icon_name: 'edit-delete-symbolic',
});
box.append(button);
this._entry = new Gtk.Entry({
max_width_chars: 25,
});
let column = new Gtk.TreeViewColumn({ title: _('Name') });
let renderer = new Gtk.CellRendererText({ editable: true });
renderer.connect('edited', this._cellEdited.bind(this));
column.pack_start(renderer, true);
column.add_attribute(renderer, 'text', this._store.Columns.LABEL);
this._treeView.append_column(column);
this._stack = new Gtk.Stack();
this._stack.add_named(box, 'display');
this._stack.add_named(this._entry, 'edit');
this.child = this._stack;
scrolled.add(this._treeView);
let toolbar = new Gtk.Toolbar({ icon_size: Gtk.IconSize.SMALL_TOOLBAR });
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
let newButton = new Gtk.ToolButton({ icon_name: 'list-add-symbolic' });
newButton.connect('clicked', this._newClicked.bind(this));
toolbar.add(newButton);
let delButton = new Gtk.ToolButton({ icon_name: 'list-remove-symbolic' });
delButton.connect('clicked', this._delClicked.bind(this));
toolbar.add(delButton);
let selection = this._treeView.get_selection();
selection.connect('changed', () => {
delButton.sensitive = selection.count_selected_rows() > 0;
this._entry.connect('activate', () => {
this.name = this._entry.text;
this._stopEdit();
});
this._entry.connect('notify::has-focus', () => {
if (this._entry.has_focus)
return;
this._stopEdit();
});
delButton.sensitive = selection.count_selected_rows() > 0;
this.add(toolbar);
this.connect('notify::name', () => {
button.action_target = new GLib.Variant('s', this.name);
this.activate_action('workspaces.update', null);
});
}
_cellEdited(renderer, path, newText) {
let [ok, iter] = this._store.get_iter_from_string(path);
if (ok)
this._store.set(iter, [this._store.Columns.LABEL], [newText]);
edit() {
this._entry.text = this.name;
this._entry.grab_focus();
this._stack.visible_child_name = 'edit';
}
_newClicked() {
let iter = this._store.append();
let index = this._store.get_path(iter).get_indices()[0];
let label = _('Workspace %d').format(index + 1);
this._store.set(iter, [this._store.Columns.LABEL], [label]);
_stopEdit() {
this.grab_focus();
this._stack.visible_child_name = 'display';
}
});
_delClicked() {
let [any, model_, iter] = this._treeView.get_selection().get_selected();
if (any)
this._store.remove(iter);
const NewWorkspaceRow = GObject.registerClass(
class NewWorkspaceRow extends Gtk.ListBoxRow {
_init() {
super._init({
action_name: 'workspaces.add',
child: new Gtk.Image({
icon_name: 'list-add-symbolic',
pixel_size: 16,
margin_top: 12,
margin_bottom: 12,
margin_start: 12,
margin_end: 12,
}),
});
this.update_property(
[Gtk.AccessibleProperty.LABEL], [_('Add Workspace')]);
}
});
@@ -205,8 +214,5 @@ function init() {
}
function buildPrefsWidget() {
let widget = new WorkspaceSettingsWidget();
widget.show_all();
return widget;
return new WorkspaceSettingsWidget();
}

View File

@@ -1,5 +1,28 @@
.panel-workspace-indicator {
padding: 0 8px;
background-color: rgba(200, 200, 200, .5);
border: 1px solid #cccccc;
padding: 0 8px;
}
.panel-workspace-indicator-box {
padding: 4px 0;
spacing: 4px;
}
.panel-workspace-indicator-box .workspace {
width: 40px;
border: 2px solid #000;
border-radius: 2px;
background-color: #595959;
}
.panel-workspace-indicator-box .workspace.active {
border-color: #fff;
}
.workspace-indicator-window-preview {
background-color: #bebebe;
border: 1px solid #828282;
}
.workspace-indicator-window-preview.active {
background-color: #d4d4d4;
}

View File

@@ -34,4 +34,10 @@ and will be picked automatically at next login.
<gnome:userid>fmuellner</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Marge Bot</foaf:name>
<gnome:userid>marge-bot</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@@ -1,130 +0,0 @@
{
"env": {
"es6": true
},
"extends": "eslint:recommended",
"rules": {
"array-bracket-newline": [
"error",
"consistent"
],
"array-bracket-spacing": [
"error",
"never"
],
"arrow-spacing": "error",
"brace-style": "error",
"comma-spacing": [
"error",
{
"before": false,
"after": true
}
],
"indent": [
"error",
4,
{
"ignoredNodes": [
"CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child"
],
"MemberExpression": "off"
}
],
"key-spacing": [
"error",
{
"beforeColon": false,
"afterColon": true
}
],
"keyword-spacing": [
"error",
{
"before": true,
"after": true
}
],
"linebreak-style": [
"error",
"unix"
],
"no-empty": [
"error",
{
"allowEmptyCatch": true
}
],
"no-implicit-coercion": [
"error",
{
"allow": ["!!"]
}
],
"no-restricted-properties": [
"error",
{
"object": "Lang",
"property": "bind",
"message": "Use arrow notation or Function.prototype.bind()"
},
{
"object": "Lang",
"property": "Class",
"message": "Use ES6 classes"
}
],
"nonblock-statement-body-position": [
"error",
"below"
],
"object-curly-newline": [
"error",
{
"consistent": true
}
],
"object-curly-spacing": "error",
"prefer-template": "error",
"quotes": [
"error",
"single",
{
"avoidEscape": true
}
],
"semi": [
"error",
"always"
],
"semi-spacing": [
"error",
{
"before": false,
"after": true
}
],
"space-before-blocks": "error",
"space-infix-ops": [
"error",
{
"int32Hint": false
}
]
},
"globals": {
"ARGV": false,
"Debugger": false,
"GIRepositoryGType": false,
"imports": false,
"Intl": false,
"log": false,
"logError": false,
"print": false,
"printerr": false,
"window": false
},
"parserOptions": {
"ecmaVersion": 2017
}
}

237
lint/eslintrc-gjs.yml Normal file
View File

@@ -0,0 +1,237 @@
---
# SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
env:
es6: true
extends: 'eslint:recommended'
rules:
array-bracket-newline:
- error
- consistent
array-bracket-spacing:
- error
- never
array-callback-return: error
arrow-parens:
- error
- as-needed
arrow-spacing: error
block-scoped-var: error
block-spacing: error
brace-style: error
# Waiting for this to have matured a bit in eslint
# camelcase:
# - error
# - properties: never
# allow: [^vfunc_, ^on_, _instance_init]
comma-dangle:
- error
- arrays: always-multiline
objects: always-multiline
functions: never
comma-spacing:
- error
- before: false
after: true
comma-style:
- error
- last
computed-property-spacing: error
curly:
- error
- multi-or-nest
- consistent
dot-location:
- error
- property
eol-last: error
eqeqeq: error
func-call-spacing: error
func-name-matching: error
func-style:
- error
- declaration
- allowArrowFunctions: true
indent:
- error
- 4
- ignoredNodes:
# Allow not indenting the body of GObject.registerClass, since in the
# future it's intended to be a decorator
- 'CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child'
# Allow dedenting chained member expressions
MemberExpression: 'off'
key-spacing:
- error
- beforeColon: false
afterColon: true
keyword-spacing:
- error
- before: true
after: true
linebreak-style:
- error
- unix
lines-between-class-members: error
max-nested-callbacks: error
max-statements-per-line: error
new-parens: error
no-array-constructor: error
no-await-in-loop: error
no-caller: error
no-constant-condition:
- error
- checkLoops: false
no-div-regex: error
no-empty:
- error
- allowEmptyCatch: true
no-extra-bind: error
no-extra-parens:
- error
- all
- conditionalAssign: false
nestedBinaryExpressions: false
returnAssign: false
no-implicit-coercion:
- error
- allow:
- '!!'
no-invalid-this: error
no-iterator: error
no-label-var: error
no-lonely-if: error
no-loop-func: error
no-nested-ternary: error
no-new-object: error
no-new-wrappers: error
no-octal-escape: error
no-proto: error
no-prototype-builtins: 'off'
no-restricted-properties:
- error
- object: Lang
property: copyProperties
message: Use Object.assign()
- object: Lang
property: bind
message: Use arrow notation or Function.prototype.bind()
- object: Lang
property: Class
message: Use ES6 classes
no-restricted-syntax:
- error
- selector: >-
MethodDefinition[key.name="_init"] >
FunctionExpression[params.length=1] >
BlockStatement[body.length=1]
CallExpression[arguments.length=1][callee.object.type="Super"][callee.property.name="_init"] >
Identifier:first-child
message: _init() that only calls super._init() is unnecessary
- selector: >-
MethodDefinition[key.name="_init"] >
FunctionExpression[params.length=0] >
BlockStatement[body.length=1]
CallExpression[arguments.length=0][callee.object.type="Super"][callee.property.name="_init"]
message: _init() that only calls super._init() is unnecessary
- selector: BinaryExpression[operator="instanceof"][right.name="Array"]
message: Use Array.isArray()
no-return-assign: error
no-return-await: error
no-self-compare: error
no-shadow: error
no-shadow-restricted-names: error
no-spaced-func: error
no-tabs: error
no-template-curly-in-string: error
no-throw-literal: error
no-trailing-spaces: error
no-undef-init: error
no-unneeded-ternary: error
no-unused-expressions: error
no-unused-vars:
- error
# Vars use a suffix _ instead of a prefix because of file-scope private vars
- varsIgnorePattern: (^unused|_$)
argsIgnorePattern: ^(unused|_)
no-useless-call: error
no-useless-computed-key: error
no-useless-concat: error
no-useless-constructor: error
no-useless-rename: error
no-useless-return: error
no-whitespace-before-property: error
no-with: error
nonblock-statement-body-position:
- error
- below
object-curly-newline:
- error
- consistent: true
object-curly-spacing: error
object-shorthand: error
operator-assignment: error
operator-linebreak: error
padded-blocks:
- error
- never
# These may be a bit controversial, we can try them out and enable them later
# prefer-const: error
# prefer-destructuring: error
prefer-numeric-literals: error
prefer-promise-reject-errors: error
prefer-rest-params: error
prefer-spread: error
prefer-template: error
quotes:
- error
- single
- avoidEscape: true
require-await: error
rest-spread-spacing: error
semi:
- error
- always
semi-spacing:
- error
- before: false
after: true
semi-style: error
space-before-blocks: error
space-before-function-paren:
- error
- named: never
# for `function ()` and `async () =>`, preserve space around keywords
anonymous: always
asyncArrow: always
space-in-parens: error
space-infix-ops:
- error
- int32Hint: false
space-unary-ops: error
spaced-comment: error
switch-colon-spacing: error
symbol-description: error
template-curly-spacing: error
template-tag-spacing: error
unicode-bom: error
valid-jsdoc:
- error
- requireReturn: false
wrap-iife:
- error
- inside
yield-star-spacing: error
yoda: error
globals:
ARGV: readonly
Debugger: readonly
GIRepositoryGType: readonly
globalThis: readonly
imports: readonly
Intl: readonly
log: readonly
logError: readonly
print: readonly
printerr: readonly
parserOptions:
ecmaVersion: 2020

View File

@@ -1,16 +0,0 @@
{
"rules": {
"indent": [
"error",
4,
{
"ignoredNodes": [
"CallExpression > ArrowFunctionExpression",
"CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child"
],
"CallExpression": { "arguments": "first" },
"MemberExpression": "off"
}
]
}
}

View File

@@ -1,30 +0,0 @@
{
"rules": {
"camelcase": [
"error",
{
"properties": "never",
"allow": ["^vfunc_"]
}
],
"no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "_$"
}
],
"object-curly-spacing": [
"error",
"always"
],
"prefer-arrow-callback": "error"
},
"globals": {
"global": false,
"_": false,
"C_": false,
"N_": false,
"ngettext": false
}
}

11
lint/eslintrc-shell.yml Normal file
View File

@@ -0,0 +1,11 @@
rules:
camelcase:
- error
- properties: never
allow: [^vfunc_, ^on_]
object-curly-spacing:
- error
- always
prefer-arrow-callback: error
globals:
global: readonly

View File

@@ -1,61 +0,0 @@
#!/bin/sh
SEP=`printf '\t'`
OUTPUT=/dev/stderr
CWD=`pwd`
SRCDIR=`dirname $0`
run_lint() {
eslint -f unix "$@" .
}
parse_opts() {
tmp=`getopt -l output: o: "$@"`
[ $? -ne 0 ] && exit 1
eval set -- $tmp
while true
do
case $1 in
--output|-o)
OUTPUT=`realpath $2`; shift 2; continue ;;
--)
shift; break ;;
esac
done
}
# delete lines that don't start with '/',
# replace the first space with tab, sort
process_for_join() {
sed -E "/\//!d; s|(\S+)\s|\1$SEP|" | sort -k 1b,1
}
# re-replace tab with space
process_post_join() {
sed -E "s|$SEP| |"
}
create_report() {
tmp1=`mktemp --tmpdir lint-XXXX`
run_lint | process_for_join > $tmp1
tmp2=`mktemp --tmpdir lint-XXXX`
run_lint -c lint/eslintrc-legacy.json | process_for_join > $tmp2
join -t"$SEP" -o '0,1.2' $tmp1 $tmp2 | process_post_join
rm $tmp1 $tmp2
}
parse_opts "$@"
cd $SRCDIR/..
create_report | tee $OUTPUT | grep -q .
rv=$(( $? == 0 ))
cd $CWD
[ $rv -eq 0 -a -f $OUTPUT ] && rm $OUTPUT
exit $rv

View File

@@ -1,11 +1,12 @@
project('gnome-shell-extensions',
version: '3.31.92',
version: '40.1',
meson_version: '>= 0.44.0',
license: 'GPL2+'
)
gettext_domain = meson.project_name()
fs = import('fs')
gnome = import('gnome')
i18n = import('i18n')
@@ -20,14 +21,8 @@ schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
sessiondir = join_paths(datadir, 'gnome-session', 'sessions')
xsessiondir = join_paths(datadir, 'xsessions')
js60 = find_program('js60', required: false)
ver_arr = meson.project_version().split('.')
if ver_arr[1].to_int().is_even()
shell_version = '@0@.@1@'.format(ver_arr[0], ver_arr[1])
else
shell_version = '.'.join(ver_arr)
endif
shell_version = '@0@.0'.format(ver_arr[0])
uuid_suffix = '@gnome-shell-extensions.gcampax.github.com'
@@ -87,9 +82,10 @@ foreach e : enabled_extensions
endforeach
if classic_mode_enabled
sassc = find_program('sassc', required: true)
subdir('data')
endif
subdir('extensions')
subdir('po')
meson.add_dist_script('meson/generate-stylesheets.py')

View File

@@ -0,0 +1,13 @@
#!/usr/bin/env python3
import os
from pathlib import PurePath
import subprocess
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
distroot = os.environ.get('MESON_DIST_ROOT')
stylesheet_path = PurePath('data/gnome-classic.css')
src = PurePath(sourceroot, stylesheet_path.with_suffix('.scss'))
dst = PurePath(distroot, stylesheet_path)
subprocess.call(['sassc', '-a', src, dst])

View File

@@ -32,12 +32,14 @@ id
is
it
ja
kab
kk
km
kn
ko
lt
lv
mjw
ml
mr
ms

View File

@@ -1,5 +1,4 @@
data/gnome-classic.desktop.in
data/gnome-classic.session.desktop.in
extensions/apps-menu/extension.js
extensions/auto-move-windows/extension.js
extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml
@@ -10,11 +9,11 @@ extensions/native-window-placement/org.gnome.shell.extensions.native-window-plac
extensions/places-menu/extension.js
extensions/places-menu/placeDisplay.js
extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml
extensions/user-theme/extension.js
extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml
extensions/window-list/extension.js
extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml
extensions/window-list/prefs.js
extensions/window-list/workspaceIndicator.js
extensions/windowsNavigator/extension.js
extensions/workspace-indicator/extension.js
extensions/workspace-indicator/prefs.js

377
po/be.po
View File

@@ -6,11 +6,11 @@
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell-extensions master\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=extensions\n"
"POT-Creation-Date: 2017-08-19 16:41+0000\n"
"PO-Revision-Date: 2017-09-01 17:56+0300\n"
"Last-Translator: Yuras Shumovich <shumovichy@gmail.com>\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/"
"issues\n"
"POT-Creation-Date: 2021-01-20 23:03+0000\n"
"PO-Revision-Date: 2021-01-24 15:33+0300\n"
"Last-Translator: Launchpad translators\n"
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
"Language: be\n"
"MIME-Version: 1.0\n"
@@ -18,9 +18,9 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 1.8.11\n"
"X-Generator: Poedit 2.4.2\n"
#: data/gnome-classic.desktop.in:3 data/gnome-classic.session.desktop.in:3
#: data/gnome-classic.desktop.in:3
msgid "GNOME Classic"
msgstr "Класічны GNOME"
@@ -28,171 +28,69 @@ msgstr "Класічны GNOME"
msgid "This session logs you into GNOME Classic"
msgstr "Гэты сеанс выкарыстоўвае класічны GNOME"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:7
msgid "Attach modal dialog to the parent window"
msgstr "Прымацаваць мадальны дыялог да бацькоўскага акна"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:8
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:25
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:33
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:41
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "Гэты ключ засланяе ключ у org.gnome.mutter калі запушчаны GNOME Shell."
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:16
msgid "Arrangement of buttons on the titlebar"
msgstr "Парадак кнопак у загалоўнай стужцы"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:17
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"Гэты ключ засланяе ключ у org.gnome.desktop.wm.preferences калі запушчаны "
"GNOME Shell."
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:24
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Аўтаматычна змяняць памеры акна пры перамяшчэнні да края экрана"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:32
msgid "Workspaces only on primary monitor"
msgstr "Працоўныя прасторы толькі на асноўным маніторы"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:40
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr "Затрымліваць змяненні фокуса ў рэжыме мышы да спынення паказальніка"
#: extensions/alternate-tab/prefs.js:20
msgid "Thumbnail only"
msgstr "Толькі мініяцюра"
#: extensions/alternate-tab/prefs.js:21
msgid "Application icon only"
msgstr "Толькі значок праграмы"
#: extensions/alternate-tab/prefs.js:22
msgid "Thumbnail and application icon"
msgstr "Мініяцюра і значок праграмы"
#: extensions/alternate-tab/prefs.js:38
msgid "Present windows as"
msgstr "Адлюстроўваць вокны як"
#: extensions/alternate-tab/prefs.js:69
msgid "Show only windows in the current workspace"
msgstr "Паказваць вокны толькі з бягучай працоўная прасторы"
#: extensions/apps-menu/extension.js:41
msgid "Activities Overview"
msgstr "Агляд заняткаў"
#: extensions/apps-menu/extension.js:141
#: extensions/apps-menu/extension.js:113
msgid "Favorites"
msgstr "Упадабаныя"
msgstr "Абраныя"
#: extensions/apps-menu/extension.js:436
#: extensions/apps-menu/extension.js:369
msgid "Applications"
msgstr "Праграмы"
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:6
msgid "Application and workspace list"
msgstr "Праграма і спіс працоўных прастораў"
msgstr "Праграма і спіс працоўных прастор"
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:7
msgid ""
"A list of strings, each containing an application id (desktop file name), "
"followed by a colon and the workspace number"
msgstr ""
"Спіс радкоў, кожны з якіх утрымлівае ідэнтыфікатар праграмы (імя *.desktop "
"файла), затым двукроп'е і нумар працоўнай прасторы"
"Спіс радкоў, кожны з якіх змяшчае ідэнтыфікатар праграмы (імя файла *."
"desktop), затым двукроп'е і нумар працоўнай прасторы"
#: extensions/auto-move-windows/prefs.js:60
msgid "Application"
msgstr "Праграма"
#: extensions/auto-move-windows/prefs.js:35
msgid "Workspace Rules"
msgstr "Правілы для працоўнай прасторы"
#: extensions/auto-move-windows/prefs.js:69
#: extensions/auto-move-windows/prefs.js:127
msgid "Workspace"
msgstr "Працоўная прастора"
#: extensions/auto-move-windows/prefs.js:85
#: extensions/auto-move-windows/prefs.js:237
msgid "Add Rule"
msgstr "Дадаць правіла"
#: extensions/auto-move-windows/prefs.js:106
msgid "Create new matching rule"
msgstr "Стварыць новае правіла адпаведнасці"
#: extensions/auto-move-windows/prefs.js:111
msgid "Add"
msgstr "Дадаць"
#. TRANSLATORS: %s is the filesystem name
#: extensions/drive-menu/extension.js:107
#: extensions/drive-menu/extension.js:112
#: extensions/places-menu/placeDisplay.js:233
#, javascript-format
msgid "Ejecting drive “%s” failed:"
msgstr "Не ўдалося выняць прывод \"%s\":"
msgstr "Не ўдалося выняць дыск «%s»:"
#: extensions/drive-menu/extension.js:125
#: extensions/drive-menu/extension.js:128
msgid "Removable devices"
msgstr "Зменныя прыстасаванні"
msgstr "Здымныя прылады"
#: extensions/drive-menu/extension.js:150
#: extensions/drive-menu/extension.js:155
msgid "Open Files"
msgstr "Адкрыць файлы"
#: extensions/example/extension.js:17
msgid "Hello, world!"
msgstr "Прывітанне, свет!"
#: extensions/example/org.gnome.shell.extensions.example.gschema.xml:5
msgid "Alternative greeting text."
msgstr "Альтэрнатыўны тэкст вітання."
#: extensions/example/org.gnome.shell.extensions.example.gschema.xml:6
msgid ""
"If not empty, it contains the text that will be shown when clicking on the "
"panel."
msgstr ""
"Калі не пуста, ўтрымлівае тэкст, які будзе паказвацца пры націсканні на "
"панэль."
#: extensions/example/prefs.js:30
msgid "Message"
msgstr "Паведамленне"
#. TRANSLATORS: Example is the name of the extension, should not be
#. translated
#: extensions/example/prefs.js:43
msgid ""
"Example aims to show how to build well behaved extensions for the Shell and "
"as such it has little functionality on its own.\n"
"Nevertheless its possible to customize the greeting message."
msgstr ""
"Example пакажа як ствараць пашырэнні для Shell. Сам па сабе ён мае мала "
"функцыянальнасці.\n"
"Тым не менш, можна змяніць тэкст прывітання."
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:5
#, fuzzy
msgid "Use more screen for windows"
msgstr "Выкарыстоўваць большую плошчу экрана для вокнаў"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:6
#, fuzzy
msgid ""
"Try to use more screen for placing window thumbnails by adapting to screen "
"aspect ratio, and consolidating them further to reduce the bounding box. "
"This setting applies only with the natural placement strategy."
msgstr ""
"Спрабаваць выкарыстаць большую плошчу экрана для размяшчэння мініяцюр шляхам "
"змянення суадносінаў бакоў экрана і ўшчыльняючы іх з мэтай змяншэння памераў "
"абмежавальнай рамкі. Гэты параметр ужываецца толькі разам з звычайным "
"Спрабаваць выкарыстаць большую плошчу экрана для размяшчэння мініяцюр праз "
"змяненне суадносінаў бакоў экрана, ўшчыльняючы іх, каб зменшыць памеры "
"абмежавальнай рамкі. Гэты параметр ужываецца толькі з натуральным "
"размяшчэннем мініяцюр."
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:11
msgid "Place window captions on top"
msgstr "Змяшчаць загалоўкі вокнаў зверху"
msgstr "Размяшчаць подпіс акна зверху"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:12
msgid ""
@@ -200,156 +98,243 @@ msgid ""
"shell default of placing it at the bottom. Changing this setting requires "
"restarting the shell to have any effect."
msgstr ""
"Калі выбрана, загалоўкі вокнаў будуць размешчаны ўверсе мініяцюры, а не "
"знізу, як прадвызначана. Для таго, каб гэтая настройка ўступіла ў сілу, "
"трэба перазапусціць абалонку."
"Калі выбрана, подпіс акна будзе над мініяцюрай, а не пад ей (як "
"перадвызначана). Каб змена налады ўступіла ў сілу, трэба перазапусціць "
"абалонку."
#: extensions/places-menu/extension.js:78
#: extensions/places-menu/extension.js:81
#: extensions/places-menu/extension.js:89
#: extensions/places-menu/extension.js:93
msgid "Places"
msgstr "Месцы"
#: extensions/places-menu/placeDisplay.js:65
#, javascript-format
msgid "Failed to mount volume for “%s”"
msgstr "Не ўдалося прымацаваць том для \"%s\"."
#: extensions/places-menu/placeDisplay.js:78
#: extensions/places-menu/placeDisplay.js:46
#, javascript-format
msgid "Failed to launch “%s”"
msgstr "Не ўдалося запусціць \"%s\""
msgstr "Не ўдалося запусціць «%s»"
#: extensions/places-menu/placeDisplay.js:137
#: extensions/places-menu/placeDisplay.js:160
#: extensions/places-menu/placeDisplay.js:61
#, javascript-format
msgid "Failed to mount volume for “%s”"
msgstr "Не ўдалося прымацаваць том для «%s»."
#: extensions/places-menu/placeDisplay.js:148
#: extensions/places-menu/placeDisplay.js:171
msgid "Computer"
msgstr "Камп'ютар"
#: extensions/places-menu/placeDisplay.js:303
#: extensions/places-menu/placeDisplay.js:359
msgid "Home"
msgstr "Дамашняя папка"
msgstr "Хатняя папка"
#: extensions/places-menu/placeDisplay.js:347
#: extensions/places-menu/placeDisplay.js:404
msgid "Browse Network"
msgstr "Агляд сеткі"
#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:7
msgid "Cycle Screenshot Sizes"
msgstr "Чаргаваць памеры экраннага здымка"
msgstr "Паслядоўнасць змены памераў для здымка экрана"
#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:11
msgid "Cycle Screenshot Sizes Backward"
msgstr "Чаргаваць памеры экраннага здымка ў адваротным напрамку"
msgstr "Адваротная паслядоўнасць змены памераў для здымка экрана"
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:5
msgid "Theme name"
msgstr "Імя матыву аздаблення"
msgstr "Назва тэмы"
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:6
msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell"
msgstr ""
"Імя матыву аздаблення, які будзе загружаны з ~/.themes/name/gnome-shell"
msgstr "Назва тэмы, што загрузіцца з ~/.themes/name/gnome-shell"
#: extensions/window-list/extension.js:110
#: extensions/window-list/extension.js:98
msgid "Close"
msgstr "Закрыць"
#: extensions/window-list/extension.js:129
#: extensions/window-list/extension.js:118
msgid "Unminimize"
msgstr "Скасаваць мінімалізацыю"
msgstr "Скасаваць згортванне"
#: extensions/window-list/extension.js:130
#: extensions/window-list/extension.js:118
msgid "Minimize"
msgstr "Мінімалізаваць"
msgstr "Згарнуць"
#: extensions/window-list/extension.js:136
#: extensions/window-list/extension.js:125
msgid "Unmaximize"
msgstr "Скасаваць максімалізацыю"
msgstr "Скасаваць разгортванне"
#: extensions/window-list/extension.js:137
#: extensions/window-list/extension.js:125
msgid "Maximize"
msgstr "Максімалізаваць"
msgstr "Разгарнуць"
#: extensions/window-list/extension.js:420
#: extensions/window-list/extension.js:432
msgid "Minimize all"
msgstr "Мінімалізаваць усе"
msgstr "Згарнуць усе"
#: extensions/window-list/extension.js:428
#: extensions/window-list/extension.js:438
msgid "Unminimize all"
msgstr "Скасаваць мінімалізацыю для ўсіх"
msgstr "Скасаваць згортванне для ўсіх"
#: extensions/window-list/extension.js:436
#: extensions/window-list/extension.js:444
msgid "Maximize all"
msgstr "Максімалізаваць усе"
msgstr "Разгарнуць усе"
#: extensions/window-list/extension.js:445
#: extensions/window-list/extension.js:452
msgid "Unmaximize all"
msgstr "Скасаваць максімалізацыю для ўсіх"
msgstr "Скасаваць разгортванне для ўсіх"
#: extensions/window-list/extension.js:454
#: extensions/window-list/extension.js:460
msgid "Close all"
msgstr "Закрыць усе"
#: extensions/window-list/extension.js:678
#: extensions/workspace-indicator/extension.js:30
msgid "Workspace Indicator"
msgstr "Індыкатар працоўнай прасторы"
#: extensions/window-list/extension.js:842
#: extensions/window-list/extension.js:737
msgid "Window List"
msgstr "Спіс вокнаў"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:12
msgid "When to group windows"
msgstr "Калі групаваць вокны"
msgstr "Умовы групавання вокнаў"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:13
msgid ""
"Decides when to group windows from the same application on the window list. "
"Possible values are “never”, “auto” and “always”."
msgstr ""
"Вырашае калі групаваць вокны адной праграмы ў спісе вокнаў. Магчымыя "
"значэнні: \"never\" (ніколі), \"auto\" (аўтаматычна), \"always\" (заўсёды)."
"Вызначае калі групаваць вокны адной праграмы ў спісе вокнаў. Магчымыя "
"значэнні: «never» (ніколі), «auto» (аўтаматычна), «always» (заўсёды)."
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20
msgid "Show the window list on all monitors"
msgstr "Паказаць спіс вокнаў на ўсіх маніторах"
#: extensions/window-list/prefs.js:100
msgid "Show windows from all workspaces"
msgstr "Паказваць вокны з усіх працоўных прастор"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:21
msgid "Whether to show windows from all workspaces or only the current one."
msgstr "Паказваць вокны з усіх працоўных прастор ці толькі з бягучай."
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:27
msgid "Show the window list on all monitors"
msgstr "Паказваць спіс вокнаў на ўсіх маніторах"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:28
msgid ""
"Whether to show the window list on all connected monitors or only on the "
"primary one."
msgstr ""
"Ці паказваць спіс вокнаў на ўсіх злучаных маніторах або толькі на галоўным."
"Паказваць спіс вокнаў на ўсіх падлучаных маніторах ці толькі на асноўным."
#: extensions/window-list/prefs.js:32
#: extensions/window-list/prefs.js:29
msgid "Window Grouping"
msgstr "Групаванне вокнаў"
#: extensions/window-list/prefs.js:50
#: extensions/window-list/prefs.js:58
msgid "Never group windows"
msgstr "Ніколі не групаваць вокны"
#: extensions/window-list/prefs.js:51
#: extensions/window-list/prefs.js:59
msgid "Group windows when space is limited"
msgstr "Групаваць вокны калі не хапае месца"
#: extensions/window-list/prefs.js:52
#: extensions/window-list/prefs.js:60
msgid "Always group windows"
msgstr "Заўсёды групаваць вокны"
#: extensions/window-list/prefs.js:75
#: extensions/window-list/prefs.js:94
msgid "Show on all monitors"
msgstr "Паказаць усе маніторы"
msgstr "Паказваць на ўсіх маніторах"
#: extensions/workspace-indicator/prefs.js:141
#: extensions/window-list/workspaceIndicator.js:247
#: extensions/workspace-indicator/extension.js:253
msgid "Workspace Indicator"
msgstr "Індыкатар працоўнай прасторы"
#: extensions/workspace-indicator/prefs.js:34
msgid "Workspace Names"
msgstr "Назвы працоўных прастораў"
msgstr "Назвы працоўных прастор"
#: extensions/workspace-indicator/prefs.js:157
msgid "Name"
msgstr "Імя"
#: extensions/workspace-indicator/prefs.js:198
#: extensions/workspace-indicator/prefs.js:67
#, javascript-format
msgid "Workspace %d"
msgstr "Працоўная прастора %d"
#: extensions/workspace-indicator/prefs.js:208
msgid "Add Workspace"
msgstr "Дадаць працоўную прастору"
#~ msgid "Attach modal dialog to the parent window"
#~ msgstr "Прымацаваць мадальны дыялог да бацькоўскага акна"
#~ msgid ""
#~ "This key overrides the key in org.gnome.mutter when running GNOME Shell."
#~ msgstr ""
#~ "Гэты ключ засланяе ключ у org.gnome.mutter калі запушчаны GNOME Shell."
#~ msgid "Arrangement of buttons on the titlebar"
#~ msgstr "Парадак кнопак у загалоўнай стужцы"
#~ msgid ""
#~ "This key overrides the key in org.gnome.desktop.wm.preferences when "
#~ "running GNOME Shell."
#~ msgstr ""
#~ "Гэты ключ засланяе ключ у org.gnome.desktop.wm.preferences калі запушчаны "
#~ "GNOME Shell."
#~ msgid "Enable edge tiling when dropping windows on screen edges"
#~ msgstr "Аўтаматычна змяняць памеры акна пры перамяшчэнні да края экрана"
#~ msgid "Workspaces only on primary monitor"
#~ msgstr "Працоўныя прасторы толькі на асноўным маніторы"
#~ msgid "Delay focus changes in mouse mode until the pointer stops moving"
#~ msgstr "Затрымліваць змяненні фокуса ў рэжыме мышы да спынення паказальніка"
#~ msgid "Thumbnail only"
#~ msgstr "Толькі мініяцюра"
#~ msgid "Application icon only"
#~ msgstr "Толькі значок праграмы"
#~ msgid "Thumbnail and application icon"
#~ msgstr "Мініяцюра і значок праграмы"
#~ msgid "Present windows as"
#~ msgstr "Адлюстроўваць вокны як"
#~ msgid "Activities Overview"
#~ msgstr "Агляд заняткаў"
#~ msgid "Application"
#~ msgstr "Праграма"
#~ msgid "Create new matching rule"
#~ msgstr "Стварыць новае правіла адпаведнасці"
#~ msgid "Add"
#~ msgstr "Дадаць"
#~ msgid "Hello, world!"
#~ msgstr "Прывітанне, свет!"
#~ msgid "Alternative greeting text."
#~ msgstr "Альтэрнатыўны тэкст вітання."
#~ msgid ""
#~ "If not empty, it contains the text that will be shown when clicking on "
#~ "the panel."
#~ msgstr ""
#~ "Калі не пуста, ўтрымлівае тэкст, які будзе паказвацца пры націсканні на "
#~ "панэль."
#~ msgid "Message"
#~ msgstr "Паведамленне"
#~ msgid ""
#~ "Example aims to show how to build well behaved extensions for the Shell "
#~ "and as such it has little functionality on its own.\n"
#~ "Nevertheless its possible to customize the greeting message."
#~ msgstr ""
#~ "Example пакажа як ствараць пашырэнні для Shell. Сам па сабе ён мае мала "
#~ "функцыянальнасці.\n"
#~ "Тым не менш, можна змяніць тэкст прывітання."
#~ msgid "Name"
#~ msgstr "Імя"

View File

@@ -1,360 +1,350 @@
# sray <sray@redhat.com>, 2013, 2014. #zanata.
# Akarshan Biswas <akarshan.biswas@hotmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=extensions\n"
"POT-Creation-Date: 2014-09-22 07:38+0000\n"
"PO-Revision-Date: 2014-09-22 16:37+0000\n"
"Last-Translator: \n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Project-Id-Version: unnamed project\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/"
"issues\n"
"POT-Creation-Date: 2020-05-28 00:55+0000\n"
"PO-Revision-Date: 2020-08-13 10:03+0530\n"
"Last-Translator: Akarshan Biswas <akarshan.biswas@hotmail.com>\n"
"Language-Team: Bengali (India) <anubad@lists.ankur.org.in>\n"
"Language: bn_IN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-DamnedLies-Scope: partial\n"
"X-Generator: Gtranslator 3.36.0\n"
#: ../data/gnome-classic.desktop.in.h:1
#: ../data/gnome-classic.session.desktop.in.in.h:1
#: data/gnome-classic.desktop.in:3 data/gnome-classic.session.desktop.in:3
msgid "GNOME Classic"
msgstr "GNOME ক্লাসিক"
#: ../data/gnome-classic.desktop.in.h:2
#: data/gnome-classic.desktop.in:4
msgid "This session logs you into GNOME Classic"
msgstr "এই সেশন অাপনাকে GNOME ক্লাসিকে লগ করায়"
#: ../data/gnome-shell-classic.desktop.in.in.h:1
msgid "GNOME Shell Classic"
msgstr "GNOME সেল ক্লাসিক"
# auto translated by TM merge from project: gnome-shell, version: 3.8.4, DocId: gnome-shell
#: ../data/gnome-shell-classic.desktop.in.in.h:2
msgid "Window management and application launching"
msgstr "উইন্ডো পরিচালনা ও অ্যাপ্লিকেশন প্রারম্ভ"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:1
msgid "Attach modal dialog to the parent window"
msgstr "প্রধান উইন্ডোতে মোডেল ডায়ালগ সংযুক্ত করুন"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:2
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"GNOME সেল চালানোর ক্ষেত্রে এই কী in org.gnome.mutter এর কী ওভাররাইড করে।"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:3
msgid "Arrangement of buttons on the titlebar"
msgstr "শিরোনাম দন্ডে বোতামগুলির সজ্জা"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:4
#| msgid ""
#| "This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"GNOME সেল চালানোর সময়ে এই কী org.gnome.desktop.wm.preferences-এর কী ওভাররাইড "
"করে।"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:5
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "উইন্ডো স্ক্রীন কিনারায় রাখার সময়ে কিনারা টাইলিং সক্রিয় করুন"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:6
msgid "Workspaces only on primary monitor"
msgstr "শুধুমাত্র প্রধান মনিটরে ওয়ার্কস্পেস"
#: ../data/org.gnome.shell.extensions.classic-overrides.gschema.xml.in.h:7
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
"পয়েন্টার অবস্থান পরিবর্তন না থামানো পর্যন্ত মাউস মোডে ফোকাস পরিবর্তন বিলম্বিত "
"করুন"
#: ../extensions/alternate-tab/prefs.js:20
msgid "Thumbnail only"
msgstr "শুধুমাত্র থাম্বনেইল"
#: ../extensions/alternate-tab/prefs.js:21
msgid "Application icon only"
msgstr "শুধুমাত্র অ্যাপ্লিকেশন অাইকন"
#: ../extensions/alternate-tab/prefs.js:22
msgid "Thumbnail and application icon"
msgstr "থাম্বনেইল এবং অ্যাপ্লিকেশন অাইকন"
#: ../extensions/alternate-tab/prefs.js:38
msgid "Present windows as"
msgstr "এই রূপে উইন্ডো উপস্থাপনা"
#: ../extensions/alternate-tab/prefs.js:69
msgid "Show only windows in the current workspace"
msgstr "শুধুমাত্র উইন্ডো বর্তমান ওয়ার্কস্পেসে দেখান"
#: ../extensions/apps-menu/extension.js:39
msgid "Activities Overview"
msgstr "ক্রিয়াকলাপের পূর্বরূপ"
msgstr "এই সেশন পনাকে GNOME ক্লাসিকে লগ করায়"
# auto translated by TM merge from project: system-config-printer, version: 1.1.16-23, DocId: system-config-printer
#: ../extensions/apps-menu/extension.js:113
#: extensions/apps-menu/extension.js:113
msgid "Favorites"
msgstr "বিশেষ"
# auto translated by TM merge from project: gnome-menus, version: 3.8.0, DocId: gnome-menus-3.0
#: ../extensions/apps-menu/extension.js:282
#: extensions/apps-menu/extension.js:369
msgid "Applications"
msgstr "অ্যাপ্লিকেশন"
#: ../extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml.in.h:1
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:6
msgid "Application and workspace list"
msgstr "অ্যাপ্লেকেশন এবং ওয়ার্কস্পেস তালিকা"
#: ../extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml.in.h:2
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:7
msgid ""
"A list of strings, each containing an application id (desktop file name), "
"followed by a colon and the workspace number"
msgstr ""
"স্ট্রীঙের একটি তালিকা, প্রতিটিতে থাকে একটি অ্যাপ্লিকেশন অাইডি (ডেস্কটপ ফাইল "
"নাম), "
"স্ট্রীঙের একটি তালিকা, প্রতিটিতে থাকে একটি অ্যাপ্লিকেশন ইডি (ডেস্কটপ ফাইল নাম), "
"সংগে থাকে যতিচিহ্ন এবং ওয়ার্কস্পেস নম্বর"
# auto translated by TM merge from project: yelp, version: 3.8.1, DocId: yelp
#: ../extensions/auto-move-windows/prefs.js:60
msgid "Application"
msgstr "অ্যাপ্লিকেশন"
#: ../extensions/auto-move-windows/prefs.js:69
#: ../extensions/auto-move-windows/prefs.js:127
msgid "Workspace"
msgstr "ওয়ার্কস্পেস"
#: extensions/auto-move-windows/prefs.js:35
#| msgid "Workspace Names"
msgid "Workspace Rules"
msgstr "ওয়ার্কস্পেস নিয়মগুলি"
# auto translated by TM merge from project: evolution, version: el6, DocId: evolution-2.32
#: ../extensions/auto-move-windows/prefs.js:85
#| msgid "Add rule"
#: extensions/auto-move-windows/prefs.js:243
msgid "Add Rule"
msgstr "নিয়ম যোগ করুন"
#: ../extensions/auto-move-windows/prefs.js:106
msgid "Create new matching rule"
msgstr "মেলানোর নতুন নিয়ম তৈরি করুন"
# auto translated by TM merge from project: file-roller, version: 3.8.3, DocId: file-roller
#: ../extensions/auto-move-windows/prefs.js:111
msgid "Add"
msgstr "যোগ করুন"
#: ../extensions/drive-menu/extension.js:106
#. TRANSLATORS: %s is the filesystem name
#: extensions/drive-menu/extension.js:112
#: extensions/places-menu/placeDisplay.js:233
#, javascript-format
msgid "Ejecting drive '%s' failed:"
msgstr "'%s' ড্রাইভ ইজেক্ট করা গেল না:"
#| msgid "Ejecting drive '%s' failed:"
msgid "Ejecting drive “%s” failed:"
msgstr "'%s' ড্রাইভ ইজেক্ট করতে ব্যর্থ :"
#: ../extensions/drive-menu/extension.js:123
#: extensions/drive-menu/extension.js:128
msgid "Removable devices"
msgstr "অপসারণযোগ্য ডিভাইসগুলি"
# auto translated by TM merge from project: gnome-user-share, version: 3.8, DocId: gnome-user-share
#: ../extensions/drive-menu/extension.js:150
msgid "Open File"
#: extensions/drive-menu/extension.js:155
#| msgid "Open File"
msgid "Open Files"
msgstr "ফাইল খুলুন"
#: ../extensions/example/extension.js:17
msgid "Hello, world!"
msgstr "ওহে, বিশ্ব!"
#: ../extensions/example/org.gnome.shell.extensions.example.gschema.xml.in.h:1
msgid "Alternative greeting text."
msgstr "বিকল্প অভিবাদন পাঠ্য।"
#: ../extensions/example/org.gnome.shell.extensions.example.gschema.xml.in.h:2
msgid ""
"If not empty, it contains the text that will be shown when clicking on the "
"panel."
msgstr "খালি না থাকলে, তাতে পাঠ্য থাকবে যা প্যানেলে ক্লিক করা হলে দেখানো হবে।"
#: ../extensions/example/prefs.js:30
#| msgid "Message:"
msgid "Message"
msgstr "বার্তা"
#: ../extensions/example/prefs.js:43
msgid ""
"Example aims to show how to build well behaved extensions for the Shell and "
"as such it has little functionality on its own.\n"
"Nevertheless it's possible to customize the greeting message."
msgstr ""
"সেলের জন্য সুস্থিত এক্সটেনশন কীভাবে গঠন করা সম্ভব তা উদাহরণের মাধ্যমে "
"উপস্থাপিত করা "
"হয়।\n"
"উপরন্তু অভিভাদন বার্তা নিজের পছন্দ মতোও করে নেওয়া যায়।"
#: ../extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml.in.h:1
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:5
msgid "Use more screen for windows"
msgstr "উইন্ডোর জন্য অারো স্ক্রীন ব্যবহার করুন"
msgstr "উইন্ডোর জন্য রো স্ক্রীন ব্যবহার করুন"
#: ../extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml.in.h:2
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:6
msgid ""
"Try to use more screen for placing window thumbnails by adapting to screen "
"aspect ratio, and consolidating them further to reduce the bounding box. "
"This setting applies only with the natural placement strategy."
msgstr ""
"স্ক্রীন অ্যাসপেক্ট অনুপাত সামঞ্জস্যপূর্ণ করে উইন্ডো থাম্বনেইল রাখার জন্য অারো "
"স্ক্রীন "
"ব্যবহারের চেষ্টা করুন, এবং বাউন্ডিং বক্স কমাতে তাদের সংঘবদ্ধ করার চেষ্টা "
"করুন। এই "
"স্ক্রীন অ্যাসপেক্ট অনুপাত সামঞ্জস্যপূর্ণ করে উইন্ডো থাম্বনেইল রাখার জন্য আরো স্ক্রীন "
"ব্যবহারের চেষ্টা করুন, এবং বাউন্ডিং বক্স কমাতে তাদের সংঘবদ্ধ করার চেষ্টা করুন। এই "
"সেটিং শুধুমাত্র স্বাভাবিক প্লেসমেন্ট কৌশলের ক্ষেত্রেই প্রযোজ্য হয়।"
#: ../extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml.in.h:3
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:11
msgid "Place window captions on top"
msgstr "উইন্ডো ক্যাপশন একেবারে শীর্ষে রাখুন"
#: ../extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml.in.h:4
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:12
msgid ""
"If true, place window captions on top the respective thumbnail, overriding "
"shell default of placing it at the bottom. Changing this setting requires "
"restarting the shell to have any effect."
msgstr ""
"যদি সত্য হয়, তলায় রাখার সেল ডিফল্ট ওভাররাইড করে সংশ্লিষ্ট থাম্বনেইলের শীর্ষে "
"উইন্ডো "
"ক্যাপশন রাখুন। এই সেটিং পরিবর্তন করলে তা প্রয়োগ করতে সেল বন্ধ করে চালু করতে "
"হবে।"
"যদি সত্য হয়, তলায় রাখার সেল ডিফল্ট ওভাররাইড করে সংশ্লিষ্ট থাম্বনেইলের শীর্ষে উইন্ডো "
"ক্যাপশন রাখুন। এই সেটিং পরিবর্তন করলে তা প্রয়োগ করতে সেল বন্ধ করে চালু করতে হবে।"
# auto translated by TM merge from project: file-roller, version: 3.8.3, DocId: file-roller
#: ../extensions/places-menu/extension.js:78
#: ../extensions/places-menu/extension.js:81
#: extensions/places-menu/extension.js:89
#: extensions/places-menu/extension.js:93
msgid "Places"
msgstr "অবস্থান"
#: ../extensions/places-menu/placeDisplay.js:57
#: extensions/places-menu/placeDisplay.js:46
#, javascript-format
msgid "Failed to launch \"%s\""
msgstr "\"%s\" লঞ্চ করা গেল না"
#| msgid "Failed to launch \"%s\""
msgid "Failed to launch “%s”"
msgstr "\"%s\" লঞ্চ করতে ব্যর্থ "
#: extensions/places-menu/placeDisplay.js:61
#, javascript-format
msgid "Failed to mount volume for “%s”"
msgstr "\"%s\" এর জন্য ভলিউম মাউন্ট করতে ব্যর্থ"
# auto translated by TM merge from project: gvfs, version: 1.16.3, DocId: gvfs
#: ../extensions/places-menu/placeDisplay.js:99
#: ../extensions/places-menu/placeDisplay.js:122
#: extensions/places-menu/placeDisplay.js:148
#: extensions/places-menu/placeDisplay.js:171
msgid "Computer"
msgstr "কম্পিউটার"
# auto translated by TM merge from project: rhsm-web, version: 0.0, DocId: management
#: ../extensions/places-menu/placeDisplay.js:200
#: extensions/places-menu/placeDisplay.js:359
msgid "Home"
msgstr "প্রথম পাতা"
#: ../extensions/places-menu/placeDisplay.js:287
#: extensions/places-menu/placeDisplay.js:404
msgid "Browse Network"
msgstr "নেটওয়ার্ক ব্রাউজ"
# auto translated by TM merge from project: gnome-system-monitor, version: 3.8.2.1, DocId: gnome-system-monitor
#: ../extensions/systemMonitor/extension.js:214
msgid "CPU"
msgstr "CPU"
# auto translated by TM merge from project: RHEV Installation Guide, version: 3.1, DocId: topics/Planning_your_Data_Center
#: ../extensions/systemMonitor/extension.js:267
msgid "Memory"
msgstr "মেমরি"
#: ../extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml.in.h:1
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:5
msgid "Theme name"
msgstr "থিম নাম"
#: ../extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml.in.h:2
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:6
msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell"
msgstr "থিমের নাম, ~/.themes/name/gnome-shell থেকে লোড করা হবে"
#: ../extensions/window-list/extension.js:110
#: extensions/window-list/extension.js:98
msgid "Close"
msgstr "বন্ধ করুন"
#: ../extensions/window-list/extension.js:120
#: extensions/window-list/extension.js:118
msgid "Unminimize"
msgstr "অান-মিনিমাইজ"
msgstr "ন-মিনিমাইজ"
#: ../extensions/window-list/extension.js:121
#: extensions/window-list/extension.js:118
msgid "Minimize"
msgstr "ছোট করুন"
#: ../extensions/window-list/extension.js:127
#: extensions/window-list/extension.js:125
msgid "Unmaximize"
msgstr "অান-ম্যাক্সিমাইজ"
msgstr "ন-ম্যাক্সিমাইজ"
#: ../extensions/window-list/extension.js:128
#: extensions/window-list/extension.js:125
msgid "Maximize"
msgstr "বড় করুন"
#: ../extensions/window-list/extension.js:300
#: extensions/window-list/extension.js:428
msgid "Minimize all"
msgstr "সকল ছোট করুন"
#: ../extensions/window-list/extension.js:308
#: extensions/window-list/extension.js:434
msgid "Unminimize all"
msgstr "সকল অান-মিনিমাইজ করুন"
msgstr "সকল ন-মিনিমাইজ করুন"
#: ../extensions/window-list/extension.js:316
#: extensions/window-list/extension.js:440
msgid "Maximize all"
msgstr "সকল বড় করুন"
#: ../extensions/window-list/extension.js:325
#: extensions/window-list/extension.js:448
msgid "Unmaximize all"
msgstr "সকল অান-ম্যাক্সিমাইজ করুন"
msgstr "সকল ন-ম্যাক্সিমাইজ করুন"
#: ../extensions/window-list/extension.js:334
#: extensions/window-list/extension.js:456
msgid "Close all"
msgstr "সকল বন্ধ করুন"
#: ../extensions/window-list/extension.js:644
#: ../extensions/workspace-indicator/extension.js:30
msgid "Workspace Indicator"
msgstr "ওয়ার্কস্পেস সূচক"
#: ../extensions/window-list/extension.js:808
#| msgid "Window Grouping"
#: extensions/window-list/extension.js:734
msgid "Window List"
msgstr "উইন্ডো তালিকা"
#: ../extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml.in.h:1
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:12
msgid "When to group windows"
msgstr "উইন্ডো দলভুক্তকরণ"
#: ../extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml.in.h:2
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:13
#| msgid ""
#| "Decides when to group windows from the same application on the window "
#| "list. Possible values are \"never\", \"auto\" and \"always\"."
msgid ""
"Decides when to group windows from the same application on the window list. "
"Possible values are \"never\", \"auto\" and \"always\"."
"Possible values are never”, “auto and always."
msgstr ""
"উইন্ডো তালিকা একই অ্যাপ্লিকেশন থেকে কখন উইন্ডো দলভুক্ত করা হবে তা সিদ্ধান্ত "
"নেয়। "
"সম্ভাব্য মানগুলি হল \"কখনও নয়\", \"স্বয়ংক্রিয়\" এবং \"সর্বদা\"।"
"উইন্ডো তালিকা একই অ্যাপ্লিকেশন থেকে কখন উইন্ডোজকে গ্রুপ করবে তা সিদ্ধান্ত নেয়। "
"সম্ভাব্য মানগুলি হ'ল \"কখনই\", \"স্বয়ং\" এবং \"সর্বদা\"।"
#: ../extensions/window-list/prefs.js:30
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20
#: extensions/window-list/prefs.js:100
#| msgid "Show only windows in the current workspace"
msgid "Show windows from all workspaces"
msgstr "সমস্ত ওয়ার্কস্পেসে থেকে উইন্ডো প্রদর্শন করুন"
#: extensions/window-list/prefs.js:29
msgid "Window Grouping"
msgstr "উইন্ডো দলভুক্তকরণ"
#: ../extensions/window-list/prefs.js:49
#: extensions/window-list/prefs.js:58
msgid "Never group windows"
msgstr "উইন্ডো কখনও দলভুক্ত করবেন না"
#: ../extensions/window-list/prefs.js:50
#: extensions/window-list/prefs.js:59
msgid "Group windows when space is limited"
msgstr "স্থান কম থাকলে উইন্ডো দলভুক্ত করুন"
#: ../extensions/window-list/prefs.js:51
#: extensions/window-list/prefs.js:60
msgid "Always group windows"
msgstr "উইন্ডো সর্বদা দলভুক্ত করুন"
#: ../extensions/workspace-indicator/prefs.js:141
#| msgid "Workspace names:"
#: extensions/window-list/prefs.js:94
msgid "Show on all monitors"
msgstr "সমস্ত মনিটরের উপর দেখান"
#: extensions/window-list/workspaceIndicator.js:207
#: extensions/workspace-indicator/extension.js:213
msgid "Workspace Indicator"
msgstr "ওয়ার্কস্পেস সূচক"
#: extensions/workspace-indicator/prefs.js:34
msgid "Workspace Names"
msgstr "ওয়ার্কস্পেস নামগুলি"
#: ../extensions/workspace-indicator/prefs.js:157
msgid "Name"
msgstr "নাম"
#: ../extensions/workspace-indicator/prefs.js:198
#: extensions/workspace-indicator/prefs.js:67
#, javascript-format
msgid "Workspace %d"
msgstr "ওয়ার্কস্পেস %d"
#: extensions/workspace-indicator/prefs.js:218
#| msgid "Workspace"
msgid "Add Workspace"
msgstr "ওয়ার্কস্পেস যোগ করুন"
#~ msgid "GNOME Shell Classic"
#~ msgstr "GNOME সেল ক্লাসিক"
# auto translated by TM merge from project: gnome-shell, version: 3.8.4, DocId: gnome-shell
#~ msgid "Window management and application launching"
#~ msgstr "উইন্ডো পরিচালনা ও অ্যাপ্লিকেশন প্রারম্ভ"
#~ msgid "Attach modal dialog to the parent window"
#~ msgstr "প্রধান উইন্ডোতে মোডেল ডায়ালগ সংযুক্ত করুন"
#~ msgid ""
#~ "This key overrides the key in org.gnome.mutter when running GNOME Shell."
#~ msgstr ""
#~ "GNOME সেল চালানোর ক্ষেত্রে এই কী in org.gnome.mutter এর কী ওভাররাইড করে।"
#~ msgid "Arrangement of buttons on the titlebar"
#~ msgstr "শিরোনাম দন্ডে বোতামগুলির সজ্জা"
#~| msgid ""
#~| "This key overrides the key in org.gnome.mutter when running GNOME Shell."
#~ msgid ""
#~ "This key overrides the key in org.gnome.desktop.wm.preferences when "
#~ "running GNOME Shell."
#~ msgstr ""
#~ "GNOME সেল চালানোর সময়ে এই কী org.gnome.desktop.wm.preferences-এর কী "
#~ "ওভাররাইড করে।"
#~ msgid "Enable edge tiling when dropping windows on screen edges"
#~ msgstr "উইন্ডো স্ক্রীন কিনারায় রাখার সময়ে কিনারা টাইলিং সক্রিয় করুন"
#~ msgid "Workspaces only on primary monitor"
#~ msgstr "শুধুমাত্র প্রধান মনিটরে ওয়ার্কস্পেস"
#~ msgid "Delay focus changes in mouse mode until the pointer stops moving"
#~ msgstr ""
#~ "পয়েন্টার অবস্থান পরিবর্তন না থামানো পর্যন্ত মাউস মোডে ফোকাস পরিবর্তন বিলম্বিত করুন"
#~ msgid "Thumbnail only"
#~ msgstr "শুধুমাত্র থাম্বনেইল"
#~ msgid "Application icon only"
#~ msgstr "শুধুমাত্র অ্যাপ্লিকেশন আইকন"
#~ msgid "Thumbnail and application icon"
#~ msgstr "থাম্বনেইল এবং অ্যাপ্লিকেশন আইকন"
#~ msgid "Present windows as"
#~ msgstr "এই রূপে উইন্ডো উপস্থাপনা"
#~ msgid "Activities Overview"
#~ msgstr "ক্রিয়াকলাপের পূর্বরূপ"
# auto translated by TM merge from project: yelp, version: 3.8.1, DocId: yelp
#~ msgid "Application"
#~ msgstr "অ্যাপ্লিকেশন"
#~ msgid "Create new matching rule"
#~ msgstr "মেলানোর নতুন নিয়ম তৈরি করুন"
# auto translated by TM merge from project: file-roller, version: 3.8.3, DocId: file-roller
#~ msgid "Add"
#~ msgstr "যোগ করুন"
#~ msgid "Hello, world!"
#~ msgstr "ওহে, বিশ্ব!"
#~ msgid "Alternative greeting text."
#~ msgstr "বিকল্প অভিবাদন পাঠ্য।"
#~ msgid ""
#~ "If not empty, it contains the text that will be shown when clicking on "
#~ "the panel."
#~ msgstr "খালি না থাকলে, তাতে পাঠ্য থাকবে যা প্যানেলে ক্লিক করা হলে দেখানো হবে।"
#~| msgid "Message:"
#~ msgid "Message"
#~ msgstr "বার্তা"
#~ msgid ""
#~ "Example aims to show how to build well behaved extensions for the Shell "
#~ "and as such it has little functionality on its own.\n"
#~ "Nevertheless it's possible to customize the greeting message."
#~ msgstr ""
#~ "সেলের জন্য সুস্থিত এক্সটেনশন কীভাবে গঠন করা সম্ভব তা উদাহরণের মাধ্যমে উপস্থাপিত "
#~ "করা হয়।\n"
#~ "উপরন্তু অভিভাদন বার্তা নিজের পছন্দ মতোও করে নেওয়া যায়।"
# auto translated by TM merge from project: gnome-system-monitor, version: 3.8.2.1, DocId: gnome-system-monitor
#~ msgid "CPU"
#~ msgstr "CPU"
# auto translated by TM merge from project: RHEV Installation Guide, version: 3.1, DocId: topics/Planning_your_Data_Center
#~ msgid "Memory"
#~ msgstr "মেমরি"
#~ msgid "Name"
#~ msgstr "নাম"
# auto translated by TM merge from project: gdm, version: 3.8.4, DocId: gdm
#~ msgid "Suspend"
#~ msgstr "স্থগিত করুন"
@@ -370,13 +360,13 @@ msgstr "ওয়ার্কস্পেস %d"
#~ msgstr "স্থগিত সক্রিয় করুন"
#~ msgid "Control the visibility of the Suspend menu item"
#~ msgstr "স্থগিত মেনু অাইটেমের দৃশ্যমানতা নিয়ন্ত্রণ করুন"
#~ msgstr "স্থগিত মেনু ইটেমের দৃশ্যমানতা নিয়ন্ত্রণ করুন"
#~ msgid "Enable hibernating"
#~ msgstr "নিদ্রিত অবস্থা সক্রিয় করুন"
#~ msgid "Control the visibility of the Hibernate menu item"
#~ msgstr "নিদ্রিত অবস্থা মেনু অাইটেমের দৃশ্যমানতা নিয়ন্ত্রণ করুন"
#~ msgstr "নিদ্রিত অবস্থা মেনু ইটেমের দৃশ্যমানতা নিয়ন্ত্রণ করুন"
#~ msgid "Normal"
#~ msgstr "স্বাভাবিক"

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