Compare commits

..

27 commits

Author SHA1 Message Date
e54696b5c6 Make icon theme test BusyBox-compatible
BusyBox find does not support GNU find's -xtype predicate, which
caused shift-icon-theme-coverage to fail in CI. Iterate symlinks with
portable find -type l -print0 and let Bash check whether each target
exists instead.
2026-05-17 18:31:58 +02:00
a338369457 Improve dynamic tiling layout handling
Replace the flat per-screen tiling order with a persistent layout
tree so split orientation and window relationships survive retiles.
Derive the per-screen tile cache from the tree when applying
geometries.

Make drag insertion deterministic by mapping the cursor position
over a target tile to the nearest split direction and previewing
the exact half that will be assigned.

Retile on Workspace.onScreensChanged so screen rotation and output
changes recompute tiled window geometry from the updated work area,
and reconcile tiled windows that KWin moved to another output.
2026-05-17 18:26:28 +02:00
40d0828343 Add SPDX header to icon theme REUSE test 2026-05-17 17:46:43 +02:00
d9877b86d0 Merge feature/identity-desktoptheme-font
Bring the Shift identity, metadata, containment, KCM/KDED, and documentation updates into the main integration branch.
2026-05-17 17:30:50 +02:00
af190a813e Clarify Shift product framing in docs
Rewrite the main project docs to present SHIFT as the product and Plasma Mobile as the upstream base. Keep compatibility-sensitive runtime identifiers such as org.kde.plasma.mobileshell and ~/.config/plasma-mobile explicit in the hacking guide instead of treating them as product identity.
2026-05-17 17:26:52 +02:00
f00a29bd21 Brand KCM and KDED metadata as SHIFT
Point the mobile shell, navigation, and Waydroid KCM metadata at the Shift repository. Brand the KDED startup and APN autodetect module names and descriptions as SHIFT while keeping existing plasma-mobile plugin/library identifiers stable.

Add a guard for these metadata surfaces so upstream project URLs and translated Plasma Mobile overrides are not reintroduced.
2026-05-17 16:31:45 +02:00
82316c393e Brand containment metadata as SHIFT
Point homescreen and panel containment metadata at the Shift repository. Update the panel and task-panel descriptions from Plasma Mobile to SHIFT, and remove translated descriptions that would override the corrected base metadata.

Add a containment metadata guard while preserving the existing org.kde.plasma.mobile.* applet target IDs.
2026-05-17 16:27:48 +02:00
d0967c100f Brand quick settings metadata as SHIFT
Update quick setting package metadata to use SHIFT-facing descriptions and repository links while preserving org.kde.plasma.quicksetting.* package IDs. Drop translated Description entries that could override the corrected base descriptions, update the Caffeine inhibition reason, and add a guard for future regressions.
2026-05-17 16:09:52 +02:00
4b34bca697 Brand initial setup module metadata as SHIFT
Update first-run KPackage descriptions and websites so package-visible metadata points at SHIFT while keeping the existing mobileinitialstart package IDs stable. Remove localized Description entries that could override the new SHIFT-facing base descriptions. Add a CTest guard for the first-run module metadata.
2026-05-17 15:54:55 +02:00
18bef9a573 Brand product metadata as SHIFT
Update session, AppStream, service, shell metadata, and initial setup about/defaults to use SHIFT-facing product metadata while keeping runtime package IDs and executable names stable. Install Shift AppStream metadata and remove stale upstream metainfo from existing prefixes. Add a guard for product metadata branding.
2026-05-17 15:44:56 +02:00
a3173160e2 Render shell-owned icons with theme masks
Use masked Kirigami icons with explicit theme colors for shell controls so the Shift icon theme renders reliably across light and dark surfaces. Replace the status-bar battery helper with theme icon names so battery glyphs also come from org.shift.icons.

Give the app-thumbnail close affordance a symbolic white X on a dark circular backing so it remains visible over previews.
2026-05-17 08:57:06 +02:00
e6f076ed54 Add Shift icon theme and coverage guard
Install org.shift.icons as the look-and-feel icon theme while keeping the Plasma style on breeze-dark. Add the icon-theme coverage guard and CTest registration so shell, System Settings, KCM, and installed Plasma icon names do not silently fall back to missing Breeze-only assets.

Document the theme rules and add scoped REUSE metadata for the Phosphor-derived SVG glyphs.
2026-05-17 08:56:33 +02:00
453c580444 Drop empty Shift desktop theme package
The package shipped no overrides and only inherited the system
default theme, so it had no visible effect. Authoring a correct
FrameSvg override needs a separate, designed effort.
2026-05-14 09:56:20 +02:00
ce5fbf8bea Bundle Atkinson Hyperlegible font files
Vendor the upstream OFL-1.1 variable TTFs so the default
look-and-feel font is actually available.
2026-05-14 09:34:10 +02:00
64e9bdf5db Use Atkinson Hyperlegible as default font
Add a Shift desktop theme package and point the look-and-feel
defaults at Atkinson Hyperlegible Next / Mono.
2026-05-14 09:34:10 +02:00
f22514528b Show timezone selection feedback
Keep the selected timezone visible in the wizard and update it before applying the system timezone.

Filter by city or zone name and report timedatectl failures without discarding the staged choice.
2026-05-11 10:03:20 +02:00
42d41351e2 Add profile-aware initial setup
Detect the device class, stage the selected experience, and write the resulting setup choices through SetupState.

Load the new device and experience modules before the existing setup pages, and use the Shift icon on the finished page.
2026-05-11 10:03:07 +02:00
1b8efc3be3 Use Activities icon for overview button
Replace the redundant app-grid icon with the Activities icon in the
Folio dock overview button.
2026-05-10 09:32:37 +02:00
3fbf68d56b Refine Dynamic Tiling drag zones
Use edge insert zones for drag-and-drop reordering, keep drag signal
connections stable across window creation, and consume task-menu tiling
requests through the script settings bridge.
2026-05-10 09:32:33 +02:00
3f6916cafc Add Dynamic Tiling task menu request bridge
Expose a KConfig-backed request channel in MobileShellSettings and use
it from the Folio task menu to request float/tile actions for a single
window.
2026-05-10 09:32:25 +02:00
3fde6cd173 Use Shift logo in nav UI
Replace the remaining KDE start-here icon in the navigation
tutorial preview and the mobile task switcher.
2026-05-09 13:55:26 +02:00
3c2d8fb602 Add activity actions to dock menu
Expose activity placement controls for running tasks in
convergence mode. The dock menu can now move a window to the
current activity, all activities, or a specific activity.
2026-05-09 13:55:23 +02:00
6ee9cb62a3 Fix Folio trash D-Bus call
Restore the /trash object path in emptyTrash(). The current
argument list is malformed and breaks the Folio plugin build.
2026-05-09 13:55:19 +02:00
ca557f1c2b Delay convergence dock tooltips
Stop dock tooltips from appearing immediately under the pointer and
hide them as soon as the user presses or opens a context menu.
2026-05-09 10:49:25 +02:00
a9e5a2f1e4 Add virtual desktop actions to the dock pager
Open desktop management from the convergence pager and let the
pager add or remove the last virtual desktop without leaving the
dock.
2026-05-09 10:48:52 +02:00
ebb80d5838 Add desktop actions to the dock button
Open the desktop button context menu on right click or press and
hold, and expose Minimize All Windows through KWin's existing
global shortcut.
2026-05-09 10:47:41 +02:00
76da62dae9 Add Peek at Desktop to the convergence dock
Place a desktop toggle next to Home in the convergence dock and
shift the pager and task focus flow around it. This brings the
upstream show-desktop affordance into SHIFT without adding a new
panel surface.
2026-05-09 10:46:32 +02:00
923 changed files with 7483 additions and 3830 deletions

1
.gitignore vendored
View file

@ -24,3 +24,4 @@ build
.preview-config/
.preview-data/
preview.sh
.icon-gen/

View file

@ -11,3 +11,14 @@ Files: HACKING.md
Copyright: Plasma-Mobile contributors
License: CC-BY-SA-4.0
Files: icons/org.shift.icons/**/*.svg
Copyright: 2023 Phosphor Icons
2026 Shift contributors
License: MIT
Comment: SVG glyphs are adapted from Phosphor Icons regular 256px paths for the Shift icon theme.
Files: icons/org.shift.icons/index.theme
icons/org.shift.icons/README.md
Copyright: 2026 Marco Allegretti
License: EUPL-1.2

View file

@ -124,7 +124,7 @@ set_package_properties(KWinDBusInterface PROPERTIES DESCRIPTION "KWin DBus inter
find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS Auth)
set_package_properties(KF6::AuthCore PROPERTIES
TYPE REQUIRED
PURPOSE "Allows Plasma Mobile to configure Waydroid"
PURPOSE "Allows SHIFT to configure Waydroid"
)
if(PLASMA_MOBILE_LOCAL_KAUTH_INSTALL)
@ -149,6 +149,7 @@ plasma_install_package(${SHIFT_SHELL_PACKAGE_DIR} org.kde.plasma.mobileshell she
add_subdirectory(bin)
add_subdirectory(color-schemes)
add_subdirectory(fonts)
add_subdirectory(icons)
add_subdirectory(wallpapers)
add_subdirectory(components)
@ -165,7 +166,8 @@ if(BUILD_TESTING)
add_subdirectory(tests)
endif()
install(FILES org.kde.plasma.mobileshell.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
install(CODE "file(REMOVE \"\$ENV{DESTDIR}${KDE_INSTALL_FULL_METAINFODIR}/org.kde.plasma.mobileshell.metainfo.xml\")")
install(FILES org.shift.mobile.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
find_program(PlasmaOpenSettings plasma-open-settings)
set_package_properties(PlasmaOpenSettings PROPERTIES

View file

@ -1,6 +1,6 @@
# Hacking on Shift
Shift is a convergent Plasma Mobile shell. This guide covers
Shift is a convergent shell built on Plasma Mobile components. This guide covers
building and testing it locally without polluting your host system.
The approach: keep every build dependency inside a **distrobox** container
@ -89,8 +89,8 @@ sudo zypper install --no-confirm \
### Runtime dependencies (needed for preview, not for compilation)
The nested preview runs the system `plasmashell` binary. It needs a
complete Plasma Mobile runtime so all QML imports resolve:
The nested preview runs the system `plasmashell` binary. It needs the
complete runtime from the Plasma Mobile stack so all QML imports resolve:
```bash
sudo zypper install --no-confirm \
@ -204,6 +204,7 @@ export EGL_PLATFORM=wayland
export QT_QUICK_CONTROLS_STYLE=org.kde.breeze
export QT_QUICK_CONTROLS_MOBILE=true
export PLASMA_PLATFORM=phone:handset
# Compatibility note: the runtime shell package id intentionally remains upstream.
export PLASMA_DEFAULT_SHELL=org.kde.plasma.mobileshell
export QT_FORCE_STDERR_LOGGING=1
exec plasmashell --replace -p org.kde.plasma.mobileshell
@ -212,7 +213,8 @@ ENDSCRIPT
# Expose the project prefix to the host kwin_wayland so it can find
# KWin scripts (convergentwindows) and their QML dependencies.
# Also overlay ~/.config/plasma-mobile so KWin reads the mobile kwinrc
# Also overlay ~/.config/plasma-mobile so KWin reads the mobile kwinrc.
# That path is intentionally preserved for compatibility with existing config handling.
# (envmanager writes convergentwindowsEnabled, Placement, etc. there).
export XDG_DATA_DIRS="$PREFIX/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
export XDG_CONFIG_DIRS="$HOME/.config/plasma-mobile:${XDG_CONFIG_DIRS:-/etc/xdg}"
@ -234,9 +236,9 @@ Make it executable: `chmod +x preview.sh`.
1. `dbus-run-session` spins up an isolated D-Bus session so the nested
compositor doesn't clash with your running desktop.
2. Four environment exports give the **host** `kwin_wayland` access to
the project's `.prefix` (KWin scripts, QML plugins) and to
`~/.config/plasma-mobile` (where envmanager writes convergence
settings like `convergentwindowsEnabled`, `Placement`, etc.).
the project's `.prefix` (KWin scripts, QML plugins) and to
`~/.config/plasma-mobile` (the preserved compatibility path where envmanager writes convergence
settings like `convergentwindowsEnabled`, `Placement`, etc.).
3. `kwin_wayland` opens a window on your current desktop and creates a
Wayland socket named `shift-kwin`. Because of the exports it can
load the `convergentwindows` script, which handles maximising

43
LICENSES/OFL-1.1.txt Normal file
View file

@ -0,0 +1,43 @@
SIL OPEN FONT LICENSE
Version 1.1 - 26 February 2007
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting, or substituting — in part or in whole — any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

View file

@ -1,11 +1,8 @@
# Shift
A fork of KDE Plasma Mobile that adds a desktop-class convergence mode.
Plasma Mobile is a phone shell. It doesn't try to be anything else.
Shift picks up where it leaves off: when you connect a monitor, keyboard,
or mouse, the same device should feel like a desktop. No second OS, no
separate session — one shell that adapts.
Shift is a fork of KDE Plasma Mobile focused on convergence.
When you connect a monitor, keyboard, or mouse, the same shell should still
work as a desktop-style environment. No second OS, no separate session.
## What's different from upstream
@ -15,6 +12,10 @@ that still works. Shift adds a **convergence mode** layer on top — toggled
via `plasmamobilerc` — that swaps in desktop-oriented behaviour without
replacing the phone UI underneath.
Compatibility-sensitive runtime identifiers such as
`org.kde.plasma.mobileshell` remain upstream-looking for now. The product is
SHIFT; the preserved identifiers are part of the current compatibility layer.
Key changes so far:
- **Unified dock** replacing the navigation panel in convergence mode,

View file

@ -1,6 +1,6 @@
# Shift
SHIFT is an open source shell built on KDE Plasma Mobile, designed to adapt fluidly to your computing needs across devices
SHIFT is an independent shell fork focused on convergence. It builds on KDE Plasma Mobile, keeps the upstream phone UI available, and layers desktop-oriented behaviour on top of the same session.
### Desktop demos
@ -8,8 +8,8 @@
![Docked mode](screenshots/quick_DesktopDemo_docked.webm)
![Tiling](screenshots/quick_DesktopDemo_tiling.webm)
Shift is a fork of [plasma-mobile](https://invent.kde.org/plasma/plasma-mobile).
The upstream phone UI is untouched; convergence adds a layer on top.
SHIFT tracks [plasma-mobile](https://invent.kde.org/plasma/plasma-mobile) as its upstream base.
The upstream phone UI remains intact; convergence-specific behaviour is added on top.
### What convergence mode changes
@ -43,6 +43,10 @@ cmake --build build
cmake --install build
```
Compatibility-sensitive identifiers such as `org.kde.plasma.mobileshell`
are intentionally preserved in the runtime and build instructions. They are
part of the current compatibility boundary, not the public product name.
### Disclaimer
SHIFT is an independent project based on KDE Plasma Mobile.
@ -61,7 +65,6 @@ SHIFT is not intended as a direct contribution to KDE Plasma Mobile.
However, if parts of this project are considered useful, contributions or ideas may be proposed upstream in a collaborative manner.
See [pm_README.md](pm_README.md) for the original Plasma Mobile README.
---

View file

@ -5,86 +5,6 @@
Exec=@CMAKE_INSTALL_FULL_LIBEXECDIR@/plasma-dbus-run-session-if-needed @CMAKE_INSTALL_FULL_LIBEXECDIR@/startplasmamobile-dev.sh
Type=Application
DesktopNames=KDE
Name=Plasma Mobile (Development)
Name[ar]=بلازما الجوال (التطوير)
Name[az]=Plasma Mobil (Tərtibat)
Name[ca]=Plasma Mobile (Desenvolupament)
Name[ca@valencia]=Plasma Mobile (desenvolupament)
Name[cs]=Plasma Mobile (Vývojová)
Name[de]=Plasma Mobile (Entwicklung)
Name[en_GB]=Plasma Mobile (Development)
Name[eo]=Plasma Poŝtelefono (Evoluo)
Name[es]=Plasma Mobile (desarrollo)
Name[eu]=Plasma Mugikorra (Garapena)
Name[fi]=Plasma Mobile (kehitys)
Name[fr]=Plasma Mobile (Développement)
Name[gl]=Plasma Mobile (desenvolvemento)
Name[he]=פלזמה לניידים (פיתוח)
Name[hu]=Plasma Mobile (fejlesztői)
Name[ia]=Plasma Mobile (Disveloppamento)
Name[is]=Plasma Mobile (þróunarútgáfa)
Name[it]=Plasma Mobile (sviluppo)
Name[ka]=Plasma Mobile (ბეტა)
Name[ko]=Plasma 모바일(개발)
Name[lv]=Plasma Mobile (izstrādē)
Name[nl]=Plasma Mobile (ontwikkeling)
Name[nn]=Plasma Mobile (utvikling)
Name[pa]= ਈਲ (ਵਿਕਾਸ)
Name[pl]=Przenośna Plazma (Rozwój)
Name[pt]=Plasma Mobile (Desenvolvimento)
Name[pt_BR]=Plasma Mobile (desenvolvimento)
Name[ru]=Plasma Mobile (разработка)
Name[sa]= ईल (विकास)
Name[sk]=Plasma Mobile (Vývoj)
Name[sl]=Plasma Mobile (Razvoj)
Name[sv]=Plasma mobil (utvecklingsversion)
Name[ta]=ி ி (ி)
Name[tr]=Plasma Cep (Geliştirme)
Name[uk]=Мобільна Плазма (версія у розробці)
Name[zh_CN]=Plasma Mobile (开发)
Name[zh_TW]=Plasma
Comment=Plasma Mobile by KDE
Comment[ar]=بلازما الجوال من كيدي
Comment[az]=KDE Plasma Mobil
Comment[ca]=Plasma Mobile, creat per la comunitat KDE
Comment[ca@valencia]=Plasma Mobile, creat per la comunitat KDE
Comment[cs]=Plasma Mobile od KDE
Comment[da]=Plasma Mobile fra KDE
Comment[de]=Plasma Mobile von KDE
Comment[en_GB]=Plasma Mobile by KDE
Comment[eo]=Plasma Mobile de KDE
Comment[es]=Plasma Mobile creado por KDE
Comment[et]=KDE Plasma Mobile
Comment[eu]=Plasma Mugikorra KDEk egina
Comment[fi]=KDE:n Plasma Mobile
Comment[fr]=Plasma Mobile par KDE
Comment[gl]=Plasma Mobile de KDE.
Comment[he]=פלזמה לניידים מבית KDE
Comment[hi]=
Comment[hu]=Plasma Mobile a KDE-től
Comment[ia]=Plasma Mobile per KDE
Comment[id]=Plasma Mobile oleh KDE
Comment[is]=Plasma Mobile frá KDE
Comment[it]=Plasma Mobile creato da KDE
Comment[ka]= Plasma, KDE-
Comment[ko]=KDE Plasma
Comment[lt]=Plasma mobilioji sąsaja pagal KDE
Comment[lv]=KDE Plasma Mobile
Comment[nl]=Plasma Mobile door KDE
Comment[nn]=Plasma Mobile frå KDE
Comment[pa]=KDE
Comment[pl]=Plazma Mobile stworzona przez KDE
Comment[pt]=Plasma Mobile do KDE
Comment[pt_BR]=Plasma Mobile do KDE
Comment[ro]=Plasma Mobile, de către KDE
Comment[ru]=KDE Plasma Mobile
Comment[sa]=
Comment[sk]=Plasma Mobile od KDE
Comment[sl]=Plasma Mobile od KDE
Comment[sv]=Plasma mobil av KDE
Comment[ta]=... ி ி
Comment[tr]=KDE tarafından yapılan Plasma Cep
Comment[uk]=Мобільна Плазма від KDE
Comment[zh_CN]=KDE Plasma Mobile
Comment[zh_TW]= KDE Plasma
Name=SHIFT (Development)
Comment=Convergent SHIFT shell session with development DBus setup
X-KDE-PluginInfo-Version=${PROJECT_VERSION}

View file

@ -6,92 +6,6 @@ Exec=@CMAKE_INSTALL_FULL_LIBEXECDIR@/plasma-dbus-run-session-if-needed ${CMAKE_I
TryExec=${CMAKE_INSTALL_FULL_BINDIR}/startplasmamobile
Type=Application
DesktopNames=KDE
Name=Plasma Mobile
Name[ar]=بلازما الجوال
Name[az]=Plasma Mobil
Name[ca]=Plasma Mobile
Name[ca@valencia]=Plasma Mobile
Name[cs]=Plasma Mobile
Name[da]=Plasma Mobile
Name[de]=Plasma Mobile
Name[en_GB]=Plasma Mobile
Name[eo]=Plasma Poŝtelefono
Name[es]=Plasma Mobile
Name[et]=Plasma Mobile
Name[eu]=Plasma Mugikorra
Name[fi]=Plasma Mobile
Name[fr]=Plasma Mobile
Name[gl]=Plasma Mobile
Name[he]=פלזמה לניידים
Name[hi]=
Name[hu]=Plasma Mobile
Name[ia]=Plasma Mobile
Name[id]=Plasma Mobile
Name[is]=Plasma Mobile
Name[it]=Plasma Mobile
Name[ka]=Plasma Mobile
Name[ko]=Plasma
Name[lt]=Plasma mobilioji sąsaja
Name[lv]=Plasma Mobile
Name[nl]=Plasma Mobile
Name[nn]=Plasma Mobile
Name[pa]=
Name[pl]=Przenośna Plazma
Name[pt]=Plasma Mobile
Name[pt_BR]=Plasma Mobile
Name[ro]=Plasma Mobile
Name[ru]=Plasma Mobile
Name[sa]=
Name[sk]=Plasma Mobile
Name[sl]=Plasma Mobile
Name[sv]=Plasma mobil
Name[ta]=ி ி
Name[tr]=Plasma Cep
Name[uk]=Мобільна Плазма
Name[zh_CN]=Plasma Mobile
Name[zh_TW]=Plasma
Comment=Plasma Mobile by KDE
Comment[ar]=بلازما الجوال من كيدي
Comment[az]=KDE Plasma Mobil
Comment[ca]=Plasma Mobile, creat per la comunitat KDE
Comment[ca@valencia]=Plasma Mobile, creat per la comunitat KDE
Comment[cs]=Plasma Mobile od KDE
Comment[da]=Plasma Mobile fra KDE
Comment[de]=Plasma Mobile von KDE
Comment[en_GB]=Plasma Mobile by KDE
Comment[eo]=Plasma Mobile de KDE
Comment[es]=Plasma Mobile creado por KDE
Comment[et]=KDE Plasma Mobile
Comment[eu]=Plasma Mugikorra KDEk egina
Comment[fi]=KDE:n Plasma Mobile
Comment[fr]=Plasma Mobile par KDE
Comment[gl]=Plasma Mobile de KDE.
Comment[he]=פלזמה לניידים מבית KDE
Comment[hi]=
Comment[hu]=Plasma Mobile a KDE-től
Comment[ia]=Plasma Mobile per KDE
Comment[id]=Plasma Mobile oleh KDE
Comment[is]=Plasma Mobile frá KDE
Comment[it]=Plasma Mobile creato da KDE
Comment[ka]= Plasma, KDE-
Comment[ko]=KDE Plasma
Comment[lt]=Plasma mobilioji sąsaja pagal KDE
Comment[lv]=KDE Plasma Mobile
Comment[nl]=Plasma Mobile door KDE
Comment[nn]=Plasma Mobile frå KDE
Comment[pa]=KDE
Comment[pl]=Plazma Mobile stworzona przez KDE
Comment[pt]=Plasma Mobile do KDE
Comment[pt_BR]=Plasma Mobile do KDE
Comment[ro]=Plasma Mobile, de către KDE
Comment[ru]=KDE Plasma Mobile
Comment[sa]=
Comment[sk]=Plasma Mobile od KDE
Comment[sl]=Plasma Mobile od KDE
Comment[sv]=Plasma mobil av KDE
Comment[ta]=... ி ி
Comment[tr]=KDE tarafından yapılan Plasma Cep
Comment[uk]=Мобільна Плазма від KDE
Comment[zh_CN]=KDE Plasma Mobile
Comment[zh_TW]= KDE Plasma
Name=SHIFT
Comment=Convergent SHIFT shell session
X-KDE-PluginInfo-Version=${PROJECT_VERSION}

View file

@ -60,6 +60,8 @@ Item {
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
Layout.preferredHeight: width
source: "low-brightness"
isMask: true
color: Kirigami.Theme.textColor
}
PC3.Slider {
@ -105,6 +107,8 @@ Item {
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
Layout.preferredHeight: width
source: "high-brightness"
isMask: true
color: Kirigami.Theme.textColor
}
}
}

View file

@ -90,6 +90,10 @@ QuickSettingsDelegate {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: width
source: root.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
ColumnLayout {

View file

@ -86,6 +86,10 @@ QuickSettingsDelegate {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: width
source: root.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
}
}

View file

@ -142,6 +142,10 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: implicitWidth
source: root.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
// Indicator bar
@ -235,6 +239,10 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: implicitWidth
source: "go-next-symbolic"
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
opacity: 0.5
}
}

View file

@ -64,6 +64,10 @@ QQC2.Popup {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: implicitWidth
source: "preferences-desktop-notification-symbolic"
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
ColumnLayout {
@ -167,6 +171,10 @@ QQC2.Popup {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: implicitWidth
source: model.iconName ? model.iconName : (model.icon ? model.icon : "")
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
ColumnLayout {
@ -194,6 +202,10 @@ QQC2.Popup {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: implicitWidth
source: "go-next-symbolic"
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
opacity: 0.45
}
}

View file

@ -135,6 +135,8 @@ Controls.Drawer {
width: Kirigami.Units.iconSizes.large
height: width
source: "view-preview"
isMask: true
color: Kirigami.Theme.textColor
visible: !walliePreview.visible
}

View file

@ -146,6 +146,8 @@ Window {
transformOrigin: Item.Center
rotation: root.angle
source: root.iconSource
isMask: true
color: Kirigami.Theme.textColor
}
}

View file

@ -195,6 +195,8 @@ Window {
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
source: "settings-configure"
isMask: true
color: Kirigami.Theme.textColor
}
PlasmaComponents.Label {
text: i18n("Open audio settings")

View file

@ -227,6 +227,10 @@ Item {
source: 'arrow-down'
implicitHeight: Kirigami.Units.iconSizes.small
implicitWidth: Kirigami.Units.iconSizes.small
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom

View file

@ -30,6 +30,10 @@ Item {
width: Math.min(parent.width, parent.height)
height: width
anchors.centerIn: parent
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
Controls.ToolTip.text: model.toolTipTitle ? model.toolTipTitle : (model.title ? model.title : "")

View file

@ -13,7 +13,6 @@ import org.kde.kirigami as Kirigami
import org.kde.kitemmodels
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.workspace.components 2.0 as PW
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.battery // needed for charging state
@ -21,6 +20,35 @@ import org.kde.plasma.private.battery // needed for charging state
RowLayout {
property real textPixelSize: Kirigami.Units.gridUnit * 0.6
function batteryIconName(percent, charging) {
let name;
if (percent >= 95) {
name = "battery-100";
} else if (percent >= 85) {
name = "battery-090";
} else if (percent >= 75) {
name = "battery-080";
} else if (percent >= 65) {
name = "battery-070";
} else if (percent >= 55) {
name = "battery-060";
} else if (percent >= 45) {
name = "battery-050";
} else if (percent >= 35) {
name = "battery-040";
} else if (percent >= 25) {
name = "battery-030";
} else if (percent >= 15) {
name = "battery-020";
} else if (percent > 5) {
name = "battery-010";
} else {
name = "battery-000";
}
return charging ? name + "-charging" : name;
}
visible: MobileShell.BatteryInfo.isVisible
ListView {
@ -51,16 +79,17 @@ RowLayout {
height: batteryRepeater.height
PW.BatteryIcon {
Kirigami.Icon {
id: battery
Layout.alignment: Qt.AlignVCenter
Layout.fillHeight: true
width: batteryLabel.height
hasBattery: PluggedIn
percent: Percent
pluggedIn: ChargeState === BatteryControlModel.Charging
source: PluggedIn ? batteryIconName(Percent, ChargeState === BatteryControlModel.Charging) : "battery-missing"
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
PlasmaComponents.Label {

View file

@ -16,6 +16,10 @@ Kirigami.Icon {
id: connectionIcon
source: MobileShell.BluetoothInfo.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
visible: MobileShell.BluetoothInfo.isVisible
}

View file

@ -33,6 +33,10 @@ Item {
anchors.fill: parent
visible: !connectingIndicator.visible
source: connectionIcon.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
}
// Connecting indicator

View file

@ -33,6 +33,10 @@ Item {
height: parent.height
source: MobileShell.SignalStrengthInfo.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
// don't show mobile indicator icon if the networkmanager one is already showing
visible: (!isInternetIndicatorMobileData || wirelessStatus.hotspotSSID.length !== 0) && MobileShell.SignalStrengthInfo.showIndicator

View file

@ -18,6 +18,10 @@ Kirigami.Icon {
id: paIcon
source: MobileShell.AudioInfo.icon
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
isMask: true
color: Kirigami.Theme.textColor
visible: MobileShell.AudioInfo.isVisible
}

View file

@ -47,6 +47,7 @@ MobileShellSettings::MobileShellSettings(QObject *parent)
Q_EMIT gamingModeEnabledChanged();
Q_EMIT gamingDismissHintEnabledChanged();
Q_EMIT dynamicTilingEnabledChanged();
Q_EMIT dynamicTilingWindowRequestChanged();
Q_EMIT snapLayoutsEnabledChanged();
Q_EMIT allowLogoutChanged();
}
@ -291,6 +292,40 @@ void MobileShellSettings::setDynamicTilingEnabled(bool enabled)
m_config->sync();
}
QString MobileShellSettings::dynamicTilingWindowRequestAction() const
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
return group.readEntry("dynamicTilingWindowRequestAction", QString{});
}
QString MobileShellSettings::dynamicTilingWindowRequestId() const
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
return group.readEntry("dynamicTilingWindowRequestId", QString{});
}
int MobileShellSettings::dynamicTilingWindowRequestSerial() const
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
return group.readEntry("dynamicTilingWindowRequestSerial", 0);
}
void MobileShellSettings::requestDynamicTilingWindowAction(const QString &windowId, const QString &action)
{
if (windowId.isEmpty() || action.isEmpty()) {
return;
}
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
const int serial = group.readEntry("dynamicTilingWindowRequestSerial", 0) + 1;
group.writeEntry("dynamicTilingWindowRequestId", windowId, KConfigGroup::Notify);
group.writeEntry("dynamicTilingWindowRequestAction", action, KConfigGroup::Notify);
group.writeEntry("dynamicTilingWindowRequestSerial", serial, KConfigGroup::Notify);
m_config->sync();
Q_EMIT dynamicTilingWindowRequestChanged();
}
bool MobileShellSettings::snapLayoutsEnabled() const
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};

View file

@ -59,6 +59,9 @@ class MobileShellSettings : public QObject
// Dynamic (BSP) window tiling — only meaningful in convergence mode.
// When false, KWin's native quick-tile behaviour is used unmodified.
Q_PROPERTY(bool dynamicTilingEnabled READ dynamicTilingEnabled WRITE setDynamicTilingEnabled NOTIFY dynamicTilingEnabledChanged)
Q_PROPERTY(QString dynamicTilingWindowRequestAction READ dynamicTilingWindowRequestAction NOTIFY dynamicTilingWindowRequestChanged)
Q_PROPERTY(QString dynamicTilingWindowRequestId READ dynamicTilingWindowRequestId NOTIFY dynamicTilingWindowRequestChanged)
Q_PROPERTY(int dynamicTilingWindowRequestSerial READ dynamicTilingWindowRequestSerial NOTIFY dynamicTilingWindowRequestChanged)
// Snap layout picker — only meaningful in convergence mode when dynamic tiling is off.
Q_PROPERTY(bool snapLayoutsEnabled READ snapLayoutsEnabled WRITE setSnapLayoutsEnabled NOTIFY snapLayoutsEnabledChanged)
@ -288,6 +291,10 @@ public:
*/
bool dynamicTilingEnabled() const;
void setDynamicTilingEnabled(bool enabled);
QString dynamicTilingWindowRequestAction() const;
QString dynamicTilingWindowRequestId() const;
int dynamicTilingWindowRequestSerial() const;
Q_INVOKABLE void requestDynamicTilingWindowAction(const QString &windowId, const QString &action);
/**
* Whether the SHIFT snap layout picker is enabled.
@ -346,6 +353,7 @@ Q_SIGNALS:
void gamingModeEnabledChanged();
void gamingDismissHintEnabledChanged();
void dynamicTilingEnabledChanged();
void dynamicTilingWindowRequestChanged();
void snapLayoutsEnabledChanged();
void allowLogoutChanged();
void lockscreenLeftButtonActionChanged();

View file

@ -5,7 +5,7 @@
# Folio Homescreen
This is the paged homescreen for Plasma Mobile.
This is the paged homescreen for SHIFT.
### How it works

View file

@ -98,6 +98,13 @@ void HomeScreen::triggerOverview() const
QDBusConnection::sessionBus().send(message);
}
void HomeScreen::triggerMinimizeAll() const
{
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.kglobalaccel", "/component/kwin", "org.kde.kglobalaccel.Component", "invokeShortcut");
message.setArguments({QStringLiteral("MinimizeAll")});
QDBusConnection::sessionBus().send(message);
}
void HomeScreen::activateVirtualDesktop(const QVariant &desktop) const
{
if (!desktop.isValid() || desktop.toString().isEmpty()) {
@ -108,6 +115,22 @@ void HomeScreen::activateVirtualDesktop(const QVariant &desktop) const
virtualDesktopInfo.requestActivate(desktop);
}
void HomeScreen::createVirtualDesktop() const
{
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
virtualDesktopInfo.requestCreateDesktop(virtualDesktopInfo.numberOfDesktops());
}
void HomeScreen::removeLastVirtualDesktop() const
{
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
if (virtualDesktopInfo.numberOfDesktops() <= 1) {
return;
}
virtualDesktopInfo.requestRemoveDesktop(virtualDesktopInfo.numberOfDesktops() - 1);
}
void HomeScreen::emptyTrash() const
{
QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kio.trash"),

View file

@ -51,7 +51,10 @@ public:
void configChanged() override;
Q_INVOKABLE void triggerOverview() const;
Q_INVOKABLE void triggerMinimizeAll() const;
Q_INVOKABLE void activateVirtualDesktop(const QVariant &desktop) const;
Q_INVOKABLE void createVirtualDesktop() const;
Q_INVOKABLE void removeLastVirtualDesktop() const;
Q_INVOKABLE void emptyTrash() const;
FolioSettings *folioSettings();

View file

@ -118,7 +118,7 @@
"Name[uk]": "Фоліо",
"Name[zh_CN]": "Folio",
"Name[zh_TW]": "Folio",
"Website": "https://plasma-mobile.org"
"Website": "https://invent.kde.org/marcoa/shift-shell"
},
"X-Plasma-API-Minimum-Version": "6.0",
"X-Plasma-ContainmentType": "Desktop",

View file

@ -50,11 +50,13 @@ Item {
anchors.rightMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
anchors.fill: parent
Kirigami.SearchField {
QQC2.TextField {
id: searchField
onTextChanged: folio.ApplicationListSearchModel.setFilterFixedString(text)
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
leftPadding: Kirigami.Units.iconSizes.small + Kirigami.Units.largeSpacing * 2
rightPadding: clearSearchArea.visible ? clearSearchArea.width + Kirigami.Units.largeSpacing : Kirigami.Units.largeSpacing
background: Rectangle {
radius: Kirigami.Units.cornerRadius
@ -76,6 +78,42 @@ Item {
font.weight: Font.Bold
Kirigami.Icon {
anchors.left: parent.left
anchors.leftMargin: Kirigami.Units.largeSpacing
anchors.verticalCenter: parent.verticalCenter
width: Kirigami.Units.iconSizes.small
height: width
source: "search"
isMask: true
color: Kirigami.Theme.textColor
opacity: 0.65
}
MouseArea {
id: clearSearchArea
anchors.right: parent.right
anchors.rightMargin: Kirigami.Units.smallSpacing
anchors.verticalCenter: parent.verticalCenter
width: Kirigami.Units.iconSizes.smallMedium
height: width
visible: searchField.text.length > 0
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: searchField.clear()
Kirigami.Icon {
anchors.centerIn: parent
width: Kirigami.Units.iconSizes.small
height: width
source: "window-close-symbolic"
isMask: true
color: Kirigami.Theme.textColor
opacity: clearSearchArea.containsMouse ? 0.9 : 0.65
}
}
Connections {
target: folio.HomeScreenState
function onViewStateChanged(): void {

View file

@ -157,6 +157,8 @@ Rectangle {
height: width
source: tile.catIcon
active: tileArea.containsMouse || tile.isActive
isMask: true
color: tile.isActive ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor
}
PlasmaComponents.Label {

View file

@ -13,6 +13,7 @@ import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.taskmanager as TaskManager
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
import org.kde.kirigami as Kirigami
import QtQuick.Controls as Controls
import QtQuick.Templates as T
@ -93,17 +94,54 @@ MouseArea {
property real pagerButtonWidth: showPager ? Math.min(root.height, Kirigami.Units.gridUnit * 2.5) : 0
readonly property int pagerLeftCount: showPager ? Math.ceil(virtualDesktopInfo.numberOfDesktops / 2) : 0
readonly property int pagerRightCount: showPager ? virtualDesktopInfo.numberOfDesktops - pagerLeftCount : 0
property real desktopButtonWidth: convergenceMode ? root.height : 0
property real trashButtonWidth: convergenceMode ? root.height : 0
property real searchButtonWidth: convergenceMode ? root.height : 0
readonly property real leftControlsWidth: convergenceMode ? navButtonWidth + pagerLeftCount * pagerButtonWidth : 0
readonly property real leftControlsWidth: convergenceMode ? navButtonWidth + desktopButtonWidth + pagerLeftCount * pagerButtonWidth : 0
readonly property real rightControlsWidth: convergenceMode ? navButtonWidth + searchButtonWidth + trashButtonWidth + pagerRightCount * pagerButtonWidth : 0
readonly property real dockCenterX: convergenceMode
? leftControlsWidth + (root.width - leftControlsWidth - rightControlsWidth) / 2
: root.width / 2
Behavior on pagerButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on desktopButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on trashButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on searchButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
property Item pendingDockToolTipItem: null
property Item activeDockToolTipItem: null
Timer {
id: dockToolTipTimer
interval: Kirigami.Units.toolTipDelay
onTriggered: {
root.activeDockToolTipItem = root.pendingDockToolTipItem
root.pendingDockToolTipItem = null
dockToolTipHideTimer.restart()
}
}
Timer {
id: dockToolTipHideTimer
interval: Kirigami.Units.toolTipDelay * 3
onTriggered: root.hideDockToolTip(root.activeDockToolTipItem)
}
function requestDockToolTip(item) {
activeDockToolTipItem = null
pendingDockToolTipItem = item
dockToolTipHideTimer.stop()
dockToolTipTimer.restart()
}
function hideDockToolTip(item) {
if (!item || pendingDockToolTipItem === item || activeDockToolTipItem === item) {
pendingDockToolTipItem = null
activeDockToolTipItem = null
dockToolTipTimer.stop()
dockToolTipHideTimer.stop()
}
}
function pagerDesktopName(index) {
let names = virtualDesktopInfo.desktopNames
if (names && index < names.length && String(names[index]).length > 0)
@ -139,12 +177,44 @@ MouseArea {
return result
}
function taskActivities(taskModel) {
let activities = taskModel.Activities
return activities ? activities : []
}
function taskWindowId(taskModel) {
let winIds = taskModel.WinIdList
return winIds && winIds.length === 1 ? String(winIds[0]) : ""
}
function activityName(activityId) {
let name = activityInfo.activityName(activityId)
return name && name.length > 0 ? name : i18n("Activity")
}
function menuActivityIds(taskActivities) {
let runningActivities = activityInfo.runningActivities()
if (!runningActivities || runningActivities.length <= 1) {
return []
}
let result = []
for (let i = 0; i < runningActivities.length; ++i) {
let activityId = runningActivities[i]
if (taskActivities.length === 1 && String(taskActivities[0]) === String(activityId)) {
continue
}
result.push(activityId)
}
return result
}
// Returns the desktop ID of the pager button under screen-space x, or ""
function pagerButtonDesktopAt(x) {
if (!showPager) return ""
let ids = virtualDesktopInfo.desktopIds
for (let i = 0; i < pagerLeftCount; ++i) {
let bx = navButtonWidth + i * pagerButtonWidth
let bx = navButtonWidth + desktopButtonWidth + i * pagerButtonWidth
if (x >= bx && x < bx + pagerButtonWidth)
return (ids && i < ids.length) ? String(ids[i]) : ""
}
@ -235,11 +305,7 @@ MouseArea {
Keys.onEnterPressed: MobileShellState.ShellDBusClient.openHomeScreen()
Keys.onSpacePressed: MobileShellState.ShellDBusClient.openHomeScreen()
Keys.onRightPressed: {
let first = repeater.itemAt(0)
if (first) { first.keyboardFocus(); return }
let firstTask = taskRepeater.itemAt(0)
if (firstTask) { firstTask.forceActiveFocus(); return }
searchButton.forceActiveFocus()
desktopButton.forceActiveFocus()
}
KeyboardHighlight {
@ -264,6 +330,8 @@ MouseArea {
height: width
source: "start-here-shift"
active: homeMouseArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
MouseArea {
@ -275,6 +343,125 @@ MouseArea {
}
}
// Peek at Desktop button (convergence mode, next to Home)
Rectangle {
id: desktopButton
visible: root.convergenceMode || opacity > 0
enabled: root.convergenceMode
opacity: root.convergenceMode ? 1 : 0
activeFocusOnTab: root.convergenceMode
x: root.navButtonWidth
y: 0
width: root.desktopButtonWidth
height: root.height
color: "transparent"
function toggleDesktop() {
WindowPlugin.WindowUtil.requestShowingDesktop(!WindowPlugin.WindowUtil.isShowingDesktop)
}
Behavior on opacity {
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad }
}
Accessible.role: Accessible.Button
Accessible.name: WindowPlugin.WindowUtil.isShowingDesktop ? i18n("Stop Peeking at Desktop") : i18n("Peek at Desktop")
Accessible.onPressAction: desktopButton.toggleDesktop()
Keys.onReturnPressed: desktopButton.toggleDesktop()
Keys.onEnterPressed: desktopButton.toggleDesktop()
Keys.onSpacePressed: desktopButton.toggleDesktop()
Keys.onLeftPressed: homeButton.forceActiveFocus()
Keys.onRightPressed: {
let first = repeater.itemAt(0)
if (first) { first.keyboardFocus(); return }
let firstTask = taskRepeater.itemAt(0)
if (firstTask) { firstTask.forceActiveFocus(); return }
searchButton.forceActiveFocus()
}
KeyboardHighlight {
anchors.fill: parent
visible: desktopButton.activeFocus
}
Rectangle {
anchors.fill: parent
anchors.margins: root.dockItemInset
radius: Kirigami.Units.cornerRadius
color: root.dockItemColor(desktopMouseArea.containsPress, desktopMouseArea.containsMouse, WindowPlugin.WindowUtil.isShowingDesktop)
Behavior on color {
ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
}
}
Kirigami.Icon {
anchors.centerIn: parent
width: root.dockIconSize
height: width
source: "user-desktop"
active: desktopMouseArea.containsMouse || WindowPlugin.WindowUtil.isShowingDesktop
isMask: true
color: Kirigami.Theme.textColor
}
PC3.ToolTip {
visible: root.activeDockToolTipItem === desktopButton && desktopMouseArea.containsMouse && !desktopMouseArea.containsPress && !desktopContextMenu.opened
text: desktopButton.Accessible.name
}
MouseArea {
id: desktopMouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: root.convergenceMode ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: (mouse) => {
root.hideDockToolTip(desktopButton)
if (mouse.button === Qt.RightButton) {
desktopContextMenu.open()
} else {
desktopButton.toggleDesktop()
}
}
onPressAndHold: {
root.hideDockToolTip(desktopButton)
desktopContextMenu.open()
haptics.buttonVibrate()
}
onContainsMouseChanged: {
if (containsMouse) {
root.requestDockToolTip(desktopButton)
} else {
root.hideDockToolTip(desktopButton)
}
}
onPressedChanged: {
if (pressed) {
root.hideDockToolTip(desktopButton)
}
}
}
PC3.Menu {
id: desktopContextMenu
popupType: T.Popup.Window
PC3.MenuItem {
icon.name: "user-desktop"
text: desktopButton.Accessible.name
onTriggered: desktopButton.toggleDesktop()
}
PC3.MenuItem {
icon.name: "window-minimize-symbolic"
text: i18n("Minimize All Windows")
enabled: !WindowPlugin.WindowUtil.isShowingDesktop
onTriggered: root.folio.triggerMinimizeAll()
}
}
}
// Overview button (convergence mode, right end)
Rectangle {
id: overviewButton
@ -323,8 +510,10 @@ MouseArea {
anchors.centerIn: parent
width: root.dockIconSize
height: width
source: "view-grid-symbolic"
source: "activities"
active: overviewMouseArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
MouseArea {
@ -365,7 +554,7 @@ MouseArea {
if (lastTask) { lastTask.forceActiveFocus(); return }
let lastFav = repeater.itemAt(repeater.count - 1)
if (lastFav) { lastFav.keyboardFocus(); return }
homeButton.forceActiveFocus()
desktopButton.forceActiveFocus()
}
Keys.onRightPressed: overviewButton.forceActiveFocus()
@ -391,10 +580,12 @@ MouseArea {
height: width
source: "search"
active: searchMouseArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
PC3.ToolTip {
visible: searchMouseArea.containsMouse
visible: root.activeDockToolTipItem === searchButton && searchMouseArea.containsMouse && !searchMouseArea.containsPress
text: i18n("Search")
}
@ -403,7 +594,22 @@ MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: root.convergenceMode ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: root.folio.HomeScreenState.openSearchWidget()
onClicked: {
root.hideDockToolTip(searchButton)
root.folio.HomeScreenState.openSearchWidget()
}
onContainsMouseChanged: {
if (containsMouse) {
root.requestDockToolTip(searchButton)
} else {
root.hideDockToolTip(searchButton)
}
}
onPressedChanged: {
if (pressed) {
root.hideDockToolTip(searchButton)
}
}
}
}
@ -427,7 +633,7 @@ MouseArea {
return root.pagerButtonDesktopAt(cx) === desktopId
}
x: root.navButtonWidth + index * root.pagerButtonWidth
x: root.navButtonWidth + root.desktopButtonWidth + index * root.pagerButtonWidth
y: 0
width: root.pagerButtonWidth
height: root.height
@ -452,7 +658,7 @@ MouseArea {
}
PC3.ToolTip {
visible: leftPagerHover.containsMouse
visible: root.activeDockToolTipItem === leftDesktopBtn && leftPagerHover.containsMouse && !leftPagerHover.containsPress && !leftPagerContextMenu.opened
text: root.pagerDesktopName(leftDesktopBtn.index)
}
@ -460,10 +666,55 @@ MouseArea {
id: leftPagerHover
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: {
if (leftDesktopBtn.desktopId)
onClicked: (mouse) => {
root.hideDockToolTip(leftDesktopBtn)
if (mouse.button === Qt.RightButton) {
leftPagerContextMenu.open()
} else if (leftDesktopBtn.desktopId) {
root.folio.activateVirtualDesktop(leftDesktopBtn.desktopId)
}
}
onPressAndHold: {
root.hideDockToolTip(leftDesktopBtn)
leftPagerContextMenu.open()
haptics.buttonVibrate()
}
onContainsMouseChanged: {
if (containsMouse) {
root.requestDockToolTip(leftDesktopBtn)
} else {
root.hideDockToolTip(leftDesktopBtn)
}
}
onPressedChanged: {
if (pressed) {
root.hideDockToolTip(leftDesktopBtn)
}
}
}
PC3.Menu {
id: leftPagerContextMenu
popupType: T.Popup.Window
PC3.MenuItem {
icon.name: "list-add"
text: i18n("Add Virtual Desktop")
onTriggered: root.folio.createVirtualDesktop()
}
PC3.MenuItem {
icon.name: "list-remove"
text: i18n("Remove Virtual Desktop")
enabled: virtualDesktopInfo.numberOfDesktops > 1
onTriggered: root.folio.removeLastVirtualDesktop()
}
Controls.MenuSeparator {}
PC3.MenuItem {
icon.name: "preferences-desktop-virtual"
text: i18n("Configure Virtual Desktops…")
onTriggered: MobileShell.ShellUtil.executeCommand("plasma-open-settings kcm_kwin_virtualdesktops")
}
}
}
@ -515,7 +766,7 @@ MouseArea {
}
PC3.ToolTip {
visible: rightPagerHover.containsMouse
visible: root.activeDockToolTipItem === rightDesktopBtn && rightPagerHover.containsMouse && !rightPagerHover.containsPress && !rightPagerContextMenu.opened
text: root.pagerDesktopName(rightDesktopBtn.desktopIndex)
}
@ -523,10 +774,55 @@ MouseArea {
id: rightPagerHover
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: {
if (rightDesktopBtn.desktopId)
onClicked: (mouse) => {
root.hideDockToolTip(rightDesktopBtn)
if (mouse.button === Qt.RightButton) {
rightPagerContextMenu.open()
} else if (rightDesktopBtn.desktopId) {
root.folio.activateVirtualDesktop(rightDesktopBtn.desktopId)
}
}
onPressAndHold: {
root.hideDockToolTip(rightDesktopBtn)
rightPagerContextMenu.open()
haptics.buttonVibrate()
}
onContainsMouseChanged: {
if (containsMouse) {
root.requestDockToolTip(rightDesktopBtn)
} else {
root.hideDockToolTip(rightDesktopBtn)
}
}
onPressedChanged: {
if (pressed) {
root.hideDockToolTip(rightDesktopBtn)
}
}
}
PC3.Menu {
id: rightPagerContextMenu
popupType: T.Popup.Window
PC3.MenuItem {
icon.name: "list-add"
text: i18n("Add Virtual Desktop")
onTriggered: root.folio.createVirtualDesktop()
}
PC3.MenuItem {
icon.name: "list-remove"
text: i18n("Remove Virtual Desktop")
enabled: virtualDesktopInfo.numberOfDesktops > 1
onTriggered: root.folio.removeLastVirtualDesktop()
}
Controls.MenuSeparator {}
PC3.MenuItem {
icon.name: "preferences-desktop-virtual"
text: i18n("Configure Virtual Desktops…")
onTriggered: MobileShell.ShellUtil.executeCommand("plasma-open-settings kcm_kwin_virtualdesktops")
}
}
}
@ -611,10 +907,12 @@ MouseArea {
height: width
source: trashFilesModel.count > 0 ? "user-trash-full" : "user-trash"
active: trashMouseArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
PC3.ToolTip {
visible: trashMouseArea.containsMouse
visible: root.activeDockToolTipItem === trashButton && trashMouseArea.containsMouse && !trashMouseArea.containsPress && !trashContextMenu.opened
text: trashFilesModel.count > 0
? i18np("Trash — 1 item", "Trash — %1 items", trashFilesModel.count)
: i18n("Trash")
@ -627,12 +925,25 @@ MouseArea {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: (mouse) => {
root.hideDockToolTip(trashButton)
if (mouse.button === Qt.RightButton) {
trashContextMenu.open()
} else {
Qt.openUrlExternally("trash:/")
}
}
onContainsMouseChanged: {
if (containsMouse) {
root.requestDockToolTip(trashButton)
} else {
root.hideDockToolTip(trashButton)
}
}
onPressedChanged: {
if (pressed) {
root.hideDockToolTip(trashButton)
}
}
}
PC3.Menu {
@ -800,7 +1111,7 @@ MouseArea {
prevDelegate.keyboardFocus();
event.accepted = true;
} else if (root.convergenceMode) {
homeButton.forceActiveFocus();
desktopButton.forceActiveFocus();
event.accepted = true;
}
}
@ -1294,7 +1605,16 @@ MouseArea {
Kirigami.Icon {
anchors.fill: parent
source: "window-close"
source: "window-close-symbolic"
isMask: true
color: "white"
}
Rectangle {
anchors.fill: parent
radius: width / 2
color: Qt.rgba(0, 0, 0, 0.55)
z: -1
}
}
}
@ -1353,7 +1673,9 @@ MouseArea {
readonly property bool isGroupParent: taskDelegate.model.IsGroupParent === true
readonly property bool dynamicTilingActive: root.convergenceMode && ShellSettings.Settings.dynamicTilingEnabled
readonly property bool showFreeGeometryActions: !taskDelegate.isGroupParent && !taskDelegate.dynamicTilingActive
readonly property bool canRequestDynamicTiling: taskDelegate.dynamicTilingActive && !taskDelegate.isGroupParent && root.taskWindowId(taskDelegate.model) !== ""
readonly property bool canChangeVirtualDesktops: taskDelegate.model.IsVirtualDesktopsChangeable === true
readonly property bool canChangeActivities: activityInfo.numberOfRunningActivities > 1 && !taskDelegate.isGroupParent
Accessible.role: Accessible.Button
Accessible.name: taskDelegate.model.display || ""
@ -1385,7 +1707,7 @@ MouseArea {
if (prev) { prev.forceActiveFocus(); return }
let lastFav = repeater.itemAt(repeater.count - 1)
if (lastFav) { lastFav.keyboardFocus(); return }
homeButton.forceActiveFocus()
desktopButton.forceActiveFocus()
}
Keys.onRightPressed: {
let next = taskRepeater.itemAt(taskDelegate.index + 1)
@ -1579,6 +1901,27 @@ MouseArea {
height: visible ? implicitHeight : 0
}
Controls.MenuSeparator {
visible: taskDelegate.canRequestDynamicTiling
height: visible ? implicitHeight : 0
}
PC3.MenuItem {
icon.name: "window"
text: i18n("Float Window")
visible: taskDelegate.canRequestDynamicTiling
height: visible ? implicitHeight : 0
onClicked: ShellSettings.Settings.requestDynamicTilingWindowAction(root.taskWindowId(taskDelegate.model), "float")
}
PC3.MenuItem {
icon.name: "view-grid-symbolic"
text: i18n("Tile Window")
visible: taskDelegate.canRequestDynamicTiling
height: visible ? implicitHeight : 0
onClicked: ShellSettings.Settings.requestDynamicTilingWindowAction(root.taskWindowId(taskDelegate.model), "tile")
}
PC3.MenuItem {
icon.name: "transform-move"
text: i18n("Move")
@ -1673,6 +2016,33 @@ MouseArea {
height: visible ? implicitHeight : 0
onClicked: tasksModel.requestNewVirtualDesktop(tasksModel.makeModelIndex(taskDelegate.index))
}
Controls.MenuSeparator {
visible: taskDelegate.canChangeActivities
height: visible ? implicitHeight : 0
}
PC3.MenuItem {
icon.name: "activities"
text: root.taskActivities(taskDelegate.model).length === 0 ? i18n("Show Only on Current Activity") : i18n("Show on All Activities")
visible: taskDelegate.canChangeActivities
height: visible ? implicitHeight : 0
onClicked: tasksModel.requestActivities(tasksModel.makeModelIndex(taskDelegate.index),
root.taskActivities(taskDelegate.model).length === 0 ? [activityInfo.currentActivity] : [])
}
Instantiator {
model: taskDelegate.canChangeActivities ? root.menuActivityIds(root.taskActivities(taskDelegate.model)) : []
delegate: PC3.MenuItem {
required property var modelData
icon.name: activityInfo.activityIcon(modelData)
text: i18n("Move to %1", root.activityName(modelData))
onTriggered: tasksModel.requestActivities(
tasksModel.makeModelIndex(taskDelegate.index), [modelData])
}
onObjectAdded: (idx, obj) => taskContextMenu.insertItem(taskContextMenu.count, obj)
onObjectRemoved: (idx, obj) => taskContextMenu.removeItem(obj)
}
}
}
}

View file

@ -513,6 +513,8 @@ Item {
source: 'arrow-up'
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
isMask: true
color: Kirigami.Theme.textColor
implicitHeight: Kirigami.Units.iconSizes.small
implicitWidth: Kirigami.Units.iconSizes.small

View file

@ -53,6 +53,8 @@ MouseArea {
height: width
source: button.iconName
active: button.containsMouse || button.checked
isMask: true
color: Kirigami.Theme.textColor
}
PC3.ToolTip {

View file

@ -599,6 +599,8 @@ Window {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
source: "system-run"
isMask: true
color: Kirigami.Theme.textColor
}
PC3.Label {
@ -1022,6 +1024,8 @@ Window {
source: "starred"
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
isMask: true
color: Kirigami.Theme.textColor
}
}
}
@ -1036,6 +1040,8 @@ Window {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
source: "input-gaming"
isMask: true
color: Kirigami.Theme.textColor
}
Repeater {

View file

@ -201,6 +201,8 @@ Window {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
Layout.alignment: Qt.AlignVCenter
isMask: true
color: "white"
}
QQC2.Label {

View file

@ -319,6 +319,8 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: "low-brightness"
isMask: true
color: Kirigami.Theme.textColor
}
PC3.Slider {
@ -380,6 +382,8 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: "high-brightness"
isMask: true
color: Kirigami.Theme.textColor
}
}
}
@ -403,6 +407,8 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: "audio-volume-low"
isMask: true
color: Kirigami.Theme.textColor
}
PC3.Slider {
@ -462,6 +468,8 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: "audio-volume-high"
isMask: true
color: Kirigami.Theme.textColor
}
}
}
@ -555,6 +563,8 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
source: "games-achievements"
isMask: true
color: Kirigami.Theme.textColor
}
PC3.Label {
text: GamingShell.GameModeControl.active
@ -659,6 +669,8 @@ Item {
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
source: "input-gaming"
isMask: true
color: Kirigami.Theme.textColor
}
PC3.Label {

View file

@ -583,6 +583,8 @@ ContainmentItem {
height: width
source: "window-close-symbolic"
active: closeArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
PlasmaComponents.ToolTip {
text: i18n("Close")
@ -633,6 +635,8 @@ ContainmentItem {
height: width
source: "system-lock-screen"
active: lockArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
PlasmaComponents.ToolTip {
text: i18n("Lock Screen")
@ -665,6 +669,8 @@ ContainmentItem {
height: width
source: "system-reboot"
active: rebootArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
PlasmaComponents.ToolTip {
text: i18n("Restart")
@ -697,6 +703,8 @@ ContainmentItem {
height: width
source: "system-shutdown"
active: shutdownArea.containsMouse
isMask: true
color: Kirigami.Theme.textColor
}
PlasmaComponents.ToolTip {
text: i18n("Shut Down")

View file

@ -27,6 +27,8 @@ PC3.ToolButton {
implicitHeight: Kirigami.Units.iconSizes.smallMedium
Layout.fillHeight: true
source: iconName
isMask: true
color: Kirigami.Theme.textColor
}
QQC2.Label {

View file

@ -119,7 +119,7 @@
"Name[uk]": "Альціон",
"Name[zh_CN]": "Halcyon",
"Name[zh_TW]": "Halcyon",
"Website": "https://plasma-mobile.org"
"Website": "https://invent.kde.org/marcoa/shift-shell"
},
"X-Plasma-API-Minimum-Version": "6.0",
"X-Plasma-ContainmentType": "Desktop",

View file

@ -44,43 +44,7 @@
}
],
"Category": "Containments",
"Description": "Top panel for Plasma Mobile",
"Description[ar]": "اللوحة العلوية لبلازما الجوال",
"Description[ca@valencia]": "Quadro superior per a Plasma Mobile",
"Description[ca]": "Plafó superior per al Plasma Mobile",
"Description[cs]": "Horní panel pro Plasma Mobile",
"Description[de]": "Obere Kontrollleiste für Plasma Mobile",
"Description[en_GB]": "Top panel for Plasma Mobile",
"Description[eo]": "Supra panelo por Plasma Mobile",
"Description[es]": "Panel superior para Plasma Mobile",
"Description[eu]": "Plasma Mugikorrerako goiko panela",
"Description[fi]": "Yläpaneeli Plasma Mobileen",
"Description[fr]": "Panneau supérieur pour Plasma Mobile",
"Description[gl]": "Panel superior para Plasma Mobile.",
"Description[he]": "לוח עליון לפלזמה לניידים",
"Description[hu]": "Felső panel a Plasma Mobile-hoz",
"Description[ia]": "Pannello in alto per Plasma Mobile",
"Description[is]": "Toppspjald fyrir Plasma Mobile",
"Description[it]": "Pannello superiore per Plasma Mobile",
"Description[ka]": "Plasma Mobile-ის ზედა პანელი",
"Description[ko]": "Plasma 모바일의 최상위 패널",
"Description[lv]": "„Plasma Mobile“ augšējais panelis",
"Description[nl]": "Hoofdpaneel voor Plasma Mobile",
"Description[nn]": "Toppanel for Plasma Mobile",
"Description[pa]": "ਪਲਾਜ਼ਮਾ ਮੋਬਾਈਲ ਲਈ ਸਿਖਰਲਾ ਪੈਨਲ",
"Description[pl]": "Górny panel dla Przenośnej Plazmy",
"Description[pt]": "Painel de topo do Plasma Mobile",
"Description[pt_BR]": "Painel superior do Plasma Mobile",
"Description[ru]": "Верхняя панель Plasma Mobile",
"Description[sa]": "प्लाज्मा मोबाईलस्य कृते शीर्षपटलम्",
"Description[sk]": "Horný panel pre Plasma Mobile",
"Description[sl]": "Vrhnja plošča za Plasma Mobile",
"Description[sv]": "Överpanel för Plasma mobil",
"Description[ta]": "பிளாஸ்மா கைபேசிக்கான மேலோரப் பலகை",
"Description[tr]": "Plasma Cep için üst panel",
"Description[uk]": "Верхня панель для мобільної Плазми",
"Description[zh_CN]": "Plasma Mobile 的顶部面板",
"Description[zh_TW]": "Plasma 行動的頂部面板",
"Description": "Top panel for SHIFT",
"License": "GPLv2+",
"Name": "Phone Panel",
"Name[ar]": "لوحة الهاتف",
@ -126,7 +90,7 @@
"Name[uk]": "Панель телефону",
"Name[zh_CN]": "手机面板",
"Name[zh_TW]": "手機面板",
"Website": "https://plasma-mobile.org"
"Website": "https://invent.kde.org/marcoa/shift-shell"
},
"X-Plasma-API-Minimum-Version": "6.0",
"X-Plasma-ContainmentType": "Panel"

View file

@ -44,43 +44,7 @@
}
],
"Category": "Containments",
"Description": "Navigation panel for Plasma Mobile",
"Description[ar]": "لوحة التنقل لبلازما الجوال",
"Description[ca@valencia]": "Quadro de navegació per a Plasma Mobile",
"Description[ca]": "Plafó de navegació per al Plasma Mobile",
"Description[cs]": "Navigační panel pro Plasma Mobile",
"Description[de]": "Navigationsleiste für Plasma Mobile",
"Description[en_GB]": "Navigation panel for Plasma Mobile",
"Description[eo]": "Navigada panelo por Plasma Mobile",
"Description[es]": "Panel de navegación para Plasma Mobile",
"Description[eu]": "Plasma Mugikorrerako nabigazio-panela",
"Description[fi]": "Navigointipaneeli Plasma Mobilelle",
"Description[fr]": "Panneau de navigation pour Plasma Mobile",
"Description[gl]": "Panel de navegación para Plasma Mobile.",
"Description[he]": "לוח ניווט לפלזמה לניידים",
"Description[hu]": "Navigációs panel a Plasma Mobile-hoz",
"Description[ia]": "Pannello de Navigation per Plasma Mobile",
"Description[is]": "Flakkspjald fyrir Plasma Mobile",
"Description[it]": "Pannello di navigazione per Plasma Mobile",
"Description[ka]": "Plasma Mobile-ის ნავიგაციის პანელი",
"Description[ko]": "Plasma 모바일의 탐색 패널",
"Description[lv]": "„Plasma Mobile“ navigācijas panelis",
"Description[nl]": "Navigatiepaneel voor Plasma Mobile",
"Description[nn]": "Navigasjonspanel for Plasma Mobile",
"Description[pa]": "ਪਲਾਜ਼ਮਾ ਮੋਬਾਈਲ ਲਈ ਨੇਵੀਗੇਸ਼ਨ ਪੈਨਲ",
"Description[pl]": "Pasek poruszania się dla Przenośnej Plazmy",
"Description[pt]": "Painel de navegação do Plasma Mobile",
"Description[pt_BR]": "Painel de navegação do Plasma Mobile",
"Description[ru]": "Панель навигации Plasma Mobile",
"Description[sa]": "प्लाज्मा मोबाईलस्य कृते नेविगेशन पैनल",
"Description[sk]": "Navigačný panel pre Plasma Mobile",
"Description[sl]": "Krmilna plošča za Plasma Mobile",
"Description[sv]": "Navigeringspanel för Plasma mobil",
"Description[ta]": "பிளாஸ்மா கைபேசிக்கான உலாவல் பலகை",
"Description[tr]": "Plasma Cep için dolaşım paneli",
"Description[uk]": "Панель навігації для мобільної Плазми",
"Description[zh_CN]": "Plasma 移动版导航面板",
"Description[zh_TW]": "Plasma 行動的導覽面板",
"Description": "Navigation panel for SHIFT",
"License": "GPLv2+",
"Name": "Phone Task panel",
"Name[ar]": "لوحة مهمة الهاتف",
@ -126,7 +90,7 @@
"Name[uk]": "Панель завдань телефону",
"Name[zh_CN]": "手机任务面板",
"Name[zh_TW]": "手機工作面板",
"Website": "https://plasma-mobile.org"
"Website": "https://invent.kde.org/marcoa/shift-shell"
},
"X-Plasma-API-Minimum-Version": "6.0",
"X-Plasma-ContainmentType": "Panel"

View file

@ -0,0 +1,12 @@
# This is the official list of project authors for copyright purposes. The first name in the list (if there are several authors), will appear as "Principal design" in the "about" section of the font specimen on Google Fonts.
# This file is distinct from the CONTRIBUTORS.txt file.
# See the latter for an explanation.
#
# Names should be added to this file as:
# Name or Organization <email address>
Elliott Scott
Megan Eiswerth
Linus Boman
Theodore Petrosky
Letters from Sweden

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,93 @@
Copyright 2020-2024 The Atkinson Hyperlegible Mono Project Authors (https://github.com/googlefonts/atkinson-hyperlegible-next-mono)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,12 @@
# This is the official list of project authors for copyright purposes. The first name in the list (if there are several authors), will appear as "Principal design" in the "about" section of the font specimen on Google Fonts.
# This file is distinct from the CONTRIBUTORS.txt file.
# See the latter for an explanation.
#
# Names should be added to this file as:
# Name or Organization <email address>
Elliott Scott
Megan Eiswerth
Linus Boman
Theodore Petrosky
Letters from Sweden

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

View file

@ -0,0 +1,93 @@
Copyright 2020-2024 The Atkinson Hyperlegible Next Project Authors (https://github.com/googlefonts/atkinson-hyperlegible-next)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020-2024 The Atkinson Hyperlegible Project Authors
SPDX-License-Identifier: OFL-1.1

22
fonts/CMakeLists.txt Normal file
View file

@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2026 SHIFT Contributors
# SPDX-License-Identifier: GPL-2.0-or-later
# Install bundled font files (if any are present) into the system font dir
# so the shell session can render the configured default font even on
# distributions that do not package it.
#
# Drop OFL-licensed font files into fonts/AtkinsonHyperlegibleNext/ and
# fonts/AtkinsonHyperlegibleMono/ alongside their SPDX .license sidecars.
file(GLOB SHIFT_FONT_FILES
LIST_DIRECTORIES false
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.ttf"
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.otf"
)
if(SHIFT_FONT_FILES)
install(
FILES ${SHIFT_FONT_FILES}
DESTINATION ${KDE_INSTALL_DATADIR}/fonts/shift
)
endif()

36
fonts/README.md Normal file
View file

@ -0,0 +1,36 @@
<!--
SPDX-FileCopyrightText: 2026 SHIFT Contributors
SPDX-License-Identifier: GPL-2.0-or-later
-->
# Shift bundled fonts
Drop the Atkinson Hyperlegible Next and Atkinson Hyperlegible Mono font files
here, organised one family per subdirectory:
```
fonts/
AtkinsonHyperlegibleNext/
AtkinsonHyperlegibleNext-*.ttf
AtkinsonHyperlegibleNext-*.ttf.license
AtkinsonHyperlegibleMono/
AtkinsonHyperlegibleMono-*.ttf
AtkinsonHyperlegibleMono-*.ttf.license
```
Sources:
- https://www.brailleinstitute.org/freefont (Atkinson Hyperlegible Next + Mono)
License: SIL Open Font License 1.1. Add a `.license` sidecar next to each
binary file with:
```
SPDX-FileCopyrightText: 2024 Braille Institute of America, Inc.
SPDX-License-Identifier: OFL-1.1
```
The build globs every `*.ttf`/`*.otf` under these subdirectories at configure
time, so adding files later does not require editing CMake. If no fonts are
present, the install step is skipped silently — `lookandfeel/contents/defaults`
still requests the family, and the system falls back to whatever fontconfig
resolves "Atkinson Hyperlegible Next" to (e.g. a distro package).

View file

@ -8,3 +8,9 @@ ecm_install_icons(
DESTINATION ${KDE_INSTALL_ICONDIR}
THEME hicolor
)
install(
DIRECTORY org.shift.icons
DESTINATION ${KDE_INSTALL_ICONDIR}
PATTERN README.md EXCLUDE
)

View file

@ -0,0 +1,37 @@
# Shift Icon Theme
`org.shift.icons` is the icon theme selected by `lookandfeel/contents/defaults`.
It inherits only `hicolor`, so shell-owned glyphs used by the Shift UI need to exist in this theme or in the local hicolor source icon set.
The SVG glyphs are adapted from Phosphor Icons and licensed through the scoped REUSE metadata in `.reuse/dep5`.
Theme paths used here:
- `actions/symbolic/`: symbolic shell glyphs used by QML controls, status indicators, quick settings, window controls, and category icons.
- `places/symbolic/`: symbolic place glyphs used by the dock and shell surfaces.
- `apps/scalable/`: colored launcher icons for desktop-file app icon names that are part of the default Shift UI.
- `preferences/scalable/`: colored System Settings category and module icons for names that should not fall back to monochrome action glyphs.
Keep `preferences/scalable` before `actions/symbolic` in `index.theme`. System Settings looks up category and KCM module icons by name, and the icon theme specification searches theme directories in order. If symbolic action aliases come first, names such as `preferences-desktop-sound`, `preferences-system-time`, or `network-wireless-symbolic` resolve to dark monochrome SVGs instead of colored preference icons.
When a QML icon is owned by the shell, render it as a masked icon with an explicit theme color:
```qml
Kirigami.Icon {
source: "icon-name"
isMask: true
color: Kirigami.Theme.textColor
}
```
Use the same pattern for shell button properties such as `iconName` and `iconSource`. Do not force `isMask` for dynamic application icons from task, notification, applet, or launcher models; those can be colored app icons.
If a required icon name is only an alias for an existing glyph, keep it as a same-directory symbolic link, for example `rotation-allowed-symbolic.svg -> rotation-allowed.svg`.
Run the coverage guard after adding or renaming shell icon sources:
```sh
bash tests/check-shift-icon-theme.sh
```
The same check is registered with CTest as `shift-icon-theme-coverage`.
When Plasma packages are installed, the guard also scans their desktop metadata and QML icon fields so desktop shell, KCM, and applet icon names do not silently fall back to Breeze-only glyphs.

View file

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<circle cx="128" cy="44" r="16"/>
<path d="M72,88c18.67-8,37.33-12,56-12s37.33,4,56,12" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
<line x1="128" y1="76" x2="128" y2="212" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
<line x1="128" y1="120" x2="84" y2="212" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
<line x1="128" y1="120" x2="172" y2="212" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 834 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<rect x="48" y="48" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><rect x="144" y="48" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><rect x="48" y="144" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><rect x="144" y="144" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 824 B

View file

@ -0,0 +1 @@
view-grid-symbolic.svg

View file

@ -0,0 +1 @@
view-grid-symbolic.svg

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<rect x="48" y="48" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><rect x="144" y="48" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><rect x="48" y="144" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><rect x="144" y="144" width="64" height="64" rx="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 824 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<polyline points="64 88 16 128 64 168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="192 88 240 128 192 168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="160" y1="40" x2="96" y2="216" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 641 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M48,216a24,24,0,0,1,24-24H208V32H72A24,24,0,0,0,48,56Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="48 216 48 224 192 224" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 526 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<line x1="152" y1="104" x2="176" y2="104" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="72" y1="104" x2="104" y2="104" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="88" y1="88" x2="88" y2="120" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M105.91,152,63.8,199.8a28,28,0,0,1-47.37-24.66L32.79,91a52,52,0,0,1,51.1-43H172a52,52,0,1,1,0,104Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M150.09,152l42.11,47.8a28,28,0,0,0,47.37-24.66L223.21,91" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1,018 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M16,216H92a52,52,0,1,0-52-52C40,200,16,216,16,216Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M112.41,116.16C131.6,90.29,179.46,32,224,32c0,44.54-58.29,92.4-84.16,111.59" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M133,90.64a84.39,84.39,0,0,1,32.41,32.41" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 718 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<circle cx="128" cy="128" r="96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M168,128c0,64-40,96-40,96s-40-32-40-96,40-96,40-96S168,64,168,128Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="37.46" y1="96" x2="218.54" y2="96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="37.46" y1="160" x2="218.54" y2="160" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 822 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<circle cx="180" cy="164" r="28" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><circle cx="52" cy="196" r="28" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="80 196 80 56 208 24 208 164" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 632 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M200,224H56a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h96l56,56V216A8,8,0,0,1,200,224Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="152 32 152 88 208 88" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="96" y1="136" x2="160" y2="136" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="96" y1="168" x2="160" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 827 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<circle cx="128" cy="128" r="12"/><circle cx="196" cy="128" r="12"/><circle cx="60" cy="128" r="12"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 321 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<line x1="88" y1="32" x2="168" y2="32" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M152,32V99.14l62.85,104.74A8,8,0,0,1,208,216H48a8,8,0,0,1-6.86-12.12L104,99.14V32" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M71.63,153.08c13.23-2.48,32-1.41,56.37,10.92,32.25,16.33,54.75,12.91,67.5,7.65" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 740 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<circle cx="128" cy="128" r="40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M41.43,178.09A99.14,99.14,0,0,1,31.36,153.8l16.78-21a81.59,81.59,0,0,1,0-9.64l-16.77-21a99.43,99.43,0,0,1,10.05-24.3l26.71-3a81,81,0,0,1,6.81-6.81l3-26.7A99.14,99.14,0,0,1,102.2,31.36l21,16.78a81.59,81.59,0,0,1,9.64,0l21-16.77a99.43,99.43,0,0,1,24.3,10.05l3,26.71a81,81,0,0,1,6.81,6.81l26.7,3a99.14,99.14,0,0,1,10.07,24.29l-16.78,21a81.59,81.59,0,0,1,0,9.64l16.77,21a99.43,99.43,0,0,1-10,24.3l-26.71,3a81,81,0,0,1-6.81,6.81l-3,26.7a99.14,99.14,0,0,1-24.29,10.07l-21-16.78a81.59,81.59,0,0,1-9.64,0l-21,16.77a99.43,99.43,0,0,1-24.3-10l-3-26.71a81,81,0,0,1-6.81-6.81Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M104,126.94a64,64,0,0,1,80-90.29L144,80l5.66,26.34L176,112l43.35-40a64,64,0,0,1-90.29,80L73,217A24,24,0,0,1,39,183Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 446 B

View file

@ -0,0 +1 @@
arrow-down.svg

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<line x1="128" y1="40" x2="128" y2="216" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="56 144 128 216 200 144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 503 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<line x1="216" y1="128" x2="40" y2="128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="112 56 40 128 112 200" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 502 B

View file

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<line x1="40" y1="128" x2="216" y2="128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
<polyline points="144 56 216 128 144 200" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 503 B

View file

@ -0,0 +1 @@
arrow-up.svg

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<line x1="128" y1="216" x2="128" y2="40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><polyline points="56 112 128 40 200 112" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 502 B

View file

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16">
<rect x="88" y="24" width="80" height="128" rx="40"/>
<path d="M48 112a80 80 0 0 0 160 0"/>
<line x1="128" y1="192" x2="128" y2="232"/>
<line x1="88" y1="232" x2="168" y2="232"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 476 B

View file

@ -0,0 +1 @@
audio-volume-high.svg

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M80,168H32a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8H80l72-56V224Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="80" y1="88" x2="80" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M192,106.85a32,32,0,0,1,0,42.3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M221.67,80a72,72,0,0,1,0,96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 804 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M80,168H32a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8H80l72-56V224Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="80" y1="88" x2="80" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M192,106.85a32,32,0,0,1,0,42.3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 666 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M80,168H32a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8H80l72-56V224Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="80" y1="88" x2="80" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M192,106.85a32,32,0,0,1,0,42.3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M221.67,80a72,72,0,0,1,0,96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 804 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M80,168H32a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8H80l72-56V224Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="240" y1="104" x2="192" y2="152" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="240" y1="152" x2="192" y2="104" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="80" y1="88" x2="80" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 809 B

View file

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
<g class="ColorScheme-Text" fill="currentColor">
<path d="M80,168H32a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8H80l72-56V224Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="80" y1="88" x2="80" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M192,106.85a32,32,0,0,1,0,42.3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M221.67,80a72,72,0,0,1,0,96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 804 B

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

View file

@ -0,0 +1 @@
battery.svg

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