diff -Nru phosh-0.8.0/config.h.in phosh-0.13.1/config.h.in
--- phosh-0.8.0/config.h.in 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/config.h.in 2021-08-31 09:15:52.000000000 +0000
@@ -11,3 +11,4 @@
#mesondefine LOCALEDIR
+#mesondefine HAVE_RFKILL_EVENT_EXT
diff -Nru phosh-0.8.0/data/00_sm.puri.Phosh.gschema.override phosh-0.13.1/data/00_sm.puri.Phosh.gschema.override
--- phosh-0.8.0/data/00_sm.puri.Phosh.gschema.override 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/00_sm.puri.Phosh.gschema.override 2021-08-31 09:15:52.000000000 +0000
@@ -1,7 +1,7 @@
-[org.gnome.desktop.a11y.applications]
+[org.gnome.desktop.a11y.applications:Phosh]
screen-keyboard-enabled=true
-[org.gnome.desktop.interface]
+[org.gnome.desktop.interface:Phosh]
clock-show-date=false
clock-show-weekday=false
diff -Nru phosh-0.8.0/data/camera-hardware-disabled-symbolic.svg phosh-0.13.1/data/camera-hardware-disabled-symbolic.svg
--- phosh-0.8.0/data/camera-hardware-disabled-symbolic.svg 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/camera-hardware-disabled-symbolic.svg 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,6 @@
+
diff -Nru phosh-0.8.0/data/feedback-quiet-symbolic.svg phosh-0.13.1/data/feedback-quiet-symbolic.svg
--- phosh-0.8.0/data/feedback-quiet-symbolic.svg 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/feedback-quiet-symbolic.svg 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,31 @@
+
+
diff -Nru phosh-0.8.0/data/meson.build phosh-0.13.1/data/meson.build
--- phosh-0.8.0/data/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -1,6 +1,37 @@
+gsd_required_components = [
+ 'org.gnome.SettingsDaemon.A11ySettings',
+ 'org.gnome.SettingsDaemon.Color',
+ 'org.gnome.SettingsDaemon.Datetime',
+ 'org.gnome.SettingsDaemon.Housekeeping',
+ 'org.gnome.SettingsDaemon.Keyboard',
+ 'org.gnome.SettingsDaemon.MediaKeys',
+ 'org.gnome.SettingsDaemon.Power',
+ 'org.gnome.SettingsDaemon.PrintNotifications',
+ 'org.gnome.SettingsDaemon.Rfkill',
+ 'org.gnome.SettingsDaemon.ScreensaverProxy',
+ 'org.gnome.SettingsDaemon.Sharing',
+ 'org.gnome.SettingsDaemon.Smartcard',
+ 'org.gnome.SettingsDaemon.Sound',
+ 'org.gnome.SettingsDaemon.UsbProtection',
+ 'org.gnome.SettingsDaemon.Wacom',
+ 'org.gnome.SettingsDaemon.Wwan',
+ 'org.gnome.SettingsDaemon.XSettings',
+]
+
+desktop_required_components = gsd_required_components + [
+ 'sm.puri.Phosh',
+ 'sm.puri.OSK0',
+]
+
desktopconf = configuration_data()
desktopconf.set('bindir', bindir)
desktopconf.set('libexecdir', libexecdir)
+desktopconf.set('required_components', ';'.join(desktop_required_components) + ';')
+if get_option('systemd')
+ desktopconf.set('hidden_under_systemd', 'X-GNOME-HiddenUnderSystemd=true')
+else
+ desktopconf.set('hidden_under_systemd', '')
+endif
desktop_files = [
'sm.puri.Phosh.desktop',
@@ -47,6 +78,14 @@
runconf.set('pkgdatadir', pkgdatadir)
runconf.set('version', meson.project_version())
runconf.set('wlrootsdir', join_paths(libexecdir, 'wlroots'))
+runconf.set('compositor', get_option('compositor'))
+
+if get_option('systemd')
+ runconf.set('session_manager', '--systemd')
+else
+ runconf.set('session_manager', '--builtin')
+endif
+
configure_file(
input: 'phosh.in',
output: 'phosh',
@@ -59,7 +98,8 @@
#generate XML enum definitions for GSettings schema
schema_enum_headers = files(
- '../src/wwan/phosh-wwan-backend.h'
+ '../src/app-grid.h',
+ '../src/wwan/phosh-wwan-backend.h',
)
generate_enums_schema = gnome.mkenums('sm.puri.phosh.enums.xml',
sources: schema_enum_headers,
@@ -97,6 +137,8 @@
install_dir: schemasdir
)
+subdir('systemd')
+
install_data('phoc.ini', install_dir : pkgdatadir)
install_data('wayland-sessions/phosh.desktop',
install_dir : 'share/wayland-sessions')
diff -Nru phosh-0.8.0/data/microphone-hardware-disabled-symbolic.svg phosh-0.13.1/data/microphone-hardware-disabled-symbolic.svg
--- phosh-0.8.0/data/microphone-hardware-disabled-symbolic.svg 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/microphone-hardware-disabled-symbolic.svg 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,6 @@
+
diff -Nru phosh-0.8.0/data/phosh.in phosh-0.13.1/data/phosh.in
--- phosh-0.8.0/data/phosh.in 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/phosh.in 2021-08-31 09:15:52.000000000 +0000
@@ -1,20 +1,8 @@
#!/bin/sh
-COMPOSITOR="/usr/bin/phoc"
+COMPOSITOR="@compositor@"
PHOC_INI="@pkgdatadir@/phoc.ini"
-
-gnome_session_args()
-{
- ARGS="--disable-acceleration-check --session=phosh"
-
- # Use builtin session handling until we can rely
- # on a newer gnome-session everywhere
- if gnome-session --help | grep -qs -e--builtin; then
- ARGS="--builtin ${ARGS}"
- fi
-
- echo "${ARGS}"
-}
+GNOME_SESSION=${GNOME_SESSION:-gnome-session}
help()
{
@@ -60,4 +48,4 @@
# variables from /etc/profile.d (XDG_*)
[ -n "$WLR_BACKENDS" ] || WLR_BACKENDS=drm,libinput
export WLR_BACKENDS
-exec "${COMPOSITOR}" -C "${PHOC_INI}" -E "bash -lc 'gnome-session $(gnome_session_args)'"
+exec "${COMPOSITOR}" -C "${PHOC_INI}" -E "bash -lc '${GNOME_SESSION} --disable-acceleration-check --session=phosh @session_manager@'"
diff -Nru phosh-0.8.0/data/phosh.service phosh-0.13.1/data/phosh.service
--- phosh-0.8.0/data/phosh.service 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/phosh.service 2021-08-31 09:15:52.000000000 +0000
@@ -1,6 +1,6 @@
[Unit]
Description=Phosh, a shell for mobile phones
-Documentation=https://source.puri.sm/Librem5/phosh
+Documentation=https://gitlab.gnome.org/World/Phosh/phosh
# Make sure we are started after logins are permitted.
After=systemd-user-sessions.service
@@ -26,7 +26,7 @@
[Service]
Environment=LANG=C.UTF-8
-Environment=XDG_CURRENT_DESKTOP=GNOME
+Environment=XDG_CURRENT_DESKTOP=GNOME:Phosh
Environment=XDG_SESSION_DESKTOP=phosh
Environment=XDG_SESSION_TYPE=wayland
ExecStart=/usr/bin/phosh
@@ -34,7 +34,7 @@
User=1000
PAMName=login
WorkingDirectory=~
-Restart=on-failure
+Restart=always
RestartSec=5s
# A virtual terminal is needed.
diff -Nru phosh-0.8.0/data/phosh.session.desktop.in.in phosh-0.13.1/data/phosh.session.desktop.in.in
--- phosh-0.8.0/data/phosh.session.desktop.in.in 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/phosh.session.desktop.in.in 2021-08-31 09:15:52.000000000 +0000
@@ -1,4 +1,4 @@
[GNOME Session]
# Translators: this is the session name, no need to translate it
Name=Phosh
-RequiredComponents=sm.puri.Phosh;org.gnome.SettingsDaemon.A11ySettings;org.gnome.SettingsDaemon.Color;org.gnome.SettingsDaemon.Datetime;org.gnome.SettingsDaemon.Housekeeping;org.gnome.SettingsDaemon.Keyboard;org.gnome.SettingsDaemon.Power;org.gnome.SettingsDaemon.PrintNotifications;org.gnome.SettingsDaemon.Rfkill;org.gnome.SettingsDaemon.ScreensaverProxy;org.gnome.SettingsDaemon.Sharing;org.gnome.SettingsDaemon.Smartcard;org.gnome.SettingsDaemon.Sound;sm.puri.OSK0;
+RequiredComponents=@required_components@
diff -Nru phosh-0.8.0/data/sm.puri.Phosh.desktop.in.in phosh-0.13.1/data/sm.puri.Phosh.desktop.in.in
--- phosh-0.8.0/data/sm.puri.Phosh.desktop.in.in 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/sm.puri.Phosh.desktop.in.in 2021-08-31 09:15:52.000000000 +0000
@@ -10,3 +10,4 @@
X-GNOME-Provides=panel;windowmanager;
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=true
+@hidden_under_systemd@
diff -Nru phosh-0.8.0/data/sm.puri.phosh.gschema.xml phosh-0.13.1/data/sm.puri.phosh.gschema.xml
--- phosh-0.8.0/data/sm.puri.phosh.gschema.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/sm.puri.phosh.gschema.xml 2021-08-31 09:15:52.000000000 +0000
@@ -2,7 +2,7 @@
- [ 'sm.puri.Calls.desktop',
+ [ 'org.gnome.Calls.desktop',
'sm.puri.Chatty.desktop',
'org.gnome.Epiphany.desktop',
'org.gnome.Contacts.desktop'
@@ -13,6 +13,17 @@
displayed in the favorites panel along with running applications.
+
+ ['adaptive']
+
+ How to filter apps in the overview. The default 'adaptive' shows only
+ adaptive apps in mobile mode and all apps in docked mode. 'off' turns
+ of all filtering.
+
+
+ Whether to filter out apps that aren't marked as adaptive in mobile mode.
+
+
[]
diff -Nru phosh-0.8.0/data/systemd/meson.build phosh-0.13.1/data/systemd/meson.build
--- phosh-0.8.0/data/systemd/meson.build 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/systemd/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,37 @@
+if get_option('systemd')
+
+gsd_wants = ''
+foreach component : gsd_required_components
+ gsd_wants += 'Wants=' + component + '.target\n'
+endforeach
+
+session_dropins = [
+ 'gnome-session@phosh.target.d',
+]
+
+sessionconf = configuration_data()
+sessionconf.set('gsd_wants', gsd_wants)
+
+foreach session_dropin : session_dropins
+ configure_file(
+ input: 'phosh.session.conf.in',
+ output: 'session.conf',
+ install_dir: join_paths(systemduserdir, session_dropin),
+ configuration: sessionconf,
+ install: true
+ )
+endforeach
+
+serviceconf = configuration_data()
+serviceconf.set('libexecdir', libexecdir)
+configure_file(
+ input: 'sm.puri.Phosh.service.in',
+ output: 'sm.puri.Phosh.service',
+ install_dir: systemduserdir,
+ configuration: serviceconf,
+ install: true
+)
+
+install_data('sm.puri.Phosh.target', install_dir: systemduserdir)
+
+endif
diff -Nru phosh-0.8.0/data/systemd/phosh.session.conf.in phosh-0.13.1/data/systemd/phosh.session.conf.in
--- phosh-0.8.0/data/systemd/phosh.session.conf.in 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/systemd/phosh.session.conf.in 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,4 @@
+[Unit]
+@gsd_wants@
+
+Requires=sm.puri.Phosh.target
diff -Nru phosh-0.8.0/data/systemd/sm.puri.Phosh.service.in phosh-0.13.1/data/systemd/sm.puri.Phosh.service.in
--- phosh-0.8.0/data/systemd/sm.puri.Phosh.service.in 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/systemd/sm.puri.Phosh.service.in 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,27 @@
+# This is a systemd user unit intended to be started with gnome-session.
+
+[Unit]
+Description=Phosh, a shell for mobile phones
+Documentation=https://gitlab.gnome.org/World/Phosh/phosh
+
+After=gnome-session-manager.target
+
+Requisite=gnome-session-initialized.target
+PartOf=gnome-session-initialized.target
+Before=gnome-session-initialized.target
+
+StartLimitIntervalSec=15s
+StartLimitBurst=3
+
+OnFailure=gnome-session-shutdown.target
+OnFailureJobMode=replace-irreversibly
+CollectMode=inactive-or-failed
+RefuseManualStart=on
+RefuseManualStop=on
+
+[Service]
+Type=notify
+ExecStart=@libexecdir@/phosh
+Restart=on-failure
+RestartSec=0ms
+Slice=session.slice
diff -Nru phosh-0.8.0/data/systemd/sm.puri.Phosh.target phosh-0.13.1/data/systemd/sm.puri.Phosh.target
--- phosh-0.8.0/data/systemd/sm.puri.Phosh.target 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/data/systemd/sm.puri.Phosh.target 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,10 @@
+[Unit]
+Description=Phosh
+DefaultDependencies=no
+
+Requisite=gnome-session-initialized.target
+PartOf=gnome-session-initialized.target
+Before=gnome-session-initialized.target
+
+Requires=sm.puri.Phosh.service
+After=sm.puri.Phosh.service
diff -Nru phosh-0.8.0/data/wayland-sessions/phosh.desktop phosh-0.13.1/data/wayland-sessions/phosh.desktop
--- phosh-0.8.0/data/wayland-sessions/phosh.desktop 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/data/wayland-sessions/phosh.desktop 2021-08-31 09:15:52.000000000 +0000
@@ -3,4 +3,4 @@
Comment=Phone Shell
Exec=phosh
Type=Application
-DesktopNames=GNOME
+DesktopNames=GNOME:Phosh
diff -Nru phosh-0.8.0/debian/changelog phosh-0.13.1/debian/changelog
--- phosh-0.8.0/debian/changelog 2021-01-19 09:34:47.000000000 +0000
+++ phosh-0.13.1/debian/changelog 2021-08-31 12:52:10.000000000 +0000
@@ -1,3 +1,88 @@
+phosh (0.13.1-1) unstable; urgency=medium
+
+ * New usptream version 0.13.1
+ * Upload to unstable
+ * Add Breaks: on older GTK. With older GTK calls and phosh would block on
+ each other on startup.
+
+ -- Guido Günther Tue, 31 Aug 2021 14:52:10 +0200
+
+phosh (0.13.0-1) UNRELEASED; urgency=medium
+
+ [ Guido Günther ]
+ * debian: Add breaks relationship on older calls.
+ This makes sure calls we don't try to run against a calls without
+ the DBus interface.
+ * d/control: Bump phoc recommends.
+ Recommend a version that allows us to bind all the interesting
+ keys.
+ * d/control: Bump breaks on gnome-calls.
+ Not strictly necessary but makes missing deps easier to detect.
+
+ [ Arnaud Ferraris ]
+ * New upstream version 0.13.0
+ * d/control: add build dependency on libgudev.
+ This is required by the new torch manager implementation.
+ * d/control: drop duplicate Homepage field
+ * d/control: drop Build-Depends on linux-libc-dev.
+ This is a downstream change, causing the arm64 build to fail on Debian
+ as our most recent kernel is 5.10.x.
+ * d/watch: update to reflect migration to GNOME infrastructure
+
+ -- Arnaud Ferraris Tue, 10 Aug 2021 11:17:12 +0200
+
+phosh (0.12.0-1) experimental; urgency=medium
+
+ * New usptream version 0.12.0
+ * d/control: Bump phoc version.
+ Recommend a version that has allows to bind all the needed keys.
+ * d/control: Add breaks on older calls.
+ We want a version that has the DBus interface
+
+ -- Guido Günther Wed, 30 Jun 2021 11:52:38 +0200
+
+phosh (0.11.0-1) experimental; urgency=medium
+
+ * New upstream version 0.11.0
+ * Use non-systemd mode for now.
+ Stick with gnome-session's builtin session management for the moment.
+
+ -- Guido Günther Mon, 31 May 2021 10:59:33 +0200
+
+phosh (0.10.2-1) experimental; urgency=medium
+
+ * New upstream version 0.10.2
+
+ -- Guido Günther Thu, 29 Apr 2021 15:32:47 +0200
+
+phosh (0.10.1-1) experimental; urgency=medium
+
+ * New upstream version 0.10.1
+
+ -- Guido Günther Mon, 12 Apr 2021 11:17:01 +0200
+
+phosh (0.10.0-1) experimental; urgency=medium
+
+ * New upstream version 0.10.0
+
+ -- Guido Günther Wed, 31 Mar 2021 17:00:22 +0200
+
+phosh (0.9.0-1) experimental; urgency=medium
+
+ * New upstream version 0.9.0
+ * d/control: Require libhandy >= 1.1.90
+ * Clean d/phosh.service
+ * salsa-ci: Build against experimental.
+ We need that for newer libhandy
+
+ -- Guido Günther Wed, 03 Mar 2021 09:53:01 +0100
+
+phosh (0.8.1-1) experimental; urgency=medium
+
+ * New upstream version 0.8.1
+
+ -- Guido Günther Fri, 12 Feb 2021 17:42:03 +0100
+
phosh (0.8.0-1) unstable; urgency=medium
* New upstream version 0.8.0
diff -Nru phosh-0.8.0/debian/clean phosh-0.13.1/debian/clean
--- phosh-0.8.0/debian/clean 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/debian/clean 2021-08-31 12:52:10.000000000 +0000
@@ -0,0 +1 @@
+debian/phosh.service
diff -Nru phosh-0.8.0/debian/control phosh-0.13.1/debian/control
--- phosh-0.8.0/debian/control 2021-01-19 09:26:36.000000000 +0000
+++ phosh-0.13.1/debian/control 2021-08-31 12:52:10.000000000 +0000
@@ -6,6 +6,7 @@
Build-Depends:
debhelper-compat (= 13),
gtk-doc-tools ,
+ libcallaudio-dev,
libsecret-1-dev,
libsystemd-dev,
libfeedback-dev,
@@ -14,7 +15,8 @@
libgnome-desktop-3-dev,
libgtk-3-dev,
libgtk-3-doc ,
- libhandy-1-dev (>= 1.0.2),
+ libgudev-1.0-dev,
+ libhandy-1-dev (>= 1.1.90),
libnm-dev,
libpam0g-dev,
libpolkit-agent-1-dev,
@@ -24,14 +26,18 @@
meson,
pandoc ,
# to run the tests
- at-spi2-core,
- gnome-themes-extra-data,
- phoc,
- xvfb,
- xauth,
+ at-spi2-core ,
+ dbus-x11 ,
+ gnome-settings-daemon-common ,
+ gnome-shell-common ,
+ gnome-themes-extra-data ,
+ gsettings-desktop-schemas ,
+ phoc ,
+ xvfb ,
+ xauth ,
Standards-Version: 4.5.0
+Homepage: https://gitlab.gnome.org/World/Phosh/phosh/
Rules-Requires-Root: no
-Homepage: https://source.puri.sm/Librem5/phosh
Vcs-Browser: https://salsa.debian.org/DebianOnMobile-team/phosh
Vcs-Git: https://salsa.debian.org/DebianOnMobile-team/phosh.git
@@ -43,7 +49,7 @@
fonts-lato,
gnome-shell-common,
gsettings-desktop-schemas,
- phoc (>= 0.4.4),
+ phoc (>= 0.7.1),
Recommends:
feedbackd,
gnome-session-bin,
@@ -55,6 +61,9 @@
Provides:
notification-daemon,
polkit-1-auth-agent,
+Breaks:
+ gnome-calls (<< 41~alpha),
+ libgtk-3-0 (<< 3.24.30),
Description: Pure Wayland shell for mobile devices
Phosh is a graphical shell for Wayland compositors speaking the layer-surface
protocol and aimed at mobile devices like smart phones and tablets using touch
diff -Nru phosh-0.8.0/debian/copyright phosh-0.13.1/debian/copyright
--- phosh-0.8.0/debian/copyright 2020-12-19 11:55:52.000000000 +0000
+++ phosh-0.13.1/debian/copyright 2021-08-31 12:52:10.000000000 +0000
@@ -1,7 +1,7 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: phosh
Upstream-Contact: Guido Günther
-Source: https://source.puri.sm/Librem5/phosh
+Source: https://gitlab.gnome.org/World/Phosh/phosh
Files: *
Copyright: 2000 Eazel, Inc.
diff -Nru phosh-0.8.0/debian/rules phosh-0.13.1/debian/rules
--- phosh-0.8.0/debian/rules 2021-01-19 09:30:46.000000000 +0000
+++ phosh-0.13.1/debian/rules 2021-08-31 12:52:10.000000000 +0000
@@ -2,7 +2,7 @@
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
-CONFIGURE_OPTS=-Dphoc_tests=disabled
+CONFIGURE_OPTS=-Dphoc_tests=disabled -Dsystemd=false
ifeq ($(filter nodoc,$(DEB_BUILD_PROFILES)),)
CONFIGURE_OPTS+=-Dgtk_doc=true
diff -Nru phosh-0.8.0/debian/salsa-ci.yml phosh-0.13.1/debian/salsa-ci.yml
--- phosh-0.8.0/debian/salsa-ci.yml 2020-12-19 11:55:52.000000000 +0000
+++ phosh-0.13.1/debian/salsa-ci.yml 2021-08-31 12:52:10.000000000 +0000
@@ -5,3 +5,11 @@
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
+
+variables:
+ RELEASE: 'experimental'
+ # Since those pull from unstable
+ SALSA_CI_DISABLE_REPROTEST: 1
+ SALSA_CI_DISABLE_PIUPARTS: 1
+ SALSA_CI_DISABLE_AUTOPKGTEST: 1
+
diff -Nru phosh-0.8.0/debian/watch phosh-0.13.1/debian/watch
--- phosh-0.8.0/debian/watch 2020-12-19 11:55:52.000000000 +0000
+++ phosh-0.13.1/debian/watch 2021-08-31 12:52:10.000000000 +0000
@@ -1,3 +1,3 @@
version=4
opts=filenamemangle=s/.*\/archive\/(\d\S+)\/phosh.*\.tar\.gz/phosh-$1\.tar\.gz/g \
- https://source.puri.sm/Librem5/phosh/tags?sort=updated_desc .*/archive/v(\d\S+)/.*\.tar\.gz.*
+ https://gitlab.gnome.org/World/Phosh/phosh/-/tags?sort=updated_desc .*/archive/v(\d\S+)/.*\.tar\.gz.*
diff -Nru phosh-0.8.0/.dir-locals.el phosh-0.13.1/.dir-locals.el
--- phosh-0.8.0/.dir-locals.el 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/.dir-locals.el 2021-08-31 09:15:52.000000000 +0000
@@ -4,5 +4,12 @@
(indent-tabs-mode . nil)
(c-basic-offset . 2)
))
+ (setq auto-mode-alist (cons '("\\.ui$" . nxml-mode) auto-mode-alist))
+ (nxml-mode . (
+ (indent-tabs-mode . nil)
+ ))
+ (css-mode . (
+ (css-indent-offset . 2)
+ ))
)
diff -Nru phosh-0.8.0/docs/patterns.md phosh-0.13.1/docs/patterns.md
--- phosh-0.8.0/docs/patterns.md 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/docs/patterns.md 2021-08-31 09:15:52.000000000 +0000
@@ -16,12 +16,12 @@
Since it acts as a Wayland client it needs a compositor to function
that provides the necessary protocols (most notably
wlr-layer-shell). It's usually used with
-[phoc](https://source.puri.sm/Librem5/phoc) (the PHOne Compositor).
+[phoc](hhttps://gitlab.gnome.org/World/Phosh/phoc) (the PHOne Compositor).
On the GNOME side it interfaces with the usual components
(e.g. [gnome-settings-daemon](https://gitlab.gnome.org/GNOME/gnome-settings-daemon),
[upower](https://gitlab.freedesktop.org/upower/upower),
-[iio-sensor-proxy](https://source.puri.sm/Librem5/debs/iio-sensor-proxy))
+[iio-sensor-proxy](https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/))
via DBus. For haptic feedback it uses
[feedbackd](https://source.puri.sm/Librem5/feedbackd/).
@@ -31,7 +31,7 @@
Although targeted at touch devices Phosh does not implement a
on screen keyboard (OSK) but leaves this to
-[squeekboard](https://source.puri.sm/Librem5/squeekboard).
+[squeekboard](hhttps://gitlab.gnome.org/World/Phosh/squeekboard).
The above combination of software is also often (a bit imprecisely)
named Phosh.
@@ -49,7 +49,7 @@
- wlr-layer-shell: Usually Wayland clients have little influence on where
the compositor places them. This protocol gives Phosh enough room
- to build the top bar via #PhoshPanel, the home bar #PhoshHome at
+ to build the top bar via #PhoshTopPanel, the home bar #PhoshHome at
the bottom, system modal dialogs e.g. #PhoshSystemPrompt and
lock screens via #PhoshLockscreen.
- wlr-foreign-toplevel-management: This allows the management of
diff -Nru phosh-0.8.0/docs/phosh-docs.xml phosh-0.13.1/docs/phosh-docs.xml
--- phosh-0.8.0/docs/phosh-docs.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/docs/phosh-docs.xml 2021-08-31 09:15:52.000000000 +0000
@@ -39,6 +39,7 @@
Widgets and Objects
+
@@ -49,20 +50,29 @@
+
+
+
+
+
+
+
+
+
@@ -84,7 +94,7 @@
-
+
@@ -95,6 +105,7 @@
+
@@ -103,9 +114,12 @@
+
+
+
@@ -120,6 +134,7 @@
Utilities
+
@@ -133,6 +148,7 @@
Generated DBus Clients
+
diff -Nru phosh-0.8.0/docs/xml/meson.build phosh-0.13.1/docs/xml/meson.build
--- phosh-0.8.0/docs/xml/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/docs/xml/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -1,4 +1,4 @@
-url = 'https://source.puri.sm/Librem5/phosh'
+url = 'https://gitlab.gnome.org/World/Phosh/phosh'
ent_conf = configuration_data()
ent_conf.set('PACKAGE', 'Phosh')
diff -Nru phosh-0.8.0/gcovr.cfg phosh-0.13.1/gcovr.cfg
--- phosh-0.8.0/gcovr.cfg 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/gcovr.cfg 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,5 @@
+exclude = src/dbus/
+exclude = src/libphosh-tool.a.p/
+exclude = src/libphosh.so.p/
+exclude = subprojects/
+exclude = tools/
diff -Nru phosh-0.8.0/.gitignore phosh-0.13.1/.gitignore
--- phosh-0.8.0/.gitignore 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/.gitignore 2021-08-31 09:15:52.000000000 +0000
@@ -7,9 +7,13 @@
*~
\#*#
.\#*
+/subprojects/glib
/subprojects/libhandy
.vscode/
*.gcov
+debian/phosh.service
+debian/sm.puri.Phosh.service
+debian/sm.puri.Phosh.target
debian/files
debian/*.substvars
debian/*debhelper*
diff -Nru phosh-0.8.0/.gitlab-ci/debian-cross.Dockerfile phosh-0.13.1/.gitlab-ci/debian-cross.Dockerfile
--- phosh-0.8.0/.gitlab-ci/debian-cross.Dockerfile 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/.gitlab-ci/debian-cross.Dockerfile 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,14 @@
+FROM debian:bullseye-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive \
+ && dpkg --add-architecture i386 \
+ && echo "deb [arch=i386] http://deb.debian.org/debian/ testing main" > /etc/apt/sources.list.d/i386.list \
+ && echo "deb [arch=amd64 arch=i386] http://deb.debian.org/debian/ experimental main" >> /etc/apt/sources.list.d/exp.list \
+ && apt-get -y update \
+ && apt-get -y install --no-install-recommends eatmydata \
+ && eatmydata apt-get -y -o APT::Immediate-Configure=false install libhandy-1-dev:i386/experimental libhandy-1-0:i386/experimental gir1.2-handy-1:i386/experimental libgladeui-common/experimental \
+ && cd /home/user/app \
+ && DEB_BUILD_PROFILES=nodoc,nocheck eatmydata apt-get -y --no-install-recommends -a i386 -o APT::Immediate-Configure=false build-dep . \
+ && eatmydata apt-get -y install --no-install-recommends git wget crossbuild-essential-i386 \
+ && eatmydata apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
diff -Nru phosh-0.8.0/.gitlab-ci/debian.Dockerfile phosh-0.13.1/.gitlab-ci/debian.Dockerfile
--- phosh-0.8.0/.gitlab-ci/debian.Dockerfile 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/.gitlab-ci/debian.Dockerfile 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,13 @@
+FROM debian:bullseye-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive \
+ && apt-get -y update \
+ && apt-get -y install --no-install-recommends wget ca-certificates gnupg eatmydata \
+ && echo "deb http://deb.debian.org/debian/ experimental main" > /etc/apt/sources.list.d/exp.list \
+ && eatmydata apt-get -y update \
+ && eatmydata apt-get --no-install-recommends -y install libhandy-1-dev/experimental libhandy-1-0/experimental gir1.2-handy-1/experimental libgladeui-common/experimental \
+ && cd /home/user/app \
+ && eatmydata apt-get --no-install-recommends -y build-dep . \
+ && eatmydata apt-get --no-install-recommends -y install build-essential git wget gcovr \
+ && eatmydata apt-get clean \
+ && eatmydata dpkg --force-depends --remove lcov
diff -Nru phosh-0.8.0/.gitlab-ci/README.md phosh-0.13.1/.gitlab-ci/README.md
--- phosh-0.8.0/.gitlab-ci/README.md 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/.gitlab-ci/README.md 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,12 @@
+### Checklist for Updating the Docker Images
+
+ - [ ] Update the `${image}.Dockerfile` file with the dependencies
+ - [ ] Run `./run-docker.sh build --base ${image} --version ${number}`
+ - [ ] Run `./run-docker.sh push --base ${image} --version ${number}`
+ once the Docker image is built; you may need to log in by using
+ `docker login` or `podman login` like
+ podman login -u -p https://registry.gitlab.gnome.org/guidog/phosh
+ See https://docs.gitlab.com/ee/user/packages/container_registry/
+ - [ ] Update the `image` keys in the `.gitlab-ci.yml` file with the new
+ image tag
+ - [ ] Open a merge request with your changes and let it run
diff -Nru phosh-0.8.0/.gitlab-ci/run-docker.sh phosh-0.13.1/.gitlab-ci/run-docker.sh
--- phosh-0.8.0/.gitlab-ci/run-docker.sh 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/.gitlab-ci/run-docker.sh 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,137 @@
+#!/bin/bash
+
+read_arg() {
+ # $1 = arg name
+ # $2 = arg value
+ # $3 = arg parameter
+ local rematch='^[^=]*=(.*)$'
+ if [[ $2 =~ $rematch ]]; then
+ read "$1" <<< "${BASH_REMATCH[1]}"
+ else
+ read "$1" <<< "$3"
+ # There is no way to shift our callers args, so
+ # return 1 to indicate they should do it instead.
+ return 1
+ fi
+}
+
+set -e
+
+build=0
+run=0
+push=0
+list=0
+print_help=0
+no_login=0
+
+while (($# > 0)); do
+ case "${1%%=*}" in
+ build) build=1;;
+ run) run=1;;
+ push) push=1;;
+ list) list=1;;
+ help) print_help=1;;
+ --base|-b) read_arg base "$@" || shift;;
+ --version|-v) read_arg base_version "$@" || shift;;
+ --no-login) no_login=1;;
+ *) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
+ esac
+ shift
+done
+
+if [ $print_help == 1 ]; then
+ echo "$0 - Build and run Docker images"
+ echo ""
+ echo "Usage: $0 [options] [basename]"
+ echo ""
+ echo "Available commands"
+ echo ""
+ echo " build --base= - Build Docker image .Dockerfile"
+ echo " run --base= - Run Docker image "
+ echo " push --base= - Push Docker image to the registry"
+ echo " list - List available images"
+ echo " help - This help message"
+ echo ""
+ exit 0
+fi
+
+cd "$(dirname "$0")"
+
+if [ $list == 1 ]; then
+ echo "Available Docker images:"
+ for f in *.Dockerfile; do
+ filename=$( basename -- "$f" )
+ basename="${filename%.*}"
+
+ echo -e " \e[1;39m$basename\e[0m"
+ done
+ exit 0
+fi
+
+# All commands after this require --base to be set
+if [ -z $base ]; then
+ echo "Usage: $0 "
+ exit 1
+fi
+
+if [ ! -f "$base.Dockerfile" ]; then
+ echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found"
+ exit 1
+fi
+
+if [ -z $base_version ]; then
+ base_version="latest"
+elif [ $base_version != "latest" ]; then
+ base_version="v$base_version"
+fi
+
+if [ ! -x "$(command -v docker)" ] || [ docker --help |& grep -q podman ]; then
+ # Docker is actually implemented by podman, and its OCI output
+ # is incompatible with some of the dockerd instances on GitLab
+ # CI runners.
+ echo "Using: Podman"
+ format="--format docker"
+ CMD="podman"
+else
+ echo "Using: Docker"
+ format=""
+ CMD="sudo docker"
+fi
+
+REGISTRY="registry.gitlab.gnome.org"
+REPO="world/phosh/phosh"
+TAG="${REGISTRY}/${REPO}/${base}:${base_version}"
+
+if [ $build == 1 ]; then
+ echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
+ ${CMD} build \
+ ${format} \
+ --volume "$(pwd)/..:/home/user/app" \
+ --build-arg HOST_USER_ID="$UID" \
+ --tag "${TAG}" \
+ --file "${base}.Dockerfile" .
+ exit $?
+fi
+
+if [ $push == 1 ]; then
+ echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}"
+
+ if [ $no_login == 0 ]; then
+ ${CMD} login ${REGISTRY}
+ fi
+
+ ${CMD} push ${TAG}
+ exit $?
+fi
+
+if [ $run == 1 ]; then
+ echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
+ ${CMD} run \
+ --rm \
+ --volume "$(pwd)/..:/home/user/app" \
+ --workdir "/home/user/app" \
+ --tty \
+ --interactive "${TAG}" \
+ bash
+ exit $?
+fi
diff -Nru phosh-0.8.0/.gitlab-ci.yml phosh-0.13.1/.gitlab-ci.yml
--- phosh-0.8.0/.gitlab-ci.yml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/.gitlab-ci.yml 2021-08-31 09:15:52.000000000 +0000
@@ -5,28 +5,22 @@
- build
- test+docs
- package
+ - deploy
variables:
- DEPS: build-essential git wget lcov
- WANT_BUILD_DEPS: "true"
+ DEBIAN_IMAGE: $CI_REGISTRY/world/phosh/phosh/debian:v0.0.20210803
+ DEBIAN_CROSS_IMAGE: $CI_REGISTRY/world/phosh/phosh/debian-cross:v0.0.20210803
XVFB_RUN: xvfb-run -a -s -noreset
COMMON_BUILD_OPTS: -Db_coverage=true --werror
- ALPINE_EDGE_DEPS: alpine-sdk elogind-dev feedbackd-dev gcr-dev git glib-dev gnome-desktop-dev
- gtk+3.0-dev libhandy1-dev gcr-dev libsecret-dev gcovr linux-pam-dev
+ ALPINE_EDGE_DEPS: alpine-sdk callaudiod-dev elogind-dev feedbackd-dev gcr-dev git glib-dev gnome-desktop-dev
+ gtk+3.0-dev libgudev-dev libhandy1-dev gcr-dev libsecret-dev gcovr linux-pam-dev
meson musl-dev networkmanager-dev ninja polkit-elogind-dev pulseaudio-dev
- upower-dev wayland-dev wayland-protocols
-
-.buster_vars: &buster_vars
- variables:
- CI_REPO: "deb http://ci.puri.sm/ scratch librem5"
- DIST: buster
- BUILD_OPTS: -Dphoc_tests=disabled -Dgtk_doc=false ${COMMON_BUILD_OPTS}
+ upower-dev wayland-dev wayland-protocols ttf-dejavu
.bullseye_vars: &bullseye_vars
variables:
- CI_REPO: "deb http://ci.puri.sm/ bullseyeci main"
DIST: bullseye
- BUILD_OPTS: -Dphoc_tests=enabled -Dgtk_doc=true ${COMMON_BUILD_OPTS}
+ BUILD_OPTS: -Dphoc_tests=enabled -Dg_tests=true ${COMMON_BUILD_OPTS}
.build_step: &build_step
script:
@@ -41,70 +35,9 @@
- ${XVFB_RUN} ninja -C _build test
- ninja -C _build coverage
-# For the smoke tests we also want debug packages, phoc,
-# weston-info, gdb, valgrind, ...
-.smoketest_vars:
- variables: &smoketest_vars
- CI_REPO: "deb http://ci.puri.sm/ scratch librem5"
- DIST: buster
- DEPS: phoc wget gnome-session-bin gdb weston valgrind
- libhandy-1-0-dbgsym libgtk-3-0-dbgsym libglib2.0-0-dbgsym
- dconf-gsettings-backend-dbgsym libfeedback-0.0-0-dbgsym
- xvfb imagemagick
- WANT_BUILD_DEPS: "false"
-
-
-before_script:
- - export DEBIAN_FRONTEND=noninteractive
- - apt-get -y update
- - apt-get -y install wget ca-certificates gnupg eatmydata
- - echo "Using CI repo ${CI_REPO}"
- - echo "$CI_REPO" > /etc/apt/sources.list.d/ci.list
- - wget -O- https://ci.puri.sm/ci-repo.key | apt-key add -
- - echo "deb http://debug.mirrors.debian.org/debian-debug/ ${DIST}-debug main" > /etc/apt/sources.list.d/debug.list
- - eatmydata apt-get -y update
- - '[ "$WANT_BUILD_DEPS" != "true" ] || eatmydata apt-get -y build-dep .'
- - eatmydata apt-get -y install $DEPS
- - ulimit -c unlimited
-
-.tags: &tags
- tags:
- - librem5
-
-build:native-debian-buster:
- <<: *tags
- stage: build
- image: debian:buster
- <<: *buster_vars
- <<: *build_step
- artifacts:
- paths:
- - _build
- except:
- variables:
- - $PKG_ONLY == "1"
-
-unit-test:native-debian-buster:
- <<: *tags
- stage: test+docs
- image: debian:buster
- needs:
- - build:native-debian-buster
- <<: *buster_vars
- <<: *test_step
- coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
- artifacts:
- when: always
- paths:
- - _build
- except:
- variables:
- - $PKG_ONLY == "1"
-
build:native-debian-bullseye:
- <<: *tags
stage: build
- image: debian:bullseye
+ image: ${DEBIAN_IMAGE}
<<: *bullseye_vars
<<: *build_step
artifacts:
@@ -114,25 +47,16 @@
variables:
- $PKG_ONLY == "1"
+# Build for 32bit architecture to catch common errors
build:cross-debian-bullseye:i386:
- <<: *tags
stage: build
- image: debian:bullseye
+ image: "${DEBIAN_CROSS_IMAGE}"
allow_failure: true
- before_script:
- - export DEBIAN_FRONTEND=noninteractive
- - echo "deb [arch=i386] http://deb.debian.org/debian/ testing main" > /etc/apt/sources.list.d/i386.list
- - apt-get -y update
- - apt-get -y install eatmydata
- - dpkg --add-architecture i386
- - eatmydata apt-get -y update
- - eatmydata apt-get -y -a i386 -o APT::Immediate-Configure=false build-dep .
- - eatmydata apt-get -y install $DEPS crossbuild-essential-i386
script:
- git submodule update --recursive
- - 'echo "Build opts: ${BUILD_OPTS}"'
+ - 'echo "Build opts: ${COMMON_BUILD_OPTS}"'
- /usr/share/meson/debcrossgen --arch i386 -o cross-i386.txt
- - meson ${BUILD_OPTS} . _build --cross-file cross-i386.txt
+ - meson ${COMMON_BUILD_OPTS} . _build --cross-file cross-i386.txt
- ninja -C _build
artifacts:
paths:
@@ -142,14 +66,13 @@
- $PKG_ONLY == "1"
unit-test:native-debian-bullseye:
- <<: *tags
stage: test+docs
- image: debian:bullseye
+ image: ${DEBIAN_IMAGE}
needs:
- build:native-debian-bullseye
<<: *bullseye_vars
<<: *test_step
- coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
+ coverage: '/^lines:\s+([\d.]+\%)\s+/'
artifacts:
when: always
paths:
@@ -159,13 +82,16 @@
- $PKG_ONLY == "1"
build-gtkdoc:
- <<: *tags
- image: debian:bullseye
stage: test+docs
- needs:
- - build:native-debian-bullseye
- <<: *bullseye_vars
+ image: ${DEBIAN_IMAGE}
+ variables:
+ DIST: bullseye
+ BUILD_OPTS: -Dgtk_doc=true ${COMMON_BUILD_OPTS}
script:
+ - git clean -dfx
+ - 'echo "Build opts: ${BUILD_OPTS}"'
+ - meson ${BUILD_OPTS} . _build
+ - ninja -C _build
- tools/doc-check
- mv _build/docs/html/ _reference/
artifacts:
@@ -176,31 +102,26 @@
- $PKG_ONLY == "1"
check-po:
- <<: *tags
stage: test+docs
- image: debian:bullseye
needs:
- build:native-debian-bullseye
+ image: ${DEBIAN_IMAGE}
before_script:
- - apt-get -y update
- - apt-get -y install intltool
+ - eatmydata apt-get -y -f install
+ - eatmydata apt-get -y update
+ - eatmydata apt-get -y install intltool gettext
<<: *bullseye_vars
script:
- # barf on untranslated C files. Seems intltool
- # can't be told to exit with non-zero exit status
- # in this case
- - cd po/
- - intltool-update -m 2>&1 | grep -qs '/.*\.c' && { intltool-update -m; exit 1; } || exit 0
+ - tools/check-po
except:
variables:
- $PKG_ONLY == "1"
check-license-headers:
- <<: *tags
stage: test+docs
- image: debian:bullseye
needs:
- build:native-debian-bullseye
+ image: ${DEBIAN_IMAGE}
<<: *bullseye_vars
script:
# Checks .c and .h files begin with a license header as
@@ -211,13 +132,12 @@
- $PKG_ONLY == "1"
build:native-alpinelinux-edge:
- <<: *tags
stage: build
image: alpine:edge
allow_failure: true
before_script:
- echo "https://alpine.global.ssl.fastly.net/alpine/edge/testing" >> /etc/apk/repositories
- - apk -q add $ALPINE_EDGE_DEPS
+ - apk add $ALPINE_EDGE_DEPS
artifacts:
paths:
- _build
@@ -230,7 +150,6 @@
- $PKG_ONLY == "1"
unit-test:native-alpinelinux-edge:
- <<: *tags
stage: test+docs
image: alpine:edge
allow_failure: true
@@ -238,7 +157,7 @@
- build:native-alpinelinux-edge
before_script:
- echo "https://alpine.global.ssl.fastly.net/alpine/edge/testing" >> /etc/apk/repositories
- - apk -q add xvfb-run $ALPINE_EDGE_DEPS
+ - apk add xvfb-run $ALPINE_EDGE_DEPS
script:
- export LC_ALL=C.UTF-8
- ${XVFB_RUN} ninja -C _build test
@@ -250,75 +169,23 @@
variables:
- $PKG_ONLY == "1"
-test:smoke:one-output:
- <<: *tags
- stage: test+docs
- image: debian:buster
- variables: *smoketest_vars
- needs:
- - build:native-debian-buster
- script:
- - export OUTDIR=output
- - export G_DEBUG=fatal-criticals
- - export WLR_X11_OUTPUTS=1
- - 'echo "SMOKE_PARAMS: $SMOKE_PARAMS"'
- - tests/smoke $SMOKE_PARAMS
- artifacts:
- paths:
- - output/*.log
- - output/*.png
- when: always
- except:
- variables:
- - $PKG_ONLY == "1"
+package:deb-pureos-byzantium:arm64:
+ variables:
+ L5_DOCKER_IMAGE: pureos/byzantium
+ DEB_BUILD_PROFILES: nodoc
+ extends: .l5-build-debian-package
+ tags:
+ - aarch64
-test:smoke:two-outputs:
- <<: *tags
- stage: test+docs
- image: debian:buster
- variables: *smoketest_vars
+pages:
+ stage: deploy
needs:
- - build:native-debian-buster
+ - build-gtkdoc
script:
- - export OUTDIR=output
- - export G_DEBUG=fatal-criticals
- - export WLR_X11_OUTPUTS=2
- - 'echo "SMOKE_PARAMS: $SMOKE_PARAMS"'
- - tests/smoke $SMOKE_PARAMS
+ - mv _reference/ public/
artifacts:
paths:
- - output/*.log
- - output/*.png
- when: always
- except:
- variables:
- - $PKG_ONLY == "1"
-
-package:deb-debian-buster:
- extends: .l5-build-debian-package
- before_script: []
-
-package:deb-debian-bullseye:arm64:
- tags:
- - librem5:arm64
- variables:
- L5_DOCKER_IMAGE: debian:bullseye
- L5_ADD_SCRATCH_CI: 'false'
- before_script: []
- extends: .l5-build-debian-package
-
-package:deb-debian-buster:arm64:
- tags:
- - librem5:arm64
- before_script: []
- extends: .l5-build-debian-package
+ - public
+ only:
+ - main
-package:deb-pureos-amber:
- variables:
- L5_DOCKER_IMAGE: pureos/amber
- L5_ADD_SCRATCH_CI: 'false'
- before_script:
- - echo "deb https://repo.pureos.net/pureos amber-phone-staging main" > /etc/apt/sources.list.d/staging.list
- - echo "deb https://repo.pureos.net/pureos amber-proposed-updates main" >> /etc/apt/sources.list.d/staging.list
- extends: .l5-build-debian-package
- allow_failure: true
diff -Nru phosh-0.8.0/.gitmodules phosh-0.13.1/.gitmodules
--- phosh-0.8.0/.gitmodules 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/.gitmodules 2021-08-31 09:15:52.000000000 +0000
@@ -1,3 +1,6 @@
[submodule "subprojects/gvc"]
path = subprojects/gvc
url = https://gitlab.gnome.org/GNOME/libgnome-volume-control.git
+[submodule "subprojects/libcall-ui"]
+ path = subprojects/libcall-ui
+ url = https://gitlab.gnome.org/World/Phosh/libcall-ui.git
diff -Nru phosh-0.8.0/HACKING.md phosh-0.13.1/HACKING.md
--- phosh-0.8.0/HACKING.md 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/HACKING.md 2021-08-31 09:15:52.000000000 +0000
@@ -106,8 +106,8 @@
```
- private methods and callbacks (these can also go at convenient
places above `phosh_thing_constructed ()`
- - `phosh_thing_set_properties ()`
- - `phosh_thing_get_properties ()`
+ - `phosh_thing_set_property ()`
+ - `phosh_thing_get_property ()`
- `phosh_thing_constructed ()`
- `phosh_thing_dispose ()`
- `phosh_thing_finalize ()`
@@ -120,4 +120,33 @@
the header file and can thus be referenced from anywhere else in the source
file.
-[1]: https://source.puri.sm/Librem5/libhandy/blob/master/HACKING.md#coding-style
+CSS Theming
+===========
+For custom widget always set the css name using `gtk_widget_class_set_css_name ()`.
+There's no need set an (additional) style class in the ui file.
+
+*Good*:
+
+```c
+static void
+phosh_lockscreen_class_init (PhoshLockscreenClass *klass)
+{
+ …
+ gtk_widget_class_set_css_name (widget_class, "phosh-lockscreen");
+ …
+}
+```
+
+*Bad*:
+
+```xml
+
+ …
+
+ …
+
+```
+
+[1]: https://gitlab.gnome.org/GNOME/libhandy/blob/master/HACKING.md#coding-style
diff -Nru phosh-0.8.0/meson.build phosh-0.13.1/meson.build
--- phosh-0.8.0/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -1,5 +1,5 @@
project('phosh', 'c',
- version: '0.8.0',
+ version: '0.13.1',
license: 'GPLv3+',
meson_version: '>= 0.50.0',
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
@@ -15,25 +15,16 @@
sessiondir = join_paths(datadir, 'gnome-session')
pkgdatadir = join_paths(datadir, meson.project_name())
pkglibdir = join_paths(libdir, meson.project_name())
+systemddir = join_paths(prefix, 'lib/systemd')
+systemduserdir = join_paths(systemddir, 'user')
-config_h = configuration_data()
-config_h.set_quoted('GETTEXT_PACKAGE', 'phosh')
-config_h.set_quoted('LOCALEDIR', localedir)
-config_h.set_quoted('PHOSH_VERSION', meson.project_version())
-
-configure_file(
- input: 'config.h.in',
- output: 'config.h',
- configuration: config_h,
-)
-
-glib_ver = 'GLIB_VERSION_2_58'
+glib_ver = 'GLIB_VERSION_2_62'
add_project_arguments([
'-DHAVE_CONFIG_H',
'-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_ver),
+ '-DGLIB_VERSION_MAX_REQUIRED=@0@'.format(glib_ver),
'-DG_LOG_USE_STRUCTURED',
- '-I' + meson.build_root(),
], language: 'c')
root_inc = include_directories('.')
@@ -103,14 +94,34 @@
gnome = import('gnome')
i18n = import('i18n')
+if get_option('g_tests')
+ glib_ver = '>= 2.69'
+else
+ glib_ver = '>= 2.62'
+endif
+
gcr_dep = dependency('gcr-3', version: '>= 3.7.5')
-gio_dep = dependency('gio-2.0', version: '>=2.58')
-gio_unix_dep = dependency('gio-unix-2.0', version: '>=2.58')
-glib_dep = dependency('glib-2.0', version: '>=2.58')
+glib_dep = dependency('glib-2.0',
+ version: glib_ver,
+ fallback: ['glib', 'libglib_dep'],
+ default_options: ['tests=false']
+ )
+gio_dep = dependency('gio-2.0',
+ version: glib_ver,
+ fallback: ['glib', 'libgio_dep'],
+ default_options: ['tests=false']
+ )
+gobject_dep = dependency('gobject-2.0',
+ version: glib_ver,
+ fallback: ['glib', 'libgobject_dep'],
+ default_options: ['tests=false']
+ )
+gio_unix_dep = dependency('gio-unix-2.0', version: '>=2.62')
gnome_desktop_dep = dependency('gnome-desktop-3.0', version: '>=3.26')
-gobject_dep = dependency('gobject-2.0', version: '>=2.50.0')
+gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas')
gtk_dep = dependency('gtk+-3.0', version: '>=3.22')
gtk_wayland_dep = dependency('gtk+-wayland-3.0', version: '>=3.22')
+gudev_dep = dependency('gudev-1.0')
libfeedback_dep = dependency('libfeedback-0.0',
fallback: ['libfeedback', 'libfeedback_dep'],
default_options: ['introspection=disabled', 'daemon=false', 'gtk_doc=false']
@@ -127,10 +138,21 @@
])
libgvc_dep = libgvc.get_variable('libgvc_dep')
libhandy_dep = dependency('libhandy-1',
- version: '>=1.0.0',
+ version: '>=1.1.90',
fallback: ['libhandy', 'libhandy_dep'],
default_options: ['introspection=disabled']
)
+libcall_ui = subproject('libcall-ui',
+ default_options: [
+ 'package_name=' + meson.project_name(),
+ 'package_version=' + meson.project_version(),
+ 'pkgdatadir=' + pkgdatadir,
+ 'pkglibdir=' + pkglibdir,
+ 'examples=false',
+ 'gtk_doc=false',
+ 'tests=false',
+ ])
+libcall_ui_dep = libcall_ui.get_variable('libcall_ui_dep')
libnm_dep = dependency('libnm', version: '>= 1.14')
libpolkit_agent_dep = dependency('polkit-agent-1', version: '>= 0.105')
# TODO: make optional for elogind?
@@ -140,6 +162,26 @@
wayland_client_dep = dependency('wayland-client', version: '>=1.14')
wayland_protos_dep = dependency('wayland-protocols', version: '>=1.12')
+
+code ='''
+#include
+
+struct rfkill_event_ext e;
+'''
+have_rfkill_event_ext = cc.compiles(code, name : 'Have rfkill_event_ext')
+
+config_h = configuration_data()
+config_h.set_quoted('GETTEXT_PACKAGE', 'phosh')
+config_h.set_quoted('LOCALEDIR', localedir)
+config_h.set_quoted('PHOSH_VERSION', meson.project_version())
+config_h.set('HAVE_RFKILL_EVENT_EXT', have_rfkill_event_ext)
+
+configure_file(
+ input: 'config.h.in',
+ output: 'config.h',
+ configuration: config_h,
+)
+
meson.add_install_script(
join_paths('build-aux', 'post_install.py'),
datadir
@@ -160,6 +202,8 @@
'',
' Tests: @0@'.format(get_option('tests')),
' Phoc Tests: @0@'.format(run_phoc_tests),
+ ' Compositor: @0@'.format(get_option('compositor')),
+ ' Systemd: @0@'.format(get_option('systemd')),
'Documentation: @0@'.format(get_option('gtk_doc')),
'-----------',
]
diff -Nru phosh-0.8.0/meson_options.txt phosh-0.13.1/meson_options.txt
--- phosh-0.8.0/meson_options.txt 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/meson_options.txt 2021-08-31 09:15:52.000000000 +0000
@@ -8,4 +8,17 @@
option('gtk_doc',
type: 'boolean', value: false,
- description: 'Whether to generate the API reference for Handy')
+ description: 'Whether to generate the API reference for Phosh')
+
+option('systemd',
+ type: 'boolean', value: false,
+ description: 'Whether to generate systemd user units')
+
+option('compositor',
+ type: 'string', value: '/usr/bin/phoc',
+ description: 'Path to the Phoc compositor for use in the launcher script')
+
+# For some tests we need (unreleased) glib >= 2.69
+option('g_tests',
+ type: 'boolean', value: false,
+ description: 'Whether to build tests that require recent glib')
diff -Nru phosh-0.8.0/NEWS phosh-0.13.1/NEWS
--- phosh-0.8.0/NEWS 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/NEWS 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,76 @@
+phosh 0.13.1
+------------
+Released: August 2021
+* Cycle through all feedback profiles in quick setting
+ (Pablo Correa Gómez)
+* Add button to close all notifications (Guido Günther)
+* Improve support for mounting encrypted media (Guido Günther)
+* Don't launch app twice when keyboard activated from search bar
+ (Guido Günther)
+* Improve fractional scaling support (Guido Günther)
+* Better media player styling (Guido Günther)
+* UI translations:
+ Daniel Șerbănescu (ro)
+ Kristjan SCHMIDT (eo)
+ Marc Riera (ca)
+ Michael Oppliger (de)
+ Andika Triwidada (id)
+
+phosh 0.13.0
+------------
+Released: August 2021
+* torch: Use logind for torch brightness. This obsoletes any upower changes.
+ (Arnaud Ferraris)
+* Support high contrast mode (David Hamner, Guido Günther)
+* ci: Use prebuilt docker images in CI to speedup builds and save resources
+ (Guido Günther)
+* lockscreen: Handle incoming phone calls (Guido Günther)
+* backrounds: Handle fractional scaling (Guido Günther)
+* notifications: Look at category for notification feedback
+* lockscreen: Display notification summary and handle global
+ "show-in-lock-screen" toggle (Guido Günther)
+* panel: Fix power menu close on tap (Mohammed Sadiq)
+* quick settings: Cycle through all feedback settings instead of only
+ full / silent (Pablo Correa Gomez)
+* Migrate to GNOME World (Andrea Veri, Guido Günther)
+* UI translations:
+ Anders Jonsson (sv)
+ Efstathios Iosifidis (el)
+ Rafael Fontenelle (pt_BR)
+ Vittorio Monti (it)
+ Yuri Chornoivan (uk)
+ Мирослав Николић (sr)
+
+phosh 0.12.1
+------------
+Released: July 2021
+* Fix defaults for favorites
+* Append 'Phosh' to XDG_CURRENT_DESKOP for the system unit too so overrides get
+ applied even when not using a display manager
+* Bring search bar closer to designs again
+* Simplify tests and test calls-manager. Fix leaks spotted by those.
+* Don't claim accelerometer when rotation lock is on reducing iio-sensor-proxy
+ wakeups considerably
+* i18n updates: uk, it, sv
+
+phosh 0.12.0
+------------
+Released: June 2021
+* Only enable proximity sensor on active calls, unblank screen on incoming
+ calls. This needs at least gnome-calls 0.3.4 and either one of
+ https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3614
+ https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2120
+* Implement most parts of org.Gtk.MountOperationHandler to handle
+ encrypted volume mounts in e.g. nautilus.
+* Show adaptive apps in mobile mode and all apps in docked mode. This
+ can be toggled via the sm.puri.phosh.PhoshAppFilterModeFlags GSetting.
+
+phosh 0.11.0
+------------
+Released: May 2021
+* Wifi/WWAN/BT quick settings toggle on/off, long press opens Settings
+* Initial support for gnome-session --systemd
+* Torch brightness slider
+* Allow to show battery percentage in top bar
+* Fixes modal-dialog keyboard navigation
+* Fixes crash with ja locale
diff -Nru phosh-0.8.0/phosh.doap phosh-0.13.1/phosh.doap
--- phosh-0.8.0/phosh.doap 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/phosh.doap 2021-08-31 09:15:52.000000000 +0000
@@ -10,7 +10,7 @@
A wayland shell PoC for for mobile phones
Phosh aims to be a wayland shell for mobile phones.
This is merely a PoC at the moment.
-
+
C
@@ -19,12 +19,14 @@
Guido Günther
+ guidog
Zander Brown
+ zbrown
diff -Nru phosh-0.8.0/po/ca.po phosh-0.13.1/po/ca.po
--- phosh-0.8.0/po/ca.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/ca.po 2021-08-31 09:15:52.000000000 +0000
@@ -5,15 +5,17 @@
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-07-18 15:28+0000\n"
-"PO-Revision-Date: 2020-07-18 18:45+0200\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-09 09:29+0000\n"
+"PO-Revision-Date: 2021-08-09 12:40+0200\n"
"Last-Translator: Marc Riera \n"
"Language-Team: Catalan\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 3.0\n"
#. Translators: this is the session name, no need to translate it
#: data/phosh.session.desktop.in.in:4
@@ -26,112 +28,302 @@
#: data/sm.puri.Phosh.desktop.in.in:5
msgid "Window management and application launching for mobile"
-msgstr "Gestió de finestres i llançament d'aplicacions per a mòbils"
+msgstr "Gestió de finestres i inici d'aplicacions per a mòbils"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Aplicació"
-#: src/bt-info.c:89 src/feedbackinfo.c:48
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Activat"
-#: src/bt-info.c:91
+#: src/bt-info.c:94
msgid "Bluetooth"
msgstr "Bluetooth"
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Acoblat"
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr "Desacoblat"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Surt"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "Es tancarà la sessió de %s automàticament d'aquí a %d segon."
+msgstr[1] "Es tancarà la sessió de %s automàticament d'aquí a %d segons."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Apaga"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "El sistema s'apagarà automàticament d'aquí a %d segon."
+msgstr[1] "El sistema s'apagarà automàticament d'aquí a %d segons."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Reinicia"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "El sistema es reiniciarà automàticament d'aquí a %d segon."
+msgstr[1] "El sistema es reiniciarà automàticament d'aquí a %d segons."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Aplicació desconeguda"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Silenciós"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Desactivat"
-#: src/lockscreen.c:84 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Voleu permetre que «%s» accedeixi a la informació de la ubicació?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Geolocalització"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Sí"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "No"
+
+#: src/lockscreen.c:157 src/ui/lockscreen.ui:267
msgid "Enter Passcode"
msgstr "Introduïu la contrasenya"
-#: src/lockscreen.c:263
+#: src/lockscreen.c:340
msgid "Checking…"
msgstr "S'està comprovant…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:341
+#: src/lockscreen.c:418
msgid "%A, %B %-e"
-msgstr "%A, %d %B"
+msgstr "%A, %-e %B"
-#: src/media-player.c:262
-msgid "Unknown title"
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+msgid "Unknown Title"
msgstr "Títol desconegut"
-#: src/media-player.c:270
-msgid "Unknown artist"
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
msgstr "Artista desconegut"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Pantalla interna"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Desconegut"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
msgstr "No s'admet el tipus d'autenticació de la xarxa sense fil «%s»"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Introduïu la contrasenya de la xarxa sense fil «%s»"
-#: src/notifications/notification.c:365 src/notifications/notification.c:581
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Obre"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Notificació"
-#: src/polkit-auth-agent.c:229
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "min"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "min"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "dia"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "dies"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "mes"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "mesos"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "any"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "anys"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "ara"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Més de %d anys"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Gairebé %d anys"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s %d %s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "L'usuari ha descartat el diàleg d'autenticació"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Contrasenya:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "S'ha produït un error. Torneu-ho a provar."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Autenticació"
-
-#: src/rotateinfo.c:46
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Vertical"
-#: src/rotateinfo.c:49
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Apaïsat"
-#: src/system-prompt.c:371
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Desactivada"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Les contrasenyes no coincideixen."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "La contrasenya no pot estar en blanc"
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Llanterna"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Recorda la decisió"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Cancel·la"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "D'acord"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Aplicació"
@@ -144,62 +336,85 @@
msgid "Add to _Favorites"
msgstr "Afegeix als _preferits"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Cerca aplicacions…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Mostra només les aplicacions adaptatives"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Algunes aplicacions estan ocupades o tenen feina sense desar"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Usuari:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domini:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "Co_nnecta"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Llisqueu cap amunt per desbloquejar"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:313
msgid "Emergency"
msgstr "Emergència"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:329
msgid "Unlock"
-msgstr "Desbloca"
+msgstr "Desbloqueja"
-#: src/ui/media-player.ui:107
-msgid "Unknown Song"
-msgstr "Cançó desconeguda"
+#: src/ui/lockscreen.ui:369
+msgid "Back"
+msgstr "Torna"
-#: src/ui/media-player.ui:127
-msgid "Unknown Artist"
-msgstr "Artista desconegut"
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Cal autenticació"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Cancel·la"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "C_onnecta"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Usuari:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Autenticació"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Confirmació:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Bloqueja la pantalla"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Surt"
-#: src/ui/top-panel.ui:29
-msgid "Power Off"
-msgstr "Apaga"
-
-#: src/wifiinfo.c:88
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Sense fil"
-#: src/wwaninfo.c:167
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Mòbil"
+
+#~ msgid "Unknown artist"
+#~ msgstr "Artista desconegut"
+
+#~ msgid "Unknown Song"
+#~ msgstr "Cançó desconeguda"
diff -Nru phosh-0.8.0/po/cs.po phosh-0.13.1/po/cs.po
--- phosh-0.8.0/po/cs.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/cs.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,21 +1,26 @@
-# Jaroslav Svoboda , 2018. #zanata
# Daniel Rusek , 2019. #zanata
-# Jaroslav Svoboda , 2019. #zanata
+# Jaroslav Svoboda , 2019-2021.
+#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-14 13:18+0100\n"
+"POT-Creation-Date: 2021-01-15 14:23+0100\n"
+"PO-Revision-Date: 2021-03-03 21:13+0100\n"
+"Last-Translator: Jaroslav Svoboda \n"
+"Language-Team: Czech \n"
+"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2019-11-11 04:58+0000\n"
-"Last-Translator: Daniel Rusek \n"
-"Language-Team: Czech\n"
-"Language: cs\n"
-"X-Generator: Zanata 4.6.2\n"
+"X-Generator: Gtranslator 3.38.0\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
+#. Translators: this is the session name, no need to translate it
+#: data/phosh.session.desktop.in.in:4
+msgid "Phosh"
+msgstr "Phosh"
+
#: data/sm.puri.Phosh.desktop.in.in:4
msgid "Phone Shell"
msgstr "Shell telefonu"
@@ -24,119 +29,251 @@
msgid "Window management and application launching for mobile"
msgstr "Správa oken a spouštění aplikací pro mobilní zařízení"
-#. Translators: this is the session name, no need to translate it
-#: data/phosh.session.desktop.in.in:4
-msgid "Phosh"
-msgstr "Phosh"
-
-#: src/app-grid-button.c:523
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Aplikace"
-#: src/feedbackinfo.c:38
+#: src/bt-info.c:92 src/feedbackinfo.c:51
+msgid "On"
+msgstr "Zapnout"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "V doku"
+
+#: src/docked-info.c:195
+msgid "Undocked"
+msgstr "Mobilní"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:44
msgid "Quiet"
-msgstr ""
+msgstr "Ztlumeno"
-#: src/feedbackinfo.c:40
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:49
msgid "Silent"
-msgstr ""
+msgstr "Potichu"
-#: src/feedbackinfo.c:42
-msgid "On"
-msgstr ""
-
-#: src/lockscreen.c:78 src/ui/lockscreen.ui:204
+#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
msgid "Enter Passcode"
-msgstr "Vložte heslo"
+msgstr "Zadejte heslo"
-#: src/lockscreen.c:257
+#: src/lockscreen.c:265
msgid "Checking…"
-msgstr "Kontroluji…"
+msgstr "Kontroluje se…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:334
+#: src/lockscreen.c:343
msgid "%A, %B %-e"
msgstr "%A, %B %-e"
-#: src/monitor-manager.c:53
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:277 src/ui/media-player.ui:107
+msgid "Unknown Title"
+msgstr "Neznámý název"
+
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:286 src/ui/media-player.ui:127
+msgid "Unknown Artist"
+msgstr "Neznámý umělec"
+
+#: src/monitor-manager.c:71
msgid "Built-in display"
msgstr "Vestavěný displej"
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:57
+#: src/monitor-manager.c:75
msgid "Unknown"
-msgstr "Neznámý"
+msgstr "Neznámé"
+
+#: src/network-auth-prompt.c:187
+#, c-format
+msgid "Authentication type of wifi network “%s” not supported"
+msgstr "Typ autentizace wifi sítě “%s” není podporován"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
-msgstr ""
+msgstr "Vložte heslo wifi sítě \"%s”"
+
+#: src/notifications/mount-notification.c:137
+msgid "Open"
+msgstr "Otevřít"
+
+#: src/notifications/notification.c:381 src/notifications/notification.c:637
+msgid "Notification"
+msgstr "Upozornění"
+
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "min"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "min"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "měs"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "měs"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "r"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "r"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "nyní"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Více než %dy"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Téměř %dy"
-#: src/polkit-auth-agent.c:229
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:232
msgid "Authentication dialog was dismissed by the user"
msgstr "Autentizační dialog byl zavřen uživatelem"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
+#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:130
#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
msgid "Password:"
msgstr "Heslo:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:324
msgid "Sorry, that didn’t work. Please try again."
msgstr "Promiňte, toto nefungovalo. Zkuste to prosím znovu."
-#: src/polkit-auth-prompt.c:488
+#: src/polkit-auth-prompt.c:469
msgid "Authenticate"
msgstr "Autentizovat"
-#: src/system-prompt.c:371
+#: src/rotateinfo.c:65
+msgid "Portrait"
+msgstr "Portrét"
+
+#: src/rotateinfo.c:68
+msgid "Landscape"
+msgstr "Na šířku"
+
+#: src/system-prompt.c:373
msgid "Passwords do not match."
msgstr "Hesla nesouhlasí."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:380
msgid "Password cannot be blank"
msgstr "Heslo nemůže být prázdné"
-#: src/wifiinfo.c:55
-msgid "Wi-Fi"
-msgstr ""
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Svítilna"
-#: src/ui/app-grid-button.ui:48
+#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Aplikace"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
-msgstr ""
+msgstr "Odstranit z _Oblíbených"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
-msgstr ""
+msgstr "Přidat do _Oblíbených"
#: src/ui/app-grid.ui:21
msgid "Search apps…"
msgstr "Hledat aplikace…"
-#: src/ui/lockscreen.ui:36
+#: src/ui/lockscreen.ui:37
msgid "Slide up to unlock"
msgstr "Táhnutím nahoru odemknete"
-#: src/ui/lockscreen.ui:250
+#: src/ui/lockscreen.ui:280
msgid "Emergency"
-msgstr ""
+msgstr "Tísňové volání"
-#: src/ui/lockscreen.ui:266
+#: src/ui/lockscreen.ui:296
msgid "Unlock"
-msgstr ""
+msgstr "Odemknout"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:89
msgid "_Cancel"
-msgstr ""
+msgstr "_Zrušit"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:105
msgid "C_onnect"
-msgstr ""
+msgstr "_Připojit"
#: src/ui/polkit-auth-prompt.ui:105
msgid "User:"
@@ -145,3 +282,31 @@
#: src/ui/system-prompt.ui:69
msgid "Confirm:"
msgstr "Potvrdit:"
+
+#: src/ui/top-panel.ui:15
+msgid "Lock Screen"
+msgstr "Zamknout obrazovku"
+
+#: src/ui/top-panel.ui:22
+msgid "Logout"
+msgstr "Odhlásit"
+
+#: src/ui/top-panel.ui:29
+msgid "Restart"
+msgstr "Restartovat"
+
+#: src/ui/top-panel.ui:36
+msgid "Power Off"
+msgstr "Vypnout"
+
+#: src/wifiinfo.c:90
+msgid "Wi-Fi"
+msgstr "Wi-Fi"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:170
+msgid "Cellular"
+msgstr "Mobilní síť"
+
+#~ msgid "%d.%m.%y"
+#~ msgstr "%d.%měs.%r"
diff -Nru phosh-0.8.0/po/da.po phosh-0.13.1/po/da.po
--- phosh-0.8.0/po/da.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/da.po 2021-08-31 09:15:52.000000000 +0000
@@ -2,15 +2,16 @@
# Copyright (C) 2020 phosh's COPYRIGHT HOLDER
# This file is distributed under the same license as the phosh package.
# Simon Jespersen , 2018-2019. #zanata
-# scootergrisen, 2020.
+# scootergrisen, 2020-2021.
+# scootergrisen: oversættelsen mangler at blive testet
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-08-14 15:29+0000\n"
-"PO-Revision-Date: 2020-09-15 00:00+0200\n"
+"POT-Creation-Date: 2021-04-01 03:31+0000\n"
+"PO-Revision-Date: 2021-04-15 00:00+0200\n"
"Last-Translator: scootergrisen\n"
-"Language-Team: Danish \n"
+"Language-Team: Danish\n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -30,77 +31,159 @@
msgid "Window management and application launching for mobile"
msgstr "Vindueshåndtering og programstarter til mobiltelefon"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Program"
-#: src/bt-info.c:89 src/feedbackinfo.c:48
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Til"
-#: src/bt-info.c:91
+#: src/bt-info.c:94
msgid "Bluetooth"
msgstr "Bluetooth"
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Forankeret"
+
+#: src/docked-info.c:81 src/docked-info.c:195
+msgid "Undocked"
+msgstr "Ikke forankeret"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Log ud"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s logges automatisk ud om %d sekund."
+msgstr[1] "%s logges automatisk ud om %d sekunder."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Sluk"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Systemet slukkes automatisk om %d sekund."
+msgstr[1] "Systemet slukkes automatisk om %d sekunder."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Genstart"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Systemet genstartes automatisk om %d sekund."
+msgstr[1] "Systemet genstartes automatisk om %d sekunder."
+
+#: src/end-session-dialog.c:270
+#| msgid "Application"
+msgid "Unknown application"
+msgstr "Ukendt program"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Stille"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Lydløs"
-#: src/lockscreen.c:84 src/ui/lockscreen.ui:234
+#: src/location-manager.c:246
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Tillad at '%s' får adgang til din placeringsinformation?"
+
+#: src/location-manager.c:251
+#| msgid "Application"
+msgid "Geolocation"
+msgstr "Geoplacering"
+
+#: src/location-manager.c:252
+msgid "Yes"
+msgstr "Ja"
+
+#: src/location-manager.c:252
+msgid "No"
+msgstr "Nej"
+
+#: src/lockscreen.c:85 src/ui/lockscreen.ui:234
msgid "Enter Passcode"
msgstr "Indtast adgangskode"
-#: src/lockscreen.c:263
+#: src/lockscreen.c:264
msgid "Checking…"
msgstr "Tjekker …"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:341
+#: src/lockscreen.c:342
msgid "%A, %B %-e"
msgstr "%A %d. %B"
#. Translators: Used when the title of a song is unknown
-#: src/media-player.c:263 src/ui/media-player.ui:107
-#| msgid "Unknown title"
+#: src/media-player.c:277 src/ui/media-player.ui:107
msgid "Unknown Title"
msgstr "Ukendt titel"
#. Translators: Used when the artist of a song is unknown
-#: src/media-player.c:272 src/ui/media-player.ui:127
+#: src/media-player.c:286 src/ui/media-player.ui:127
msgid "Unknown Artist"
msgstr "Ukendt kunstner"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:112
msgid "Built-in display"
msgstr "Indbygget skærm"
+#: src/monitor-manager.c:130
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:137
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %sn"
+msgstr "%s %sn"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:146
msgid "Unknown"
msgstr "Ukendt"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
msgstr "Godkendelsestypen for wifi-netværket “%s” understøttes ikke"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Indtast adgangskode til wifi-netværket “%s”"
-#: src/notifications/notification.c:382 src/notifications/notification.c:601
+#: src/notifications/mount-notification.c:137
+msgid "Open"
+msgstr "Åbn"
+
+#: src/notifications/notification.c:381 src/notifications/notification.c:637
msgid "Notification"
msgstr "Underretning"
@@ -170,54 +253,87 @@
msgid "y"
msgstr "å"
-#. Translators: this is the date in (short) number only format
-#: src/notifications/timestamp-label.c:107
-msgid "%d.%m.%y"
-msgstr "%d.%m.%y"
-
-#. Translators: Timestamp prefix (e.g. Over 5h)
-#: src/notifications/timestamp-label.c:198
-msgid "Over"
-msgstr "Over"
-
-#. Translators: Timestamp prefix (e.g. Almost 5h)
-#: src/notifications/timestamp-label.c:203
-msgid "Almost"
-msgstr "Næsten"
+#: src/notifications/timestamp-label.c:121
+#| msgid "Unknown"
+msgid "now"
+msgstr "nu"
+
+# scootergrisen: tjek at det er korrekt
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+#| msgid "Over"
+msgid "Over %dy"
+msgstr "Over %då"
+
+# scootergrisen: tjek at det er korrekt
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+#| msgid "Almost"
+msgid "Almost %dy"
+msgstr "Næsten %då"
+
+# scootergrisen: tjek at det er korrekt
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
-#: src/polkit-auth-agent.c:229
+#: src/polkit-auth-agent.c:225
msgid "Authentication dialog was dismissed by the user"
msgstr "Godkendelsesdialogen blev lukket af brugeren"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:85
+#: src/ui/polkit-auth-prompt.ui:57 src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Adgangskode:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Beklager, det virkede ikke. Prøv venligst igen."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Godkend"
-
-#: src/rotateinfo.c:46
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Portræt"
-#: src/rotateinfo.c:49
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Landskab"
-#: src/system-prompt.c:371
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:183
+msgid "Off"
+msgstr "Fra"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Adgangskoderne er ikke ens."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Adgangskoden må ikke være tom"
+# scootergrisen: ved ikke hvad "Torch" er. Tjek at det er korrekt oversat
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Lommelygte (Torch)"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Husk beslutning"
+
+#: src/ui/app-auth-prompt.ui:55 src/ui/end-session-dialog.ui:50
+#| msgid "_Cancel"
+msgid "Cancel"
+msgstr "Annuller"
+
+#: src/ui/app-auth-prompt.ui:66 src/ui/end-session-dialog.ui:61
+msgid "Ok"
+msgstr "OK"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Program"
@@ -234,6 +350,10 @@
msgid "Search apps…"
msgstr "Søger efter programmer …"
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Nogle programmer er optagede eller har arbejde som ikke er blevet gemt"
+
#: src/ui/lockscreen.ui:37
msgid "Slide up to unlock"
msgstr "Skub op for at låse op"
@@ -246,43 +366,40 @@
msgid "Unlock"
msgstr "Lås op"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+#| msgid "Authenticate"
+msgid "Authentication required"
+msgstr "Godkendelse kræves"
+
+#: src/ui/network-auth-prompt.ui:42
msgid "_Cancel"
msgstr "_Annuller"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:61
msgid "C_onnect"
msgstr "_Opret forbindelse"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Bruger:"
+#: src/ui/polkit-auth-prompt.ui:125
+msgid "Authenticate"
+msgstr "Godkend"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Bekræft:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Lås skærm"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Log ud"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Genstart"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Sluk"
-
-#: src/wifiinfo.c:88
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: Refers to the cellular wireless network
-#: src/wwaninfo.c:168
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Mobil"
diff -Nru phosh-0.8.0/po/de.po phosh-0.13.1/po/de.po
--- phosh-0.8.0/po/de.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/de.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,6 +1,7 @@
# German translation for phosh
# Copyright (C) 2018 THE phosh'S COPYRIGHT HOLDER
# This file is distributed under the same license as the phosh package.
+#
# Guido Günther , 2018
# Daniel Brunkhorst , 2018. #zanata
# Guido Günther , 2018. #zanata
@@ -13,21 +14,24 @@
# Mike Ballmann , 2020. #zanata
# heiko123abc , 2020.
# Tim Sabsch , 2020.
+# Michael Oppliger , 2021.
+# Philipp Kiemle , 2021.
+#
#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-06-25 08:32+0200\n"
-"PO-Revision-Date: 2020-07-29 10:16+0200\n"
-"Last-Translator: Tim Sabsch \n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-11 13:39+0000\n"
+"PO-Revision-Date: 2021-08-16 20:36+0200\n"
+"Last-Translator: Philipp Kiemle \n"
"Language-Team: German \n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3.1\n"
+"X-Generator: Poedit 2.4.2\n"
#. Translators: this is the session name, no need to translate it
#: data/phosh.session.desktop.in.in:4
@@ -42,177 +46,396 @@
msgid "Window management and application launching for mobile"
msgstr "Fensterverwaltung und Starten von Apps für mobile Geräte"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Anwendung"
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
+msgid "On"
+msgstr "An"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Angedockt"
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr "Abgedockt"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Abmelden"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s wird automatisch in %d Sekunde abgemeldet."
+msgstr[1] "%s wird automatisch in %d Sekunden abgemeldet."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Ausschalten"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Das System wird in %d Sekunde ausgeschaltet."
+msgstr[1] "Das System wird in %d Sekunden ausgeschaltet."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Neustart"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Das System wird in %d Sekunde neu gestartet."
+msgstr[1] "Das System wird in %d Sekunden neu gestartet."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Unbekannte Anwendung"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Leise"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Lautlos"
-#: src/feedbackinfo.c:42
-msgid "On"
-msgstr "An"
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Zulassen, dass »%s« Ihre Standortinformationen abruft?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Standort"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Ja"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Nein"
-#: src/lockscreen.c:82 src/ui/lockscreen.ui:217
+#: src/lockscreen.c:157 src/ui/lockscreen.ui:267
msgid "Enter Passcode"
msgstr "Zugangscode eingeben"
-#: src/lockscreen.c:261
+#: src/lockscreen.c:340
msgid "Checking…"
msgstr "Überprüfung läuft …"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:339
+#: src/lockscreen.c:418
msgid "%A, %B %-e"
msgstr "%A %d. %B"
-#: src/media-player.c:244
-msgid "Unknown title"
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+msgid "Unknown Title"
msgstr "Unbekannter Titel"
-#: src/media-player.c:252
-msgid "Unknown artist"
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
msgstr "Unbekannter Künstler"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Eingebaute Anzeige"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Unbekannt"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
-msgstr "Die Art der Legitimierung des WLAN-Netzwerks »%s« wird nicht unterstützt"
+msgstr ""
+"Die Art der Legitimierung des WLAN-Netzwerks »%s« wird nicht unterstützt"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Geben Sie das Passwort für das WLAN-Netzwerk »%s« ein"
-#: src/notifications/notification.c:365 src/notifications/notification.c:581
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Öffnen"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Benachrichtigung"
-#: src/polkit-auth-agent.c:229
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "min"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "min"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "T"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "T"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "Mon"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "Mon"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "J"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "J"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "Jetzt"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Über %d J"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Fast %d J"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Der Dialog zur Anmeldung wurde vom Benutzer geschlossen"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Passwort:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
-msgstr "Entschuldigung, das hat nicht funktioniert. Bitte versuchen Sie es erneut."
+msgstr ""
+"Entschuldigung, das hat nicht funktioniert. Bitte versuchen Sie es erneut."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Legitimieren"
+#: src/rotateinfo.c:81
+msgid "Portrait"
+msgstr "Hochformat"
+
+#: src/rotateinfo.c:84
+msgid "Landscape"
+msgstr "Querformat"
+
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Aus"
-#: src/system-prompt.c:371
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Die Passwörter stimmen nicht überein."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Das Passwort darf nicht leer sein"
-#: src/ui/app-grid-button.ui:48
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Taschenlampe"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Entscheidung merken"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "OK"
+
+#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "App"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
msgstr "Aus _Favoriten entfernen"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
msgstr "Zu _Favoriten hinzufügen"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Apps suchen …"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Nur adaptive Apps anzeigen"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Einige Anwendungen sind beschäftigt oder haben ungesicherte Änderungen"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Benutzername:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domäne:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "_Verbinden"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Nach oben wischen zum Entsperren"
-#: src/ui/lockscreen.ui:263
+#: src/ui/lockscreen.ui:313
msgid "Emergency"
msgstr "Notruf"
-#: src/ui/lockscreen.ui:279
+#: src/ui/lockscreen.ui:329
msgid "Unlock"
msgstr "Entsperren"
-#: src/ui/media-player.ui:107
-msgid "Unknown Song"
-msgstr "Unbekannter Titel"
-
-#: src/ui/media-player.ui:127
-msgid "Unknown Artist"
-msgstr "Unbekannter Künstler"
+#: src/ui/lockscreen.ui:369
+msgid "Back"
+msgstr "Zurück"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Legitimierung erforderlich"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Abbrechen"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "_Verbinden"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Benutzername:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Legitimieren"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Bestätigen:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Bildschirm sperren"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Abmelden"
-#: src/ui/top-panel.ui:29
-msgid "Power Off"
-msgstr "Ausschalten"
-
-#: src/wifiinfo.c:55
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "WLAN"
-#~ msgid "Bluetooth"
-#~ msgstr "Bluetooth"
-
-#~ msgid "Portrait"
-#~ msgstr "Hochformat"
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
+msgid "Cellular"
+msgstr "Mobilfunk"
-#~ msgid "Landscape"
-#~ msgstr "Querformat"
+#~ msgid "Unknown artist"
+#~ msgstr "Unbekannter Künstler"
-#~ msgid "Cellular"
-#~ msgstr "Mobilfunk"
+#~ msgid "Unknown Song"
+#~ msgstr "Unbekannter Titel"
#~ msgid "Suspend"
#~ msgstr "Bereitschaft"
diff -Nru phosh-0.8.0/po/el.po phosh-0.13.1/po/el.po
--- phosh-0.8.0/po/el.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/el.po 2021-08-31 09:15:52.000000000 +0000
@@ -5,17 +5,22 @@
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-14 13:18+0100\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-04 02:02+0300\n"
+"Last-Translator: Efstathios Iosifidis \n"
+"Language-Team: Greek, Modern (1453-) \n"
+"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2020-04-14 12:26+0300\n"
-"Last-Translator: Efstathios Iosifidis \n"
-"Language-Team: Greek, Modern (1453-) \n"
-"Language: el\n"
-"X-Generator: Gtranslator 3.34.0\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Poedit 2.3\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. Translators: this is the session name, no need to translate it
+#: data/phosh.session.desktop.in.in:4
+msgid "Phosh"
+msgstr "Phosh"
#: data/sm.puri.Phosh.desktop.in.in:4
msgid "Phone Shell"
@@ -25,124 +30,387 @@
msgid "Window management and application launching for mobile"
msgstr "Διαχείριση παραθύρων και εκκίνησης εφαρμογών κινητού"
-#. Translators: this is the session name, no need to translate it
-#: data/phosh.session.desktop.in.in:4
-msgid "Phosh"
-msgstr "Phosh"
-
-#: src/app-grid-button.c:523
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Εφαρμογή"
-#: src/feedbackinfo.c:38
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
+msgid "On"
+msgstr "Ενεργό"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr ""
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr ""
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Αποσύνδεση"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "Ο %s θα αποσυνδεθεί αυτόματα σε %d δευτερόλεπτο."
+msgstr[1] "Ο %s θα αποσυνδεθεί αυτόματα σε %d δευτερόλεπτα."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Διακοπή λειτουργίας"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Το σύστημα θα απενεργοποιηθεί αυτόματα σε %d δευτερόλεπτο."
+msgstr[1] "Το σύστημα θα απενεργοποιηθεί αυτόματα σε %d δευτερόλεπτα."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Επανεκκίνηση"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Το σύστημα θα επανεκκινήσει αυτόματα σε %d δευτερόλεπτο."
+msgstr[1] "Το σύστημα θα επανεκκινήσει αυτόματα σε %d δευτερόλεπτα."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Άγνωστη εφαρμογή"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Σιωπηλό"
-#: src/feedbackinfo.c:40
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Αθόρυβο"
-#: src/feedbackinfo.c:42
-msgid "On"
-msgstr "Ενεργό"
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr ""
+"Να επιτρέπεται στο «%s» να έχει πρόσβαση στις πληροφορίες τοποθεσίας σας;"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Γεωεντοπισμός"
-#: src/lockscreen.c:78 src/ui/lockscreen.ui:204
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Ναι"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Όχι"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
msgstr "Εισάγετε συνθηματικό"
-#: src/lockscreen.c:257
+#: src/lockscreen.c:335
msgid "Checking…"
-msgstr "Γίνεται έλεγχος..."
+msgstr "Γίνεται έλεγχος…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:334
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %B %-e"
-#: src/monitor-manager.c:53
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+msgid "Unknown Title"
+msgstr "Άγνωστος τίτλος"
+
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
+msgstr "Άγνωστος καλλιτέχνης"
+
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Ενσωματομένη οθόνη"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:57
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Άγνωστος τύπος οθόνης"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
+#, c-format
+msgid "Authentication type of wifi network “%s” not supported"
+msgstr "Ο τύπος πιστοποίησης του ασύρματου δικτύου «%s» δεν υποστηρίζεται"
+
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Εισάγετε συνθηματικό για το ασύρματο δίκτυο «%s»"
-#: src/polkit-auth-agent.c:229
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Άνοιγμα"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
+msgid "Notification"
+msgstr "Ειδοποίηση"
+
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "δ"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "λ"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "λ"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "ω"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "ω"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "ημ"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "ημ"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "μην"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "μην"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "ετος"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "έτη"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "τώρα"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Πάνω από %dy"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Σχεδόν %dy"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Ο διάλογος πιστοποίησης απορρίφθηκε από τον χρήστη"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Συνθηματικό:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Συγγνώμη, παρουσιάστηκε σφάλμα. Παρακαλούμε δοκιμάστε ξανά."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Πιστοποίηση"
+#: src/rotateinfo.c:81
+msgid "Portrait"
+msgstr "Κάθετα"
+
+#: src/rotateinfo.c:84
+msgid "Landscape"
+msgstr "Οριζόντια"
+
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Ανενεργό"
-#: src/system-prompt.c:371
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Τα συνθηματικά δεν ταιριάζουν."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Το συνθηματικό δεν μπορεί να είναι κενό"
-#: src/wifiinfo.c:55
-msgid "Wi-Fi"
-msgstr "Wi-Fi"
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Φακός"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Απομνημόνευση απόφασης"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Ακύρωση"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "ΟΚ"
-#: src/ui/app-grid-button.ui:48
+#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Εφαρμογή"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
msgstr "Αφαίρεση από τα _αγαπημένα"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
msgstr "Προσθήκη στα _αγαπημένα"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
-msgstr "Αναζήτηση εφαρμογών..."
+msgstr "Αναζήτηση εφαρμογών…"
+
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Εμφάνιση μόνο προσαρμοσμένων εφαρμογών"
-#: src/ui/lockscreen.ui:36
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr ""
+"Ορισμένες εφαρμογές είναι απασχολημένες ή έχουν μη αποθηκευμένη εργασία"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Χρήστης:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Τομέας:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "_Σύνδεση"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Σύρετε προς τα πάνω για ξεκλείδωμα"
-#: src/ui/lockscreen.ui:250
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Επείγον"
-#: src/ui/lockscreen.ui:266
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Ξεκλείδωμα"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr "Πίσω"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Απαιτείται πιστοποίηση"
+
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Ακύρωση"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "_Σύνδεση"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Χρήστης:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Πιστοποίηση"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Επιβεβαίωση:"
+
+#: src/ui/top-panel.ui:16
+msgid "Lock Screen"
+msgstr "Κλείδωμα οθόνης"
+
+#: src/ui/top-panel.ui:23
+msgid "Logout"
+msgstr "Έξοδος"
+
+#: src/wifiinfo.c:90
+msgid "Wi-Fi"
+msgstr "Wi-Fi"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
+msgid "Cellular"
+msgstr "Κινητή τηλεφωνία"
diff -Nru phosh-0.8.0/po/eo.po phosh-0.13.1/po/eo.po
--- phosh-0.8.0/po/eo.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/eo.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,146 +1,417 @@
-# Martin Chang , 2018. #zanata
-# Martin Chang , 2019. #zanata
+# Esperanto translation for phosh.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is distributed under the same license as the phosh package
+# Martin CHANG , 2018-2019.
+# Kristjan SCHMIDT , 2021.
+# Colin REEDER , 2021.
+#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-14 13:18+0100\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-09 08:29+0000\n"
+"PO-Revision-Date: 2021-08-11 08:20+0200\n"
+"Last-Translator: Colin REEDER \n"
+"Language-Team: Esperanto\n"
+"Language: eo\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2019-12-04 04:34+0000\n"
-"Last-Translator: Martin Chang \n"
-"Language-Team: Esperanto\n"
-"Language: eo\n"
-"X-Generator: Zanata 4.6.2\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Poedit 3.0\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. Translators: this is the session name, no need to translate it
+#: data/phosh.session.desktop.in.in:4
+msgid "Phosh"
+msgstr "Phosh"
#: data/sm.puri.Phosh.desktop.in.in:4
msgid "Phone Shell"
-msgstr "Fona ŝelo"
+msgstr "Telefona Ŝelo"
#: data/sm.puri.Phosh.desktop.in.in:5
msgid "Window management and application launching for mobile"
-msgstr "Fenestroj administri kaj lanĉi aplikaĵoj por poŝtelefono"
+msgstr "Administrado de fenestroj kaj lanĉado de aplikaĵoj por poŝtelefono"
-#. Translators: this is the session name, no need to translate it
-#: data/phosh.session.desktop.in.in:4
-msgid "Phosh"
-msgstr "Phosh"
-
-#: src/app-grid-button.c:523
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Aplikaĵo"
-#: src/feedbackinfo.c:38
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
+msgid "On"
+msgstr "Ŝaltita"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bludento"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Dokita"
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr "Ne dokita"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Elsaluti"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s estos elsalutita aŭtomate post %d sekundo."
+msgstr[1] "%s estos elsalutita aŭtomate post %d sekundoj."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Malŝalti"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "La sistemo malŝaltos aŭtomate post %d sekundo."
+msgstr[1] "La sistemo malŝaltos aŭtomate post %d sekundoj."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Restartigi"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "La sistemo restartos aŭtomate post %d sekundo."
+msgstr[1] "La sistemo restartos aŭtomate post %d sekundoj."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Nekonata aplikaĵo"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:44
msgid "Quiet"
-msgstr ""
+msgstr "Mallaŭta"
-#: src/feedbackinfo.c:40
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:49
msgid "Silent"
-msgstr ""
+msgstr "Silenta"
-#: src/feedbackinfo.c:42
-msgid "On"
-msgstr ""
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Permesi '%s' atingi vian loko?"
-#: src/lockscreen.c:78 src/ui/lockscreen.ui:204
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Geolokigo"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Jes"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Ne"
+
+#: src/lockscreen.c:157 src/ui/lockscreen.ui:267
msgid "Enter Passcode"
msgstr "Enigu pasvorton"
-#: src/lockscreen.c:257
+#: src/lockscreen.c:340
msgid "Checking…"
msgstr "Kontroli…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:334
+#: src/lockscreen.c:418
msgid "%A, %B %-e"
msgstr "%A, %B %-e"
-#: src/monitor-manager.c:53
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+msgid "Unknown Title"
+msgstr "Nekonata titolo"
+
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
+msgstr "Nekonata artisto"
+
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Integra vidigo"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:57
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Nekonate"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
+#, c-format
+msgid "Authentication type of wifi network “%s” not supported"
+msgstr "Tipo de aŭtentigo de vifio-reto \"%s\" ne estas subtenata"
+
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
+msgstr "Enigu pasvorton por la vifio-reto \"%s\""
+
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Malfermi"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
+msgid "Notification"
+msgstr "Sciigo"
+
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "t"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "t"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "mo"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "mo"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "j"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "j"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "nuna"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Pli ol %dj"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Preskaŭ %dj"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
msgstr ""
-#: src/polkit-auth-agent.c:229
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
-msgstr "La aŭtentiga dialogo estis forigi laŭ la uzanto"
+msgstr "La aŭtentiga dialogo estis forigita de la uzanto"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Pasvorto:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
-msgstr "Pardonu, ĉi tio ne efikas. Bonvolu reprovi malfrue."
+msgstr "Pardonu, ĉi tio ne sukcesas. Bonvolu reprovi."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Permesi"
+#: src/rotateinfo.c:81
+msgid "Portrait"
+msgstr "Vertikala"
+
+#: src/rotateinfo.c:84
+msgid "Landscape"
+msgstr "Horizontala"
+
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Ne ŝaltita"
-#: src/system-prompt.c:371
+#: src/system-prompt.c:364
msgid "Passwords do not match."
-msgstr "Pasvortoj ne kongruas"
+msgstr "Pasvortoj ne kongruas."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Pasvorto devas ne malpleni"
-#: src/wifiinfo.c:55
-msgid "Wi-Fi"
-msgstr ""
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Poŝlampo"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Memori decidon"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Nuligi"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "Bone"
-#: src/ui/app-grid-button.ui:48
+#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Aplikaĵo"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
-msgstr ""
+msgstr "Forigi el _Legosignoj"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
-msgstr ""
+msgstr "Aldoni al _Legosignoj"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
-msgstr "Serĉi aplikaĵo…"
+msgstr "Serĉi aplikaĵojn…"
+
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Montri nur adapta aplikaĵojn"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Kelkaj aplikaĵoj estas okupita aŭ havas nekonservitajn ŝanĝojn"
-#: src/ui/lockscreen.ui:36
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Uzanto:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domajno:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "Ko_nekti"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Ŝovi supre por malŝlosi"
-#: src/ui/lockscreen.ui:250
+#: src/ui/lockscreen.ui:313
msgid "Emergency"
-msgstr ""
+msgstr "Krizo"
-#: src/ui/lockscreen.ui:266
+#: src/ui/lockscreen.ui:329
msgid "Unlock"
-msgstr ""
+msgstr "Malŝlosi"
+
+#: src/ui/lockscreen.ui:369
+msgid "Back"
+msgstr "Reen"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Aŭtentigo estas deviga"
+
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
-msgstr ""
+msgstr "_Nuligi"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
-msgstr ""
+msgstr "K_onekti"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Uzanto:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Aŭtentigi"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Konfirmi:"
+
+#: src/ui/top-panel.ui:16
+msgid "Lock Screen"
+msgstr "Ŝlosita Ekrano"
+
+#: src/ui/top-panel.ui:23
+msgid "Logout"
+msgstr "Elsaluti"
+
+#: src/wifiinfo.c:90
+msgid "Wi-Fi"
+msgstr "Vifio"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
+msgid "Cellular"
+msgstr "Ĉela"
diff -Nru phosh-0.8.0/po/ht.po phosh-0.13.1/po/ht.po
--- phosh-0.8.0/po/ht.po 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/po/ht.po 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,326 @@
+# Phosh Creole Haitian translation
+# Copyright (C) 2021 Purism
+# This file is distributed under the same license as the Phosh package.
+# Pierre Michel Augustin , 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
+"POT-Creation-Date: 2021-02-07 15:30+0000\n"
+"PO-Revision-Date: 2021-02-21 17:28-0500\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.0.6\n"
+"Last-Translator: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: ht_HT\n"
+
+#. Translators: this is the session name, no need to translate it
+#: data/phosh.session.desktop.in.in:4
+msgid "Phosh"
+msgstr "Phosh"
+
+#: data/sm.puri.Phosh.desktop.in.in:4
+msgid "Phone Shell"
+msgstr "Shell Telefòn"
+
+#: data/sm.puri.Phosh.desktop.in.in:5
+msgid "Window management and application launching for mobile"
+msgstr "Jesyon fenèt ak lansman aplikasyon pou mobil"
+
+#: src/app-grid-button.c:536
+msgid "Application"
+msgstr "Aplikasyon"
+
+#: src/bt-info.c:92 src/feedbackinfo.c:51
+msgid "On"
+msgstr "Sou"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Docked"
+
+#: src/docked-info.c:81 src/docked-info.c:195
+msgid "Undocked"
+msgstr "Undocked"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:44
+msgid "Quiet"
+msgstr "Trankil"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:49
+msgid "Silent"
+msgstr "Silans"
+
+#: src/lockscreen.c:85 src/ui/lockscreen.ui:234
+msgid "Enter Passcode"
+msgstr "Mete pas kod"
+
+#: src/lockscreen.c:264
+msgid "Checking…"
+msgstr "Ap verifye…"
+
+#. Translators: This is a time format for a date in
+#. long format
+#: src/lockscreen.c:342
+msgid "%A, %B %-e"
+msgstr "%A, %B %-e"
+
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:277 src/ui/media-player.ui:107
+msgid "Unknown Title"
+msgstr "Tit enkoni"
+
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:286 src/ui/media-player.ui:127
+msgid "Unknown Artist"
+msgstr "Atis enkoni"
+
+#: src/monitor-manager.c:108
+msgid "Built-in display"
+msgstr "Montre \"Built-in\""
+
+#: src/monitor-manager.c:126
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:133
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in"
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %sn"
+msgstr "%s %sn"
+
+#. Translators: An unknown monitor type
+#: src/monitor-manager.c:142
+msgid "Unknown"
+msgstr "Enkoni"
+
+#: src/network-auth-prompt.c:187
+#, c-format
+msgid "Authentication type of wifi network “%s” not supported"
+msgstr "Otantifikasyon kalite rezo wifi “%s” pa sipòte"
+
+#: src/network-auth-prompt.c:192
+#, c-format
+msgid "Enter password for the wifi network “%s”"
+msgstr "Mete modpas pou rezo wifi “%s” la"
+
+#: src/notifications/mount-notification.c:137
+msgid "Open"
+msgstr "Ouvri"
+
+#: src/notifications/notification.c:381 src/notifications/notification.c:637
+msgid "Notification"
+msgstr "Notifikasyon"
+
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "mo"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "mos"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "y"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "y"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "kounye a"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Plis pase %dy"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Prèske %dy"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:225
+msgid "Authentication dialog was dismissed by the user"
+msgstr "Dyalòg Otantifikasyon te ranvwaye pa itilizatè a"
+
+#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:127
+#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+msgid "Password:"
+msgstr "Mo de pas:"
+
+#: src/polkit-auth-prompt.c:325
+msgid "Sorry, that didn’t work. Please try again."
+msgstr "Eskize, sa pa te mache. Souple eseye ankò."
+
+#: src/polkit-auth-prompt.c:470
+msgid "Authenticate"
+msgstr "Otantifye"
+
+#: src/rotateinfo.c:65
+msgid "Portrait"
+msgstr "Pòtrè"
+
+#: src/rotateinfo.c:68
+msgid "Landscape"
+msgstr "Peyizaj"
+
+#: src/system-prompt.c:375
+msgid "Passwords do not match."
+msgstr "Mo de pas pa matche ak."
+
+#: src/system-prompt.c:382
+msgid "Password cannot be blank"
+msgstr "Mo de pas pa ka vid"
+
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Flach"
+
+#: src/ui/app-grid-button.ui:49
+msgid "App"
+msgstr "Aplikasyon"
+
+#: src/ui/app-grid-button.ui:76
+msgid "Remove from _Favorites"
+msgstr "Retire nan _sa_ou_renmen"
+
+#: src/ui/app-grid-button.ui:81
+msgid "Add to _Favorites"
+msgstr "Ajoute nan _sa_ou_renmen"
+
+#: src/ui/app-grid.ui:21
+msgid "Search apps…"
+msgstr "Chèche aplikasyon yo…"
+
+#: src/ui/lockscreen.ui:37
+msgid "Slide up to unlock"
+msgstr "Monte pou debloke"
+
+#: src/ui/lockscreen.ui:280
+msgid "Emergency"
+msgstr "Ijans"
+
+#: src/ui/lockscreen.ui:296
+msgid "Unlock"
+msgstr "Debloke"
+
+#: src/ui/network-auth-prompt.ui:89
+msgid "_Cancel"
+msgstr "_Anile"
+
+#: src/ui/network-auth-prompt.ui:105
+msgid "C_onnect"
+msgstr "K_onekte"
+
+#: src/ui/polkit-auth-prompt.ui:105
+msgid "User:"
+msgstr "Itilizatè:"
+
+#: src/ui/system-prompt.ui:69
+msgid "Confirm:"
+msgstr "Konfime:"
+
+#: src/ui/top-panel.ui:15
+msgid "Lock Screen"
+msgstr "Bloke ekran"
+
+#: src/ui/top-panel.ui:22
+msgid "Logout"
+msgstr "Dekonekte"
+
+#: src/ui/top-panel.ui:29
+msgid "Restart"
+msgstr "Redemare"
+
+#: src/ui/top-panel.ui:36
+msgid "Power Off"
+msgstr "Fèmen"
+
+#: src/wifiinfo.c:90
+msgid "Wi-Fi"
+msgstr "Wi-Fi"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:170
+msgid "Cellular"
+msgstr "Selilè"
diff -Nru phosh-0.8.0/po/hu.po phosh-0.13.1/po/hu.po
--- phosh-0.8.0/po/hu.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/hu.po 2021-08-31 09:15:52.000000000 +0000
@@ -3,7 +3,7 @@
msgstr ""
"Project-Id-Version: phosh\n"
"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-07-06 03:30+0000\n"
+"POT-Creation-Date: 2021-01-16 03:33+0000\n"
"PO-Revision-Date: 2020-07-08 12:55+0200\n"
"Last-Translator: Meskó Balázs \n"
"Language-Team: Hungarian\n"
@@ -27,115 +27,244 @@
msgid "Window management and application launching for mobile"
msgstr "Ablakkezelés és alkalmazásindítás mobilra"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Alkalmazás"
+#: src/bt-info.c:92 src/feedbackinfo.c:51
+msgid "On"
+msgstr "Be"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr ""
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr ""
+
+#: src/docked-info.c:195
+msgid "Undocked"
+msgstr ""
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Csendes"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Néma"
-#: src/feedbackinfo.c:48
-msgid "On"
-msgstr "Be"
-
-#: src/lockscreen.c:82 src/ui/lockscreen.ui:217
+#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
msgid "Enter Passcode"
msgstr "Adja meg a jelkódot"
-#: src/lockscreen.c:261
+#: src/lockscreen.c:265
msgid "Checking…"
msgstr "Ellenőrzés…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:339
+#: src/lockscreen.c:343
msgid "%A, %B %-e"
msgstr "%B %-d. %A"
-#: src/media-player.c:262
-msgid "Unknown title"
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:277 src/ui/media-player.ui:107
+#, fuzzy
+#| msgid "Unknown title"
+msgid "Unknown Title"
msgstr "Ismeretlen cím"
-#: src/media-player.c:270
-msgid "Unknown artist"
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:286 src/ui/media-player.ui:127
+msgid "Unknown Artist"
msgstr "Ismeretlen előadó"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:108
msgid "Built-in display"
msgstr "Beépített kijelző"
+#: src/monitor-manager.c:126
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr ""
+
+#: src/monitor-manager.c:133
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %sn"
+msgstr ""
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:142
msgid "Unknown"
msgstr "Ismeretlen"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
msgstr "A(z) „%s” Wi-Fi-hálózat hitelesítési típusa nem támogatott"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Adja meg a(z) „%s” Wi-Fi-hálózat jelszavát"
-#: src/notifications/notification.c:365 src/notifications/notification.c:581
+#: src/notifications/mount-notification.c:137
+msgid "Open"
+msgstr ""
+
+#: src/notifications/notification.c:381 src/notifications/notification.c:637
msgid "Notification"
msgstr "Értesítés"
-#: src/polkit-auth-agent.c:229
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr ""
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr ""
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr ""
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr ""
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr ""
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr ""
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr ""
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr ""
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr ""
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr ""
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr ""
+
+#: src/notifications/timestamp-label.c:121
+#, fuzzy
+#| msgid "Unknown"
+msgid "now"
+msgstr "Ismeretlen"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr ""
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr ""
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr ""
+
+#: src/polkit-auth-agent.c:232
msgid "Authentication dialog was dismissed by the user"
msgstr "A felhasználó bezárta a hitelesítési párbeszédet"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
+#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:130
#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
msgid "Password:"
msgstr "Jelszó:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Sajnáljuk, ez nem működött. Próbálja meg újra."
-#: src/polkit-auth-prompt.c:488
+#: src/polkit-auth-prompt.c:470
msgid "Authenticate"
msgstr "Hitelesítés"
-#: src/rotateinfo.c:46
+#: src/rotateinfo.c:65
msgid "Portrait"
msgstr "Álló"
-#: src/rotateinfo.c:49
+#: src/rotateinfo.c:68
msgid "Landscape"
msgstr "Fekvő"
-#: src/system-prompt.c:371
+#: src/system-prompt.c:375
msgid "Passwords do not match."
msgstr "A jelszavak nem egyeznek."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:382
msgid "Password cannot be blank"
msgstr "A jelszavak nem lehetnek üresek"
-#: src/ui/app-grid-button.ui:48
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr ""
+
+#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Alkalmazás"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
msgstr "Eltávolítás a _Kedvencek közül"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
msgstr "Hozzáadás a _Kedvencekhez"
@@ -147,27 +276,19 @@
msgid "Slide up to unlock"
msgstr "Csúsztassa fel a feloldáshoz"
-#: src/ui/lockscreen.ui:263
+#: src/ui/lockscreen.ui:280
msgid "Emergency"
msgstr "Vészhelyzet"
-#: src/ui/lockscreen.ui:279
+#: src/ui/lockscreen.ui:296
msgid "Unlock"
msgstr "Feloldás"
-#: src/ui/media-player.ui:107
-msgid "Unknown Song"
-msgstr "Ismeretlen szám"
-
-#: src/ui/media-player.ui:127
-msgid "Unknown Artist"
-msgstr "Ismeretlen előadó"
-
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:89
msgid "_Cancel"
msgstr "_Mégse"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:105
msgid "C_onnect"
msgstr "Kapcs_olódás"
@@ -188,9 +309,24 @@
msgstr "Kilépés"
#: src/ui/top-panel.ui:29
+msgid "Restart"
+msgstr ""
+
+#: src/ui/top-panel.ui:36
msgid "Power Off"
msgstr "Kikapcsolás"
-#: src/wifiinfo.c:88
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:170
+msgid "Cellular"
+msgstr ""
+
+#~ msgid "Unknown artist"
+#~ msgstr "Ismeretlen előadó"
+
+#~ msgid "Unknown Song"
+#~ msgstr "Ismeretlen szám"
diff -Nru phosh-0.8.0/po/id.po phosh-0.13.1/po/id.po
--- phosh-0.8.0/po/id.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/id.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,10 +1,14 @@
-# Andika Triwidada , 2020. #zanata
+# Indonesian translation of phosh
+# Copyright 2020 phosh's copyright holder
+# This file is distributed under the same license as the phosh package.
+# Andika Triwidada , 2020, 2021. #zanata
+#
msgid ""
msgstr ""
-"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-12-12 15:33+0000\n"
-"PO-Revision-Date: 2020-12-14 14:25+0700\n"
+"Project-Id-Version: phosh main\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-28 09:22+0700\n"
"Last-Translator: Andika Triwidada \n"
"Language-Team: Indonesian\n"
"Language: id\n"
@@ -31,7 +35,7 @@
msgid "Application"
msgstr "Aplikasi"
-#: src/bt-info.c:92 src/feedbackinfo.c:51
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Nyala"
@@ -43,10 +47,47 @@
msgid "Docked"
msgstr "Ditambatkan"
-#: src/docked-info.c:195
+#: src/docked-info.c:81 src/docked-info.c:199
msgid "Undocked"
msgstr "Lepas Tambat"
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Keluar"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s akan dikeluarkan secara otomatis dalam %d detik."
+msgstr[1] "%s akan dikeluarkan secara otomatis dalam %d detik."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Matikan Daya"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Sistem akan dimatikan secara otomatis dalam %d detik."
+msgstr[1] "Sistem akan dimatikan secara otomatis dalam %d detik."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Mulai Ulang"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Sistem akan dinyalakan ulang secara otomatis dalam %d detik."
+msgstr[1] "Sistem akan dinyalakan ulang secara otomatis dalam %d detik."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Aplikasi tak dikenal"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
@@ -61,36 +102,68 @@
msgid "Silent"
msgstr "Senyap"
-#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Izinkan '%s' mengakses informasi lokasi Anda?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Geolokasi"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Ya"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Tidak"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
msgstr "Masukkan Kode Sandi"
-#: src/lockscreen.c:265
+#: src/lockscreen.c:335
msgid "Checking…"
msgstr "Memeriksa…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:343
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %d %B"
#. Translators: Used when the title of a song is unknown
-#: src/media-player.c:277 src/ui/media-player.ui:107
+#: src/media-player.c:279 src/ui/media-player.ui:107
msgid "Unknown Title"
msgstr "Judul Tidak Dikenal"
#. Translators: Used when the artist of a song is unknown
-#: src/media-player.c:286 src/ui/media-player.ui:127
+#: src/media-player.c:288 src/ui/media-player.ui:127
msgid "Unknown Artist"
msgstr "Artis Tak Dikenal"
-#: src/monitor-manager.c:71
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Tampilan bawaan"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:75
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Tak dikenal"
@@ -104,129 +177,135 @@
msgid "Enter password for the wifi network “%s”"
msgstr "Masukkan kata sandi untuk jaringan wifi %s"
-#: src/notifications/mount-notification.c:137
+#: src/notifications/mount-notification.c:122
msgid "Open"
msgstr "Buka"
-#: src/notifications/notification.c:381 src/notifications/notification.c:637
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Notifikasi"
#. Translators: Timestamp seconds suffix
-#: src/notifications/timestamp-label.c:83
+#: src/notifications/timestamp-label.c:84
msgctxt "timestamp-suffix-seconds"
msgid "s"
msgstr "d"
#. Translators: Timestamp minute suffix
-#: src/notifications/timestamp-label.c:85
+#: src/notifications/timestamp-label.c:86
msgctxt "timestamp-suffix-minute"
msgid "m"
msgstr "m"
#. Translators: Timestamp minutes suffix
-#: src/notifications/timestamp-label.c:87
+#: src/notifications/timestamp-label.c:88
msgctxt "timestamp-suffix-minutes"
msgid "m"
msgstr "m"
#. Translators: Timestamp hour suffix
-#: src/notifications/timestamp-label.c:89
+#: src/notifications/timestamp-label.c:90
msgctxt "timestamp-suffix-hour"
msgid "h"
msgstr "j"
#. Translators: Timestamp hours suffix
-#: src/notifications/timestamp-label.c:91
+#: src/notifications/timestamp-label.c:92
msgctxt "timestamp-suffix-hours"
msgid "h"
msgstr "j"
#. Translators: Timestamp day suffix
-#: src/notifications/timestamp-label.c:93
+#: src/notifications/timestamp-label.c:94
msgctxt "timestamp-suffix-day"
msgid "d"
msgstr "h"
#. Translators: Timestamp days suffix
-#: src/notifications/timestamp-label.c:95
+#: src/notifications/timestamp-label.c:96
msgctxt "timestamp-suffix-days"
msgid "d"
msgstr "h"
#. Translators: Timestamp month suffix
-#: src/notifications/timestamp-label.c:97
+#: src/notifications/timestamp-label.c:98
msgctxt "timestamp-suffix-month"
msgid "mo"
msgstr "b"
#. Translators: Timestamp months suffix
-#: src/notifications/timestamp-label.c:99
+#: src/notifications/timestamp-label.c:100
msgctxt "timestamp-suffix-months"
msgid "mos"
msgstr "b"
#. Translators: Timestamp year suffix
-#: src/notifications/timestamp-label.c:101
+#: src/notifications/timestamp-label.c:102
msgctxt "timestamp-suffix-year"
msgid "y"
msgstr "t"
#. Translators: Timestamp years suffix
-#: src/notifications/timestamp-label.c:103
+#: src/notifications/timestamp-label.c:104
msgctxt "timestamp-suffix-years"
msgid "y"
msgstr "t"
-#. Translators: this is the date in (short) number only format
-#: src/notifications/timestamp-label.c:106
-msgid "%d.%m.%y"
-msgstr "%d.%m.%y"
-
-#. Translators: Timestamp prefix (e.g. Over 5h)
-#: src/notifications/timestamp-label.c:197
-msgid "Over"
-msgstr "Lewat"
-
-#. Translators: Timestamp prefix (e.g. Almost 5h)
-#: src/notifications/timestamp-label.c:202
-msgid "Almost"
-msgstr "Hampir"
-
-#: src/notifications/timestamp-label.c:210
+#: src/notifications/timestamp-label.c:121
msgid "now"
msgstr "kini"
-#: src/polkit-auth-agent.c:231
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Lebih %dt"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Hampir %dt"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Dialog autentikasi ditutup oleh pengguna"
-#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Kata sandi:"
-#: src/polkit-auth-prompt.c:324
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Maaf, itu tidak bekerja. Harap coba lagi."
-#: src/polkit-auth-prompt.c:490
-msgid "Authenticate"
-msgstr "Autentikasi"
-
-#: src/rotateinfo.c:65
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Potret"
-#: src/rotateinfo.c:68
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Lanskap"
-#: src/system-prompt.c:373
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Mati"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Kata sandi tidak cocok."
-#: src/system-prompt.c:380
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Kata sandi tidak bisa kosong"
@@ -234,6 +313,18 @@
msgid "Torch"
msgstr "Obor"
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Ingat keputusan"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Batal"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "Ok"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "App"
@@ -246,59 +337,79 @@
msgid "Add to _Favorites"
msgstr "Tambah ke _Favorit"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Cari app…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Hanya tampilkan app yang adaptif"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Beberapa aplikasi sibuk atau belum disimpan hasilnya"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Pengguna:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domain:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "S_ambung"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Usap naik untuk membuka kunci"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Darurat"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Buka kunci"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr "Mundur"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Perlu autentikasi"
+
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Batal"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "S_ambung"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Pengguna:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Autentikasi"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Konfirmasi:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Kunci Layar"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Log Keluar"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Mulai Ulang"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Matikan Daya"
-
#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: Refers to the cellular wireless network
-#: src/wwaninfo.c:170
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Seluler"
diff -Nru phosh-0.8.0/po/it.po phosh-0.13.1/po/it.po
--- phosh-0.8.0/po/it.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/it.po 2021-08-31 09:15:52.000000000 +0000
@@ -2,149 +2,411 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the phosh package.
# Ant Pandolfo , 2018.
-# antpanlinux , 2018. #zanata
-# antpanlinux , 2019. #zanata
+# antpanlinux , 2019. #zanata-2021.
+#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-14 13:18+0100\n"
+"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
+"POT-Creation-Date: 2021-07-22 03:33+0000\n"
+"PO-Revision-Date: 2021-07-10 15:47+0200\n"
+"Last-Translator: antpanlinux \n"
+"Language-Team: antpanlinux \n"
+"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2019-10-11 01:32+0000\n"
-"Language-Team: antpanlinux \n"
-"X-Generator: Zanata 4.6.2\n"
-"Last-Translator: antpanlinux \n"
+"X-Generator: Gtranslator 3.30.1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"Language: it\n"
+
+#. Translators: this is the session name, no need to translate it
+#: data/phosh.session.desktop.in.in:4
+msgid "Phosh"
+msgstr "Phosh"
#: data/sm.puri.Phosh.desktop.in.in:4
msgid "Phone Shell"
-msgstr "Shell"
+msgstr "Shell del telefono"
#: data/sm.puri.Phosh.desktop.in.in:5
msgid "Window management and application launching for mobile"
-msgstr "Finestra gestore ed avviatore applicazioni per cellulare"
+msgstr "Gestore di finestre e avviatore di applicazioni per cellulare"
-#. Translators: this is the session name, no need to translate it
-#: data/phosh.session.desktop.in.in:4
-msgid "Phosh"
-msgstr "Phosh"
-
-#: src/app-grid-button.c:523
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Applicazione"
-#: src/feedbackinfo.c:38
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
+msgid "On"
+msgstr "Attivo"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Agganciato"
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr "Sganciato"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Termina sessione"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s verrà disconnesso automaticamente tra %d secondo."
+msgstr[1] "%s verrà disconnesso automaticamente tra %d secondi."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Spegni"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Il sistema si spegnerà automaticamente tra %d secondo."
+msgstr[1] "Il sistema si spegnerà automaticamente tra %d secondi."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Riavvia"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Il sistema verrà riavviato automaticamente tra %d secondo."
+msgstr[1] "Il sistema verrà riavviato automaticamente tra %d secondi."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Applicazione sconosciuta"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:44
msgid "Quiet"
-msgstr ""
+msgstr "Muto"
-#: src/feedbackinfo.c:40
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:49
msgid "Silent"
-msgstr ""
+msgstr "Silenzioso"
-#: src/feedbackinfo.c:42
-msgid "On"
-msgstr ""
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Consenti a '%s' di conoscere la tua posizione?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Posizione"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Sì"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "No"
-#: src/lockscreen.c:78 src/ui/lockscreen.ui:204
+#: src/lockscreen.c:95 src/ui/lockscreen.ui:233
msgid "Enter Passcode"
-msgstr "Inserisci codice"
+msgstr "Inserire la password"
-#: src/lockscreen.c:257
+#: src/lockscreen.c:278
msgid "Checking…"
-msgstr "Sto controllando..."
+msgstr "Sto controllando…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:334
+#: src/lockscreen.c:356
msgid "%A, %B %-e"
msgstr "%A, %B %-e"
-#: src/monitor-manager.c:53
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+msgid "Unknown Title"
+msgstr "Titolo sconosciuto"
+
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
+msgstr "Artista sconosciuto"
+
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Schermo integrato"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:57
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Sconosciuto"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
+#, c-format
+msgid "Authentication type of wifi network “%s” not supported"
+msgstr "Tipo di autenticazione della rete Wi-Fi “%s” non supportato"
+
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
-msgstr ""
+msgstr "Inserire la password per la rete Wi-Fi “%s”"
+
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Apri"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
+msgid "Notification"
+msgstr "Notifica"
+
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "o"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "o"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "g"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "g"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "me"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "mesi"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "a"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "a"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "adesso"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Oltre %da"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Quasi %da"
-#: src/polkit-auth-agent.c:229
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "La finestra di autenticazione è stata chiusa dall'utente"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Password:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
-msgstr "Scusa non ha funzionato.Per favore riprova."
+msgstr "Non ha funzionato. Per favore riprova."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Autenticato"
+#: src/rotateinfo.c:81
+msgid "Portrait"
+msgstr "Verticale"
+
+#: src/rotateinfo.c:84
+msgid "Landscape"
+msgstr "Orizzontale"
+
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Inattivo"
-#: src/system-prompt.c:371
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Le password non corrispondono"
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "La password non può essere vuota"
-#: src/wifiinfo.c:55
-msgid "Wi-Fi"
-msgstr ""
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Torcia"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Ricorda la decisione"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Annulla"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "Ok"
-#: src/ui/app-grid-button.ui:48
+#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "App"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
-msgstr ""
+msgstr "Rimuovi dai _Preferiti"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
-msgstr ""
+msgstr "Aggiungi ai _Preferiti"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
-msgstr "Ricerca app..."
+msgstr "Ricerca app…"
-#: src/ui/lockscreen.ui:36
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Mostra solo le app adattive"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Alcune applicazioni sono occupate o hanno del lavoro non salvato"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Utente:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Dominio:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "Co_nnetti"
+
+#: src/ui/lockscreen.ui:37
msgid "Slide up to unlock"
msgstr "Scorri verso l'alto per sbloccare"
-#: src/ui/lockscreen.ui:250
+#: src/ui/lockscreen.ui:279
msgid "Emergency"
-msgstr ""
+msgstr "Emergenza"
-#: src/ui/lockscreen.ui:266
+#: src/ui/lockscreen.ui:295
msgid "Unlock"
-msgstr ""
+msgstr "Sblocca"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Autenticazione richiesta"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
-msgstr ""
+msgstr "_Annulla"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
-msgstr ""
+msgstr "C_onnetti"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Utente:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Autenticazione"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Conferma:"
+
+#: src/ui/top-panel.ui:16
+msgid "Lock Screen"
+msgstr "Blocca schermo"
+
+#: src/ui/top-panel.ui:23
+msgid "Logout"
+msgstr "Esci"
+
+#: src/wifiinfo.c:90
+msgid "Wi-Fi"
+msgstr "Wi-Fi"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
+msgid "Cellular"
+msgstr "Cellulare"
diff -Nru phosh-0.8.0/po/ja.po phosh-0.13.1/po/ja.po
--- phosh-0.8.0/po/ja.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/ja.po 2021-08-31 09:15:52.000000000 +0000
@@ -41,9 +41,11 @@
msgid "Application"
msgstr "アプリケーション"
+#. Maintainers: while 普通 remains correct in context of normal, manner and silent manner modes,
+#. it doesn't in the context of screen rotation. So I changed it to have it make kind of make sense for both.
#: src/bt-info.c:92 src/feedbackinfo.c:51
msgid "On"
-msgstr "普通"
+msgstr "有効"
#: src/bt-info.c:94
msgid "Bluetooth"
@@ -57,6 +59,28 @@
msgid "Undocked"
msgstr "ドック外"
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "ログアウト"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%2$d秒後、%1$sさんは自動でログアウトされます。"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "%d秒後、この端末は自動でシャットダウンされます。"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "%d秒後、この端末は自動で再起動されます。"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
@@ -71,6 +95,25 @@
msgid "Silent"
msgstr "サイレントマナー"
+#: src/location-manager.c:266
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "'%s'に位置情報へのアクセスを許可しますか?"
+
+#: src/location-manager.c:271
+msgid "Geolocation"
+msgstr "位置情報"
+
+#: src/location-manager.c:252
+#: src/location-manager.c:272
+msgid "Yes"
+msgstr "はい"
+
+#: src/location-manager.c:252
+#: src/location-manager.c:272
+msgid "No"
+msgstr "いいえ"
+
#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
msgid "Enter Passcode"
msgstr "パスコードを入力"
@@ -104,6 +147,11 @@
msgid "Unknown"
msgstr "不明なディスプレー"
+#: src/end-session-dialog.c:270
+#| msgid "Application"
+msgid "Unknown application"
+msgstr "不明なアプリ"
+
#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
@@ -235,6 +283,12 @@
msgid "Landscape"
msgstr "横方向"
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:183
+msgid "Off"
+msgstr "無効"
+
#: src/system-prompt.c:373
msgid "Passwords do not match."
msgstr "パスワードが一致しません。"
@@ -247,6 +301,10 @@
msgid "Torch"
msgstr "懐中電灯"
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "覚える"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "アプリ"
@@ -279,6 +337,19 @@
msgid "_Cancel"
msgstr "キャンセル(_C)"
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "使用中または未保存したデータでございます。"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+#| msgid "Authenticate"
+msgid "Authentication required"
+msgstr "認証必須"
+
+#: src/ui/app-auth-prompt.ui:66 src/ui/end-session-dialog.ui:61
+msgid "Ok"
+msgstr "OK"
+
#: src/ui/network-auth-prompt.ui:105
msgid "C_onnect"
msgstr "接続(_O)"
@@ -315,3 +386,18 @@
#: src/wwaninfo.c:170
msgid "Cellular"
msgstr "モバイル通信"
+
+#: src/monitor-manager.c:130
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:137
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %sn"
+msgstr "%s %sn"
diff -Nru phosh-0.8.0/po/LINGUAS phosh-0.13.1/po/LINGUAS
--- phosh-0.8.0/po/LINGUAS 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/LINGUAS 2021-08-31 09:15:52.000000000 +0000
@@ -16,6 +16,7 @@
fr
fur
he
+ht
hu
id
it
diff -Nru phosh-0.8.0/po/nl.po phosh-0.13.1/po/nl.po
--- phosh-0.8.0/po/nl.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/nl.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,147 +1,397 @@
# Joachim Moernaut , 2018. #zanata
# Joachim Moernaut , 2019. #zanata
# Willem Sonke , 2019. #zanata
+# jjdekroon , 2021.
+# Nathan Follens , 2021.
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-03-14 13:18+0100\n"
+"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
+"POT-Creation-Date: 2021-04-03 15:31+0000\n"
+"PO-Revision-Date: 2021-04-03 19:25+0200\n"
+"Last-Translator: Nathan Follens \n"
+"Language-Team: Dutch\n"
+"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2019-10-02 09:46+0000\n"
-"Last-Translator: Willem Sonke \n"
-"Language-Team: Dutch\n"
-"Language: nl\n"
-"X-Generator: Zanata 4.6.2\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Poedit 2.4.2\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. Translators: this is the session name, no need to translate it
+#: data/phosh.session.desktop.in.in:4
+msgid "Phosh"
+msgstr "Phosh"
#: data/sm.puri.Phosh.desktop.in.in:4
msgid "Phone Shell"
-msgstr "Phone Shell"
+msgstr "Telefoonshell"
#: data/sm.puri.Phosh.desktop.in.in:5
msgid "Window management and application launching for mobile"
msgstr "Vensterbeheer en opstarten van mobiele toepassingen"
-#. Translators: this is the session name, no need to translate it
-#: data/phosh.session.desktop.in.in:4
-msgid "Phosh"
-msgstr "Phosh"
-
-#: src/app-grid-button.c:523
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Toepassing"
-#: src/feedbackinfo.c:38
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
+msgid "On"
+msgstr "Aan"
+
+#: src/bt-info.c:94
+msgid "Bluetooth"
+msgstr "Bluetooth"
+
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "In dock"
+
+#: src/docked-info.c:81 src/docked-info.c:195
+msgid "Undocked"
+msgstr "Uit dock"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Uitloggen"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s wordt automatisch uitgelogd over %d seconde."
+msgstr[1] "%s wordt automatisch uitgelogd over %d seconden."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Uitschakelen"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Het systeem wordt automatisch uitgeschakeld over %d seconde."
+msgstr[1] "Het systeem wordt automatisch uitgeschakeld over %d seconden."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Herstarten"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Het systeem zal automatisch herstarten over %d seconde."
+msgstr[1] "Het systeem zal automatisch herstarten over %d seconden."
+
+#: src/end-session-dialog.c:270
+msgid "Unknown application"
+msgstr "Onbekende applicatie"
+
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:44
msgid "Quiet"
-msgstr ""
+msgstr "Rustig"
-#: src/feedbackinfo.c:40
+#. Translators: quiet and silent are fbd profiles names:
+#. see https://source.puri.sm/Librem5/feedbackd#profiles
+#. for details
+#: src/feedbackinfo.c:49
msgid "Silent"
-msgstr ""
+msgstr "Stil"
-#: src/feedbackinfo.c:42
-msgid "On"
-msgstr ""
+#: src/location-manager.c:246
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "‘%s’ toegang geven tot uw locatiegegevens?"
+
+#: src/location-manager.c:251
+msgid "Geolocation"
+msgstr "Geolocatie"
+
+#: src/location-manager.c:252
+msgid "Yes"
+msgstr "Ja"
+
+#: src/location-manager.c:252
+msgid "No"
+msgstr "Nee"
-#: src/lockscreen.c:78 src/ui/lockscreen.ui:204
+#: src/lockscreen.c:85 src/ui/lockscreen.ui:234
msgid "Enter Passcode"
-msgstr "Pin invoeren"
+msgstr "Voer de pincode in"
-#: src/lockscreen.c:257
+#: src/lockscreen.c:264
msgid "Checking…"
-msgstr ""
+msgstr "Bezig met controleren…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:334
+#: src/lockscreen.c:342
msgid "%A, %B %-e"
msgstr "%A %d %B"
-#: src/monitor-manager.c:53
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:277 src/ui/media-player.ui:107
+msgid "Unknown Title"
+msgstr "Onbekende titel"
+
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:286 src/ui/media-player.ui:127
+msgid "Unknown Artist"
+msgstr "Onbekende artiest"
+
+#: src/monitor-manager.c:112
msgid "Built-in display"
-msgstr "Ingebouwd scherm"
+msgstr "Ingebouwd beeldscherm"
+
+#: src/monitor-manager.c:130
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:137
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %sn"
+msgstr "%s %sn"
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:57
+#: src/monitor-manager.c:146
msgid "Unknown"
msgstr "Onbekend"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
+#, c-format
+msgid "Authentication type of wifi network “%s” not supported"
+msgstr "Authenticatietype van wifinetwerk ‘%s’ wordt niet ondersteund"
+
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
-msgstr ""
+msgstr "Voer het wachtwoord in voor wifinetwerk ‘%s’"
+
+#: src/notifications/mount-notification.c:137
+msgid "Open"
+msgstr "Openen"
+
+#: src/notifications/notification.c:381 src/notifications/notification.c:637
+msgid "Notification"
+msgstr "Notificatie"
+
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "u"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "u"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "mnd"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "mnd"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "j"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "j"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "nu"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Meer dan %dj"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Bijna %dj"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
-#: src/polkit-auth-agent.c:229
+#: src/polkit-auth-agent.c:225
msgid "Authentication dialog was dismissed by the user"
-msgstr "Aanmelddialoog geannuleerd door gebruiker"
+msgstr "Authenticatievenster is door de gebruiker afgesloten"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:85
+#: src/ui/polkit-auth-prompt.ui:57 src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Wachtwoord:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
-msgstr "Aanmelden mislukt. Probeer het nogmaals."
+msgstr "Helaas, dat werkte niet. Probeer het opnieuw."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Aanmelden"
+#: src/rotateinfo.c:81
+msgid "Portrait"
+msgstr "Staand"
+
+#: src/rotateinfo.c:84
+msgid "Landscape"
+msgstr "Liggend"
+
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:183
+msgid "Off"
+msgstr "Uit"
-#: src/system-prompt.c:371
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Wachtwoorden komen niet overeen."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
-msgstr "Wachtwoord mag niet leeg zijn."
+msgstr "Wachtwoord mag niet leeg zijn"
-#: src/wifiinfo.c:55
-msgid "Wi-Fi"
-msgstr ""
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Zaklamp"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Keuze onthouden"
+
+#: src/ui/app-auth-prompt.ui:55 src/ui/end-session-dialog.ui:50
+msgid "Cancel"
+msgstr "Annuleren"
-#: src/ui/app-grid-button.ui:48
+#: src/ui/app-auth-prompt.ui:66 src/ui/end-session-dialog.ui:61
+msgid "Ok"
+msgstr "Oké"
+
+#: src/ui/app-grid-button.ui:49
msgid "App"
-msgstr ""
+msgstr "App"
-#: src/ui/app-grid-button.ui:75
+#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
-msgstr ""
+msgstr "Verwijderen uit _favorieten"
-#: src/ui/app-grid-button.ui:80
+#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
-msgstr ""
+msgstr "Toevoegen aan _favorieten"
#: src/ui/app-grid.ui:21
msgid "Search apps…"
-msgstr ""
+msgstr "Apps zoeken…"
-#: src/ui/lockscreen.ui:36
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Sommige applicaties zijn bezig of hebben niet-opgeslagen werk"
+
+#: src/ui/lockscreen.ui:37
msgid "Slide up to unlock"
msgstr "Veeg omhoog om te ontgrendelen"
-#: src/ui/lockscreen.ui:250
+#: src/ui/lockscreen.ui:280
msgid "Emergency"
-msgstr ""
+msgstr "Noodgeval"
-#: src/ui/lockscreen.ui:266
+#: src/ui/lockscreen.ui:296
msgid "Unlock"
-msgstr ""
+msgstr "Ontgrendelen"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Verificatie vereist"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:42
msgid "_Cancel"
-msgstr ""
+msgstr "_Annuleren"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:61
msgid "C_onnect"
-msgstr ""
+msgstr "_Verbinden"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Gebruikersnaam:"
+#: src/ui/polkit-auth-prompt.ui:125
+msgid "Authenticate"
+msgstr "Aanmelden"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Bevestigen:"
+
+#: src/ui/top-panel.ui:16
+msgid "Lock Screen"
+msgstr "Vergrendelscherm"
+
+#: src/ui/top-panel.ui:23
+msgid "Logout"
+msgstr "Afmelden"
+
+#: src/wifiinfo.c:90
+msgid "Wi-Fi"
+msgstr "Wifi"
+
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
+msgid "Cellular"
+msgstr "Mobiel"
+
+#~ msgid "User:"
+#~ msgstr "Gebruikersnaam:"
diff -Nru phosh-0.8.0/po/POTFILES.in phosh-0.13.1/po/POTFILES.in
--- phosh-0.8.0/po/POTFILES.in 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/POTFILES.in 2021-08-31 09:15:52.000000000 +0000
@@ -11,6 +11,7 @@
src/batteryinfo.c
src/bt-info.c
src/docked-info.c
+src/end-session-dialog.c
src/fader.c
src/favorite-list-model.c
src/feedbackinfo.c
@@ -18,6 +19,7 @@
src/home.c
src/idle-manager.c
src/layersurface.c
+src/location-manager.c
src/lockscreen.c
src/lockscreen-manager.c
src/lockshield.c
@@ -49,8 +51,11 @@
src/toplevel-manager.c
src/torch-info.c
src/ui/activity.ui
+src/ui/app-auth-prompt.ui
src/ui/app-grid-button.ui
src/ui/app-grid.ui
+src/ui/end-session-dialog.ui
+src/ui/gtk-mount-prompt.ui
src/ui/home.ui
src/ui/lockscreen.ui
src/ui/media-player.ui
diff -Nru phosh-0.8.0/po/POTFILES.skip phosh-0.13.1/po/POTFILES.skip
--- phosh-0.8.0/po/POTFILES.skip 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/POTFILES.skip 2021-08-31 09:15:52.000000000 +0000
@@ -1,4 +1,4 @@
src/gtk-list-models/gtkfilterlistmodel.c
src/gtk-list-models/gtksortlistmodel.c
src/settings/gvc-channel-bar.c
-subprojects/gvc/gvc-mixer-control.c
+subprojects/**
diff -Nru phosh-0.8.0/po/pt_BR.po phosh-0.13.1/po/pt_BR.po
--- phosh-0.8.0/po/pt_BR.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/pt_BR.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,23 +1,23 @@
# Brazilian Portuguese translaiton to phosh.
-# Copyright (C) 2020 THE phosh'S COPYRIGHT HOLDER
+# Copyright (C) 2021 THE phosh'S COPYRIGHT HOLDER
# This file is distributed under the same license as the phosh package.
# Luís Fernando Stürmer da Rosa , 2018-2020.
-# Rafael Fontenelle , 2020.
+# Rafael Fontenelle , 2020-2021.
#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-08-01 15:29+0000\n"
-"PO-Revision-Date: 2020-07-30 20:40-0300\n"
-"Last-Translator: Luís Fernando Stürmer da Rosa \n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-06 08:40-0300\n"
+"Last-Translator: Rafael Fontenelle \n"
"Language-Team: Brazilian Portuguese \n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.3.1\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Gtranslator 40.0\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
#. Translators: this is the session name, no need to translate it
#: data/phosh.session.desktop.in.in:4
@@ -32,155 +32,318 @@
msgid "Window management and application launching for mobile"
msgstr "Gerenciador de janelas e lançador de aplicativos para telefone"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Aplicativo"
-#: src/bt-info.c:89 src/feedbackinfo.c:48
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Ligado"
-#: src/bt-info.c:91
+#: src/bt-info.c:94
msgid "Bluetooth"
msgstr "Bluetooth"
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Ancorado"
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr "Desancorado"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Sair"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s será desconectado automaticamente em %d segundo."
+msgstr[1] "%s será desconectado automaticamente em %d segundos."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Desligar"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "O sistema será desligado automaticamente em %d segundo."
+msgstr[1] "O sistema será desligado automaticamente em %d segundos."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Reiniciar"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "O sistema será reiniciado automaticamente em %d segundo."
+msgstr[1] "O sistema será reiniciado automaticamente em %d segundos."
+
+#: src/end-session-dialog.c:269
+#| msgid "Application"
+msgid "Unknown application"
+msgstr "Aplicativo desconhecido"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Quieto"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Silêncio"
-#: src/lockscreen.c:84 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Permitir que “%s” acesse informações da sua localização?"
+
+#: src/location-manager.c:273
+#| msgid "Application"
+msgid "Geolocation"
+msgstr "Localização geográfica"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Sim"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Não"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
msgstr "Insira a senha"
-#: src/lockscreen.c:263
+#: src/lockscreen.c:335
msgid "Checking…"
msgstr "Verificando…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:341
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %d de %B"
-#: src/media-player.c:262
-msgid "Unknown title"
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+#| msgid "Unknown title"
+msgid "Unknown Title"
msgstr "Título desconhecido"
-#: src/media-player.c:270
-msgid "Unknown artist"
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
msgstr "Artista desconhecido"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Tela integrada"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Desconhecido"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
msgstr "Tipo de autenticação da rede wifi “%s” sem suporte"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Insira a senha para a rede wifi “%s”"
-#: src/notifications/notification.c:382 src/notifications/notification.c:601
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Abrir"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Notificação"
-#: src/notifications/timestamp-label.c:83
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+#| msgid "s"
+msgctxt "timestamp-suffix-seconds"
msgid "s"
msgstr "s"
-#: src/notifications/timestamp-label.c:84
-#: src/notifications/timestamp-label.c:85
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+#| msgid "m"
+msgctxt "timestamp-suffix-minute"
msgid "m"
msgstr "m"
-#: src/notifications/timestamp-label.c:86
-#: src/notifications/timestamp-label.c:87
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+#| msgid "m"
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+#| msgid "h"
+msgctxt "timestamp-suffix-hour"
msgid "h"
msgstr "h"
-#: src/notifications/timestamp-label.c:88
-#: src/notifications/timestamp-label.c:89
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+#| msgid "h"
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "h"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+#| msgid "d"
+msgctxt "timestamp-suffix-day"
msgid "d"
msgstr "d"
-#: src/notifications/timestamp-label.c:90
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+#| msgid "d"
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "d"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+#| msgid "mo"
+msgctxt "timestamp-suffix-month"
msgid "mo"
msgstr "m"
-#: src/notifications/timestamp-label.c:91
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+#| msgid "mos"
+msgctxt "timestamp-suffix-months"
msgid "mos"
-msgstr "ms"
+msgstr "m"
-#: src/notifications/timestamp-label.c:92
-#: src/notifications/timestamp-label.c:93
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+#| msgid "y"
+msgctxt "timestamp-suffix-year"
msgid "y"
msgstr "a"
-#. Translators: this is the date in number only format
-#: src/notifications/timestamp-label.c:96
-msgid "%d.%m.%y"
-msgstr "%d.%m.%y"
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+#| msgid "y"
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "a"
+
+#: src/notifications/timestamp-label.c:121
+#| msgid "Unknown"
+msgid "now"
+msgstr "agora"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+#| msgid "Over"
+msgid "Over %dy"
+msgstr "Mais de %dy"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+#| msgid "Almost"
+msgid "Almost %dy"
+msgstr "Quase %dy"
-#: src/notifications/timestamp-label.c:186
-msgid "Over"
-msgstr "Mais de"
-
-#: src/notifications/timestamp-label.c:190
-msgid "Almost"
-msgstr "Quase"
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
-#: src/polkit-auth-agent.c:229
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Diálogo de autenticação dispensado pelo usuário"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Senha:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Ops! Não deu! Tente novamente."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Autenticar"
-
-#: src/rotateinfo.c:46
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Retrato"
-#: src/rotateinfo.c:49
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Paisagem"
-#: src/system-prompt.c:371
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Desligada"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "As senhas não conferem."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "A senha não pode ficar em branco"
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Tocha"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Lembrar da decisão"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+#| msgid "_Cancel"
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "Ok"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Aplicativo"
@@ -193,69 +356,93 @@
msgid "Add to _Favorites"
msgstr "Adicionar aos _favoritos"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Procurar aplicativos…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Mostrar apenas aplicativos adaptativos"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Alguns aplicativos estão ocupados ou possuem trabalhos não salvos"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Usuário:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domínio:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+#| msgid "C_onnect"
+msgid "Co_nnect"
+msgstr "C_onectar"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Deslize para desbloquear"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Emergência"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Desbloquear"
-#: src/ui/media-player.ui:107
-msgid "Unknown Song"
-msgstr "Música desconhecida"
-
-#: src/ui/media-player.ui:127
-msgid "Unknown Artist"
-msgstr "Artista desconhecido"
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr "Voltar"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+#| msgid "Authenticate"
+msgid "Authentication required"
+msgstr "Autenticação necessária"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Cancelar"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "C_onectar"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Usuário:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Autenticar"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Confirmar:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Tela de bloqueio"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Encerrar sessão"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Reiniciar"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Desligar"
-
-#: src/wifiinfo.c:88
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
-#: src/wwaninfo.c:167
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Celular"
+#~ msgid "Unknown artist"
+#~ msgstr "Artista desconhecido"
+
+#~ msgid "%d.%m.%y"
+#~ msgstr "%d.%m.%y"
+
+#~ msgid "Unknown Song"
+#~ msgstr "Música desconhecida"
+
#~ msgid "Suspend"
#~ msgstr "Suspender"
diff -Nru phosh-0.8.0/po/ro.po phosh-0.13.1/po/ro.po
--- phosh-0.8.0/po/ro.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/ro.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,23 +1,24 @@
# Romanian translation for phosh.
# Copyright (C) 2020 phosh's COPYRIGHT HOLDER
# This file is distributed under the same license as the phosh package.
-# Florentina Mușat , 2020.
+# Florentina Mușat , 2020-2021.
#
msgid ""
msgstr ""
"Project-Id-Version: phosh master\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-07-18 03:30+0000\n"
-"PO-Revision-Date: 2020-07-18 16:59+0300\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-13 17:48+0200\n"
"Last-Translator: Florentina Mușat \n"
"Language-Team: Romanian \n"
"Language: ro\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
-"20)) ? 1 : 2);;\n"
-"X-Generator: Poedit 2.3.1\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && n"
+"%100<=19) ? 1 : 2);\n"
+"X-Generator: Gtranslator 3.30.1\n"
+"X-Poedit-SourceCharset: UTF-8\n"
#. Translators: this is the session name, no need to translate it
#: data/phosh.session.desktop.in.in:4
@@ -30,183 +31,391 @@
#: data/sm.puri.Phosh.desktop.in.in:5
msgid "Window management and application launching for mobile"
-msgstr "Administrare de fereastră și lansare de aplicație pentru mobil"
+msgstr "Gestionarea ferestrei și pornirea aplicațiilor pentru mobil"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Aplicație"
-#: src/bt-info.c:89 src/feedbackinfo.c:48
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Pornit"
-#: src/bt-info.c:91
+#: src/bt-info.c:94
msgid "Bluetooth"
msgstr "Bluetooth"
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Cuplat"
+
+#: src/docked-info.c:81 src/docked-info.c:199
+msgid "Undocked"
+msgstr "Decuplat"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Deconectare"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s se va deconecta automat în %d secundă."
+msgstr[1] "%s se va deconecta automat în %d secunde."
+msgstr[2] "%s se va deconecta automat în %d de secunde."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Oprește"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Sistemul se va opri automat în %d secundă."
+msgstr[1] "Sistemul se va opri automat în %d secunde."
+msgstr[2] "Sistemul se va opri automat în %d de secunde."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Repornește"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Sistemul va reporni automat în %d secundă."
+msgstr[1] "Sistemul va reporni automat în %d secunde."
+msgstr[2] "Sistemul va reporni automat în %d de secunde."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Aplicație necunoscută"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
-msgstr "Încet"
+msgstr "Liniștit"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Silențios"
-#: src/lockscreen.c:84 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "„%s” poate accesa poziția ta geografică?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Poziția geografică"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Da"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Nu"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
-msgstr "Introduceți parola"
+msgstr "Introdu codul de acces"
-#: src/lockscreen.c:263
+#: src/lockscreen.c:335
msgid "Checking…"
msgstr "Se verifică…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:341
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %B %-e"
-#: src/media-player.c:262
-msgid "Unknown title"
+#. Translators: Used when the title of a song is unknown
+#: src/media-player.c:279 src/ui/media-player.ui:107
+msgid "Unknown Title"
msgstr "Titlu necunoscut"
-#: src/media-player.c:270
-msgid "Unknown artist"
+#. Translators: Used when the artist of a song is unknown
+#: src/media-player.c:288 src/ui/media-player.ui:127
+msgid "Unknown Artist"
msgstr "Artist necunoscut"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:114
msgid "Built-in display"
-msgstr "Afișaj integrat"
+msgstr "Ecran integrat"
+
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Necunoscut"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
-msgstr "Tipul de autentificare de rețea de wifi „%s” nu este suportat"
+msgstr "Tipul de autentificare pentru rețeaua Wi-Fi „%s” nu este acceptat"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
-msgstr "Introduceți parola pentru rețeaua de wifi „%s”"
+msgstr "Introdu parola pentru rețeaua Wi-Fi „%s”"
+
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Deschide"
-#: src/notifications/notification.c:365 src/notifications/notification.c:581
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Notificare"
-#: src/polkit-auth-agent.c:229
+#. Translators: Timestamp seconds suffix
+#: src/notifications/timestamp-label.c:84
+msgctxt "timestamp-suffix-seconds"
+msgid "s"
+msgstr "s"
+
+#. Translators: Timestamp minute suffix
+#: src/notifications/timestamp-label.c:86
+msgctxt "timestamp-suffix-minute"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp minutes suffix
+#: src/notifications/timestamp-label.c:88
+msgctxt "timestamp-suffix-minutes"
+msgid "m"
+msgstr "m"
+
+#. Translators: Timestamp hour suffix
+#: src/notifications/timestamp-label.c:90
+msgctxt "timestamp-suffix-hour"
+msgid "h"
+msgstr "o"
+
+#. Translators: Timestamp hours suffix
+#: src/notifications/timestamp-label.c:92
+msgctxt "timestamp-suffix-hours"
+msgid "h"
+msgstr "o"
+
+#. Translators: Timestamp day suffix
+#: src/notifications/timestamp-label.c:94
+msgctxt "timestamp-suffix-day"
+msgid "d"
+msgstr "z"
+
+#. Translators: Timestamp days suffix
+#: src/notifications/timestamp-label.c:96
+msgctxt "timestamp-suffix-days"
+msgid "d"
+msgstr "z"
+
+#. Translators: Timestamp month suffix
+#: src/notifications/timestamp-label.c:98
+msgctxt "timestamp-suffix-month"
+msgid "mo"
+msgstr "lu"
+
+#. Translators: Timestamp months suffix
+#: src/notifications/timestamp-label.c:100
+msgctxt "timestamp-suffix-months"
+msgid "mos"
+msgstr "luni"
+
+#. Translators: Timestamp year suffix
+#: src/notifications/timestamp-label.c:102
+msgctxt "timestamp-suffix-year"
+msgid "y"
+msgstr "a"
+
+#. Translators: Timestamp years suffix
+#: src/notifications/timestamp-label.c:104
+msgctxt "timestamp-suffix-years"
+msgid "y"
+msgstr "a"
+
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "acum"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Peste %da"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Aproape %da"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
-msgstr "Fereastra de autentificare a fost închisă de către utilizator"
+msgstr "Fereastra de autentificare a fost închisă de utilizator"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
-msgstr "Parolă:"
+msgstr "Parola:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
-msgstr "Nu a funcționat. Încercați din nou."
-
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Autentificare"
+msgstr "Nu a funcționat. Încearcă din nou."
-#: src/rotateinfo.c:46
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Portret"
-#: src/rotateinfo.c:49
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Peisaj"
-#: src/system-prompt.c:371
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Oprit"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Parolele nu se potrivesc."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Parola nu poate fi goală"
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Lanternă"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Memorează decizia"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Anulează"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "De acord"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Aplicație"
#: src/ui/app-grid-button.ui:76
msgid "Remove from _Favorites"
-msgstr "Elimină din _favorite"
+msgstr "Elimină din _Favorite"
#: src/ui/app-grid-button.ui:81
msgid "Add to _Favorites"
-msgstr "Adaugă la _favorite"
+msgstr "Adaugă la _Favorite"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Caută aplicații…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Arată doar aplicații adaptabile"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Unele aplicații sunt ocupate sau au lucrări nesalvate"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Utilizator:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domeniu:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+#| msgid "C_onnect"
+msgid "Co_nnect"
+msgstr "Co_nectează"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
-msgstr "Glisează în sus pentru a debloca"
+msgstr "Trage în sus pentru a debloca"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Urgență"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Deblocare"
-#: src/ui/media-player.ui:107
-msgid "Unknown Song"
-msgstr "Cântec necunoscut"
-
-#: src/ui/media-player.ui:127
-msgid "Unknown Artist"
-msgstr "Artist necunoscut"
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr "Înapoi"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Autentificare necesară"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Anulează"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "C_onectează"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Utilizator:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Autentificare"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Confirmă:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
-msgstr "Ecran de blocare"
+msgstr "Blochează ecranul"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
-msgstr "Deautentificare"
+msgstr "Deconectare"
-#: src/ui/top-panel.ui:29
-msgid "Power Off"
-msgstr "Oprire"
-
-#: src/wifiinfo.c:88
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
-#: src/wwaninfo.c:167
+#. Translators: Refers to the cellular wireless network
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Celular"
-
-#~ msgid "Suspend"
-#~ msgstr "Suspendă"
diff -Nru phosh-0.8.0/po/sr.po phosh-0.13.1/po/sr.po
--- phosh-0.8.0/po/sr.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/sr.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,33 +1,32 @@
# Serbian translation for phosh.
-# Copyright (C) 2020 phosh's COPYRIGHT HOLDER
+# Copyright ©2020 phosh's COPYRIGHT HOLDER
# This file is distributed under the same license as the phosh package.
# nikp123 , 2020.
# Марко М. Костић , 2020.
-#
+# Мирослав Николић , 2021.
msgid ""
msgstr ""
"Project-Id-Version: phosh master\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-10-29 15:33+0000\n"
-"PO-Revision-Date: 2020-10-30 02:03+0100\n"
-"Last-Translator: Марко М. Костић \n"
-"Language-Team: Serbian \n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-08 07:02+0200\n"
+"Last-Translator: Мирослав Николић \n"
+"Language-Team: Serbian <(nothing)>\n"
"Language: sr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
-"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Poedit 2.4.1\n"
+"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : "
+"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#. Translators: this is the session name, no need to translate it
#: data/phosh.session.desktop.in.in:4
msgid "Phosh"
-msgstr "Phosh"
+msgstr "Теш"
#: data/sm.puri.Phosh.desktop.in.in:4
msgid "Phone Shell"
-msgstr "Мобилна шкољка"
+msgstr "Телефонска шкољка"
#: data/sm.puri.Phosh.desktop.in.in:5
msgid "Window management and application launching for mobile"
@@ -37,7 +36,7 @@
msgid "Application"
msgstr "Апликација"
-#: src/bt-info.c:92 src/feedbackinfo.c:51
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Укљ."
@@ -49,10 +48,54 @@
msgid "Docked"
msgstr "Усидрен"
-#: src/docked-info.c:195
+#: src/docked-info.c:81 src/docked-info.c:199
msgid "Undocked"
msgstr "Одсидрен"
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Одјави ме"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "„%s“ ће бити одјављен за %d секунду."
+msgstr[1] "„%s“ ће бити одјављен за %d секунде."
+msgstr[2] "„%s“ ће бити одјављен за %d секунди."
+msgstr[3] "„%s“ ће бити одјављен за једну секунду."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Искључивање"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Рачунар ће се искључити за %d секунду."
+msgstr[1] "Рачунар ће се искључити за %d секунде."
+msgstr[2] "Рачунар ће се искључити за %d секунди."
+msgstr[3] "Рачунар ће се искључити за једну секунду."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Поново покрени"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Систем ће се поново покренути за %d секунду."
+msgstr[1] "Систем ће се поново покренути за %d секунде."
+msgstr[2] "Систем ће се поново покренути за %d секунди."
+msgstr[3] "Систем ће се поново покренути за једну секунду."
+
+#: src/end-session-dialog.c:269
+#| msgid "Application"
+msgid "Unknown application"
+msgstr "Непознат програм"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
@@ -67,164 +110,214 @@
msgid "Silent"
msgstr "Утишано"
-#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Да дозволим да „%s“ приступи вашим подацима о месту?"
+
+#: src/location-manager.c:273
+#| msgid "Application"
+msgid "Geolocation"
+msgstr "Геолокација"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Да"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Не"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
msgstr "Унеси код"
-#: src/lockscreen.c:265
+#: src/lockscreen.c:335
msgid "Checking…"
msgstr "Проверавам…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:343
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %d. %B"
#. Translators: Used when the title of a song is unknown
-#: src/media-player.c:277 src/ui/media-player.ui:107
+#: src/media-player.c:279 src/ui/media-player.ui:107
msgid "Unknown Title"
msgstr "Непознат наслов"
#. Translators: Used when the artist of a song is unknown
-#: src/media-player.c:286 src/ui/media-player.ui:127
+#: src/media-player.c:288 src/ui/media-player.ui:127
msgid "Unknown Artist"
msgstr "Непознат извођач"
-#: src/monitor-manager.c:71
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Уграђени екран"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:75
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Непознато"
-#: src/network-auth-prompt.c:186
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
msgstr "Тип пријављивања на бежичној мрежи „%s“ није подржан"
-#: src/network-auth-prompt.c:191
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "Унесите лозинку бежичне мреже „%s“"
-#: src/notifications/notification.c:382 src/notifications/notification.c:601
+#: src/notifications/mount-notification.c:122
+msgid "Open"
+msgstr "Отвори"
+
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Обавештење"
#. Translators: Timestamp seconds suffix
-#: src/notifications/timestamp-label.c:83
+#: src/notifications/timestamp-label.c:84
msgctxt "timestamp-suffix-seconds"
msgid "s"
msgstr "с"
#. Translators: Timestamp minute suffix
-#: src/notifications/timestamp-label.c:85
+#: src/notifications/timestamp-label.c:86
msgctxt "timestamp-suffix-minute"
msgid "m"
msgstr "м"
#. Translators: Timestamp minutes suffix
-#: src/notifications/timestamp-label.c:87
+#: src/notifications/timestamp-label.c:88
msgctxt "timestamp-suffix-minutes"
msgid "m"
msgstr "м"
#. Translators: Timestamp hour suffix
-#: src/notifications/timestamp-label.c:89
+#: src/notifications/timestamp-label.c:90
msgctxt "timestamp-suffix-hour"
msgid "h"
msgstr "ч"
#. Translators: Timestamp hours suffix
-#: src/notifications/timestamp-label.c:91
+#: src/notifications/timestamp-label.c:92
msgctxt "timestamp-suffix-hours"
msgid "h"
msgstr "ч"
#. Translators: Timestamp day suffix
-#: src/notifications/timestamp-label.c:93
+#: src/notifications/timestamp-label.c:94
msgctxt "timestamp-suffix-day"
msgid "d"
msgstr "д"
#. Translators: Timestamp days suffix
-#: src/notifications/timestamp-label.c:95
+#: src/notifications/timestamp-label.c:96
msgctxt "timestamp-suffix-days"
msgid "d"
msgstr "д"
#. Translators: Timestamp month suffix
-#: src/notifications/timestamp-label.c:97
+#: src/notifications/timestamp-label.c:98
msgctxt "timestamp-suffix-month"
msgid "mo"
msgstr "мес."
#. Translators: Timestamp months suffix
-#: src/notifications/timestamp-label.c:99
+#: src/notifications/timestamp-label.c:100
msgctxt "timestamp-suffix-months"
msgid "mos"
msgstr "мес."
#. Translators: Timestamp year suffix
-#: src/notifications/timestamp-label.c:101
+#: src/notifications/timestamp-label.c:102
msgctxt "timestamp-suffix-year"
msgid "y"
msgstr "г"
#. Translators: Timestamp years suffix
-#: src/notifications/timestamp-label.c:103
+#: src/notifications/timestamp-label.c:104
msgctxt "timestamp-suffix-years"
msgid "y"
msgstr "г"
-#. Translators: this is the date in (short) number only format
-#: src/notifications/timestamp-label.c:106
-msgid "%d.%m.%y"
-msgstr "%d.%m.%y"
-
-#. Translators: Timestamp prefix (e.g. Over 5h)
-#: src/notifications/timestamp-label.c:197
-msgid "Over"
-msgstr "Више од"
-
-#. Translators: Timestamp prefix (e.g. Almost 5h)
-#: src/notifications/timestamp-label.c:202
-msgid "Almost"
-msgstr "Скоро "
+#: src/notifications/timestamp-label.c:121
+#| msgid "Unknown"
+msgid "now"
+msgstr "сада"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+#| msgid "Over"
+msgid "Over %dy"
+msgstr "Преко %dг"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+#| msgid "Almost"
+msgid "Almost %dy"
+msgstr "Скоро %dг"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
-#: src/polkit-auth-agent.c:231
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Корисник је одбацио прозорче за потврђивање идентитета"
-#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Лозинка:"
-#: src/polkit-auth-prompt.c:324
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Нетачно. Покушајте поново."
-#: src/polkit-auth-prompt.c:490
-msgid "Authenticate"
-msgstr "Потврди идентитет"
-
-#: src/rotateinfo.c:65
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Усправно"
-#: src/rotateinfo.c:68
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Положено"
-#: src/system-prompt.c:373
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Искљ."
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Лозинке се не подударају."
-#: src/system-prompt.c:380
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Лозинка не може бити празна"
@@ -232,6 +325,19 @@
msgid "Torch"
msgstr "Бакља"
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Упамти одлуку"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+#| msgid "_Cancel"
+msgid "Cancel"
+msgstr "Откажи"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "У реду"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Програм"
@@ -244,62 +350,87 @@
msgid "Add to _Favorites"
msgstr "Додај у о_миљено"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Претражи апликације…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Прикажи само прилагодљиве програме"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Неки програми су заузети или имају несачувани рад"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Корисник:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Домен:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+#| msgid "C_onnect"
+msgid "Co_nnect"
+msgstr "П_овежи се"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Превуци нагоре за откључавање"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Хитни позив"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Откључај"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr "Назад"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+#| msgid "Authenticate"
+msgid "Authentication required"
+msgstr "Потребно је потврђивање идентитета"
+
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Откажи"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "П_овежи се"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Корисник:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Потврди идентитет"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Потврди:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Закључавање екрана"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Одјава"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Поново покрени"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Искључивање"
-
#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Бежична"
#. Translators: Refers to the cellular wireless network
-#: src/wwaninfo.c:170
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Мобилна"
+#~ msgid "%d.%m.%y"
+#~ msgstr "%d.%m.%y"
+
#~ msgid "Suspend"
#~ msgstr "Обустави"
diff -Nru phosh-0.8.0/po/sv.po phosh-0.13.1/po/sv.po
--- phosh-0.8.0/po/sv.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/sv.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,13 +1,14 @@
# Ludwig Johnson , 2018. #zanata
# Nami , 2019. #zanata
-# Anders Jonsson , 2020.
+# Anders Jonsson , 2020, 2021.
+# Luna Jernberg , 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-12-24 15:33+0000\n"
-"PO-Revision-Date: 2020-12-25 00:01+0100\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-03 16:29+0200\n"
"Last-Translator: Anders Jonsson \n"
"Language-Team: Swedish \n"
"Language: sv\n"
@@ -34,7 +35,7 @@
msgid "Application"
msgstr "Program"
-#: src/bt-info.c:92 src/feedbackinfo.c:51
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "På"
@@ -46,10 +47,47 @@
msgid "Docked"
msgstr "Dockad"
-#: src/docked-info.c:195
+#: src/docked-info.c:81 src/docked-info.c:199
msgid "Undocked"
msgstr "Ej dockad"
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Logga ut"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s kommer att loggas ut automatiskt om %d sekund."
+msgstr[1] "%s kommer att loggas ut automatiskt om %d sekunder."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Stäng av"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Systemet kommer att stängas av automatiskt om %d sekund."
+msgstr[1] "Systemet kommer att stängas av automatiskt om %d sekunder."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Starta om"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Systemet kommer att startas om automatiskt om %d sekund."
+msgstr[1] "Systemet kommer att startas om automatiskt om %d sekunder."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Okänt program"
+
# Inget ljud, möjligen vibration
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
@@ -65,36 +103,68 @@
msgid "Silent"
msgstr "Tyst"
-#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Ge ”%s” tillgång till din platsinformation?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Platsbestämning"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Ja"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Nej"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
msgstr "Ange lösenord"
-#: src/lockscreen.c:265
+#: src/lockscreen.c:335
msgid "Checking…"
msgstr "Kontrollerar…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:343
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %-e %B"
#. Translators: Used when the title of a song is unknown
-#: src/media-player.c:277 src/ui/media-player.ui:107
+#: src/media-player.c:279 src/ui/media-player.ui:107
msgid "Unknown Title"
msgstr "Okänd titel"
#. Translators: Used when the artist of a song is unknown
-#: src/media-player.c:286 src/ui/media-player.ui:127
+#: src/media-player.c:288 src/ui/media-player.ui:127
msgid "Unknown Artist"
msgstr "Okänd artist"
-#: src/monitor-manager.c:71
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Inbyggd skärm"
+#: src/monitor-manager.c:132
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:139
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %s"
+msgstr "%s %s"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:75
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Okänd"
@@ -108,129 +178,135 @@
msgid "Enter password for the wifi network “%s”"
msgstr "Ange lösenord för wifi-nätverket ”%s”"
-#: src/notifications/mount-notification.c:137
+#: src/notifications/mount-notification.c:122
msgid "Open"
msgstr "Öppna"
-#: src/notifications/notification.c:381 src/notifications/notification.c:637
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Avisering"
#. Translators: Timestamp seconds suffix
-#: src/notifications/timestamp-label.c:83
+#: src/notifications/timestamp-label.c:84
msgctxt "timestamp-suffix-seconds"
msgid "s"
msgstr "s"
#. Translators: Timestamp minute suffix
-#: src/notifications/timestamp-label.c:85
+#: src/notifications/timestamp-label.c:86
msgctxt "timestamp-suffix-minute"
msgid "m"
msgstr "m"
#. Translators: Timestamp minutes suffix
-#: src/notifications/timestamp-label.c:87
+#: src/notifications/timestamp-label.c:88
msgctxt "timestamp-suffix-minutes"
msgid "m"
msgstr "m"
#. Translators: Timestamp hour suffix
-#: src/notifications/timestamp-label.c:89
+#: src/notifications/timestamp-label.c:90
msgctxt "timestamp-suffix-hour"
msgid "h"
msgstr "h"
#. Translators: Timestamp hours suffix
-#: src/notifications/timestamp-label.c:91
+#: src/notifications/timestamp-label.c:92
msgctxt "timestamp-suffix-hours"
msgid "h"
msgstr "h"
#. Translators: Timestamp day suffix
-#: src/notifications/timestamp-label.c:93
+#: src/notifications/timestamp-label.c:94
msgctxt "timestamp-suffix-day"
msgid "d"
msgstr "d"
#. Translators: Timestamp days suffix
-#: src/notifications/timestamp-label.c:95
+#: src/notifications/timestamp-label.c:96
msgctxt "timestamp-suffix-days"
msgid "d"
msgstr "d"
#. Translators: Timestamp month suffix
-#: src/notifications/timestamp-label.c:97
+#: src/notifications/timestamp-label.c:98
msgctxt "timestamp-suffix-month"
msgid "mo"
msgstr "mån"
#. Translators: Timestamp months suffix
-#: src/notifications/timestamp-label.c:99
+#: src/notifications/timestamp-label.c:100
msgctxt "timestamp-suffix-months"
msgid "mos"
msgstr "mån"
#. Translators: Timestamp year suffix
-#: src/notifications/timestamp-label.c:101
+#: src/notifications/timestamp-label.c:102
msgctxt "timestamp-suffix-year"
msgid "y"
msgstr "å"
#. Translators: Timestamp years suffix
-#: src/notifications/timestamp-label.c:103
+#: src/notifications/timestamp-label.c:104
msgctxt "timestamp-suffix-years"
msgid "y"
msgstr "å"
-#. Translators: this is the date in (short) number only format
-#: src/notifications/timestamp-label.c:106
-msgid "%d.%m.%y"
-msgstr "%y.%m.%d"
-
-#. Translators: Timestamp prefix (e.g. Over 5h)
-#: src/notifications/timestamp-label.c:197
-msgid "Over"
-msgstr "Över"
-
-#. Translators: Timestamp prefix (e.g. Almost 5h)
-#: src/notifications/timestamp-label.c:202
-msgid "Almost"
-msgstr "Nästan"
-
-#: src/notifications/timestamp-label.c:210
+#: src/notifications/timestamp-label.c:121
msgid "now"
msgstr "nu"
-#: src/polkit-auth-agent.c:231
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "Över %då"
+
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Nästan %då"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Autentiseringsdialogen avvisades av användaren"
-#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:130
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Lösenord:"
-#: src/polkit-auth-prompt.c:324
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Tyvärr, det fungerade inte. Var god försök igen."
-#: src/polkit-auth-prompt.c:468
-msgid "Authenticate"
-msgstr "Godkänn"
-
-#: src/rotateinfo.c:65
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Stående"
-#: src/rotateinfo.c:68
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Liggande"
-#: src/system-prompt.c:373
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "Av"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Lösenorden matchar inte."
-#: src/system-prompt.c:380
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Lösenordet får inte vara tomt"
@@ -238,6 +314,18 @@
msgid "Torch"
msgstr "Ficklampa"
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Kom ihåg beslut"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Avbryt"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "OK"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "App"
@@ -250,59 +338,79 @@
msgid "Add to _Favorites"
msgstr "Lägg till i _favoriter"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Sök appar…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Visa endast adaptiva appar"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Några program är upptagna eller innehåller icke sparat arbete"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Användare:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Domän:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "A_nslut"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Svep uppåt för att låsa upp"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Nödläge"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Lås upp"
-#: src/ui/network-auth-prompt.ui:89
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr "Bakåt"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Autentisering krävs"
+
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "A_vbryt"
-#: src/ui/network-auth-prompt.ui:105
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "A_nslut"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Användare:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Godkänn"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Bekräfta:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Lås skärm"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Logga ut"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Starta om"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Stäng av"
-
#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: Refers to the cellular wireless network
-#: src/wwaninfo.c:170
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Mobilt nätverk"
diff -Nru phosh-0.8.0/po/tr.po phosh-0.13.1/po/tr.po
--- phosh-0.8.0/po/tr.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/tr.po 2021-08-31 09:15:52.000000000 +0000
@@ -1,12 +1,12 @@
# Turkish translation of phosh.
-# Emin Tufan Çetin , 2019-2020.
+# Emin Tufan Çetin , 2019, 2020, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2020-08-14 15:29+0000\n"
-"PO-Revision-Date: 2020-09-29 14:55+0300\n"
+"POT-Creation-Date: 2021-04-01 03:31+0000\n"
+"PO-Revision-Date: 2021-04-05 12:35+0300\n"
"Last-Translator: Emin Tufan Çetin \n"
"Language-Team: Turkish \n"
"Language: tr\n"
@@ -29,76 +29,154 @@
msgid "Window management and application launching for mobile"
msgstr "Mobil için pencere yönetimi ve uygulama başlatımı"
-#: src/app-grid-button.c:530
+#: src/app-grid-button.c:536
msgid "Application"
msgstr "Uygulama"
-#: src/bt-info.c:89 src/feedbackinfo.c:48
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
msgstr "Açık"
-#: src/bt-info.c:91
+#: src/bt-info.c:94
msgid "Bluetooth"
msgstr "Bluetooth"
+#: src/docked-info.c:81
+msgid "Docked"
+msgstr "Yuvada"
+
+#: src/docked-info.c:81 src/docked-info.c:195
+msgid "Undocked"
+msgstr "Yuvada Değil"
+
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Oturumu Kapat"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "%s oturumu %d saniye içinde kendiliğinden kapatılacak."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Gücü Kapat"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Sistem %d saniye içinde kendiliğinden kapanacak."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Yeniden Başlat"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Sistem %d saniye içinde kendiliğinden yeniden başlayacak."
+
+#: src/end-session-dialog.c:270
+msgid "Unknown application"
+msgstr "Bilinmeyen uygulama"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:41
+#: src/feedbackinfo.c:44
msgid "Quiet"
msgstr "Titreşim"
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
-#: src/feedbackinfo.c:46
+#: src/feedbackinfo.c:49
msgid "Silent"
msgstr "Sessiz"
-#: src/lockscreen.c:84 src/ui/lockscreen.ui:234
+#: src/location-manager.c:246
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "'%s' konum bilginize erişebilsin mi?"
+
+#: src/location-manager.c:251
+msgid "Geolocation"
+msgstr "Coğrafi Konum"
+
+#: src/location-manager.c:252
+msgid "Yes"
+msgstr "Evet"
+
+#: src/location-manager.c:252
+msgid "No"
+msgstr "Hayır"
+
+#: src/lockscreen.c:85 src/ui/lockscreen.ui:234
msgid "Enter Passcode"
msgstr "Parolayı Gir"
-#: src/lockscreen.c:263
+#: src/lockscreen.c:264
msgid "Checking…"
msgstr "Denetleniyor…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:341
+#: src/lockscreen.c:342
msgid "%A, %B %-e"
msgstr "%A, %B %-e"
#. Translators: Used when the title of a song is unknown
-#: src/media-player.c:263 src/ui/media-player.ui:107
+#: src/media-player.c:277 src/ui/media-player.ui:107
msgid "Unknown Title"
msgstr "Bilinmeyen Başlık"
#. Translators: Used when the artist of a song is unknown
-#: src/media-player.c:272 src/ui/media-player.ui:127
+#: src/media-player.c:286 src/ui/media-player.ui:127
msgid "Unknown Artist"
msgstr "Bilinmeyen Sanatçı"
-#: src/monitor-manager.c:58
+#: src/monitor-manager.c:112
msgid "Built-in display"
msgstr "İç ekran"
+#: src/monitor-manager.c:130
+#, c-format
+msgctxt ""
+"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgid "%s %s"
+msgstr "%s %s"
+
+#: src/monitor-manager.c:137
+#, c-format
+msgctxt ""
+"This is a monitor vendor name followed by product/model name where size in "
+"inches could not be calculated, e.g. Dell U2414H"
+msgid "%s %sn"
+msgstr "%s %sn"
+
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:62
+#: src/monitor-manager.c:146
msgid "Unknown"
msgstr "Bilinmeyen"
-#: src/network-auth-prompt.c:184
+#: src/network-auth-prompt.c:187
#, c-format
msgid "Authentication type of wifi network “%s” not supported"
msgstr "“%s” wifi ağının yetkilendirme türü desteklenmiyor"
-#: src/network-auth-prompt.c:189
+#: src/network-auth-prompt.c:192
#, c-format
msgid "Enter password for the wifi network “%s”"
msgstr "“%s” wifi ağı için parola gir"
-#: src/notifications/notification.c:382 src/notifications/notification.c:601
+#: src/notifications/mount-notification.c:137
+msgid "Open"
+msgstr "Aç"
+
+#: src/notifications/notification.c:381 src/notifications/notification.c:637
msgid "Notification"
msgstr "Bildirim"
@@ -168,54 +246,79 @@
msgid "y"
msgstr "y"
-#. Translators: this is the date in (short) number only format
-#: src/notifications/timestamp-label.c:107
-msgid "%d.%m.%y"
-msgstr "%d.%m.%y"
-
-#. Translators: Timestamp prefix (e.g. Over 5h)
-#: src/notifications/timestamp-label.c:198
-msgid "Over"
-msgstr "Geçik"
-
-#. Translators: Timestamp prefix (e.g. Almost 5h)
-#: src/notifications/timestamp-label.c:203
-msgid "Almost"
-msgstr "Neredeyse"
+#: src/notifications/timestamp-label.c:121
+msgid "now"
+msgstr "şimdi"
+
+#. Translators: time difference "Over 5 years"
+#: src/notifications/timestamp-label.c:189
+#, c-format
+msgid "Over %dy"
+msgstr "%d yılı aşkın"
-#: src/polkit-auth-agent.c:229
+#. Translators: time difference "almost 5 years"
+#: src/notifications/timestamp-label.c:193
+#, c-format
+msgid "Almost %dy"
+msgstr "Neredeyse %d yıl"
+
+#. Translators: a time difference like '<5m', if in doubt leave untranslated
+#: src/notifications/timestamp-label.c:200
+#, c-format
+msgid "%s%d%s"
+msgstr "%s%d%s"
+
+#: src/polkit-auth-agent.c:225
msgid "Authentication dialog was dismissed by the user"
msgstr "Kullanıcı, yetkilendirme kutusunu görmezden geldi"
-#: src/polkit-auth-prompt.c:276 src/ui/network-auth-prompt.ui:128
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:85
+#: src/ui/polkit-auth-prompt.ui:57 src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Parola:"
-#: src/polkit-auth-prompt.c:322
+#: src/polkit-auth-prompt.c:325
msgid "Sorry, that didn’t work. Please try again."
msgstr "Üzgünüz, işe yaramadı. Lütfen yeniden deneyin."
-#: src/polkit-auth-prompt.c:488
-msgid "Authenticate"
-msgstr "Yetkilendir"
-
-#: src/rotateinfo.c:46
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Dikey"
-#: src/rotateinfo.c:49
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Yatay"
-#: src/system-prompt.c:371
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:183
+msgid "Off"
+msgstr "Kapalı"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Parolalar eşleşmedi."
-#: src/system-prompt.c:378
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Parola boş olamaz"
+#: src/torch-info.c:80
+msgid "Torch"
+msgstr "Fener"
+
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Kararı anımsa"
+
+#: src/ui/app-auth-prompt.ui:55 src/ui/end-session-dialog.ui:50
+msgid "Cancel"
+msgstr "İptal"
+
+#: src/ui/app-auth-prompt.ui:66 src/ui/end-session-dialog.ui:61
+msgid "Ok"
+msgstr "Tamam"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Uygulama"
@@ -232,6 +335,10 @@
msgid "Search apps…"
msgstr "Uygulama ara…"
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Bazı uygulamalar meşgul ya da kaydedilmemiş verisi var"
+
#: src/ui/lockscreen.ui:37
msgid "Slide up to unlock"
msgstr "Açmak için kaldır"
@@ -244,52 +351,39 @@
msgid "Unlock"
msgstr "Kilidi Aç"
-#: src/ui/network-auth-prompt.ui:90
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Yetkilendirme gerekli"
+
+#: src/ui/network-auth-prompt.ui:42
msgid "_Cancel"
msgstr "_İptal"
-#: src/ui/network-auth-prompt.ui:106
+#: src/ui/network-auth-prompt.ui:61
msgid "C_onnect"
msgstr "_Bağlan"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Kullanıcı:"
+#: src/ui/polkit-auth-prompt.ui:125
+msgid "Authenticate"
+msgstr "Yetkilendir"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Doğrula:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Ekranı Kilitle"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Oturumu Kapat"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Yeniden Başlat"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Gücü Kapat"
-
-#: src/wifiinfo.c:88
+#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: Refers to the cellular wireless network
-#: src/wwaninfo.c:168
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Hücresel"
-
-#~ msgid "Unknown artist"
-#~ msgstr "Bilinmeyen sanatçı"
-
-#~ msgid "Unknown Song"
-#~ msgstr "Bilinmeyen Şarkı"
-
-#~ msgid "Suspend"
-#~ msgstr "Askıya Al"
diff -Nru phosh-0.8.0/po/uk.po phosh-0.13.1/po/uk.po
--- phosh-0.8.0/po/uk.po 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/po/uk.po 2021-08-31 09:15:52.000000000 +0000
@@ -7,18 +7,17 @@
msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
-"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/phosh/issues\n"
-"POT-Creation-Date: 2021-01-16 03:33+0000\n"
-"PO-Revision-Date: 2021-01-16 09:10+0200\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/phosh/issues\n"
+"POT-Creation-Date: 2021-08-03 09:16+0000\n"
+"PO-Revision-Date: 2021-08-03 16:28+0300\n"
"Last-Translator: Yuri Chornoivan \n"
"Language-Team: Ukrainian \n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Lokalize 20.11.70\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<"
-"=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"X-Generator: Lokalize 20.12.0\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
#. Translators: this is the session name, no need to translate it
#: data/phosh.session.desktop.in.in:4
@@ -37,9 +36,9 @@
msgid "Application"
msgstr "Програма"
-#: src/bt-info.c:92 src/feedbackinfo.c:51
+#: src/bt-info.c:92 src/feedbackinfo.c:51 src/rotateinfo.c:103
msgid "On"
-msgstr "Увімкнено"
+msgstr "❙"
#: src/bt-info.c:94
msgid "Bluetooth"
@@ -49,10 +48,50 @@
msgid "Docked"
msgstr "Зафіксовано"
-#: src/docked-info.c:195
+#: src/docked-info.c:81 src/docked-info.c:199
msgid "Undocked"
msgstr "Від'єднано"
+#: src/end-session-dialog.c:162
+msgid "Log Out"
+msgstr "Вийти"
+
+#: src/end-session-dialog.c:165
+#, c-format
+msgid "%s will be logged out automatically in %d second."
+msgid_plural "%s will be logged out automatically in %d seconds."
+msgstr[0] "Вихід з системи %s буде здійснено автоматично за %d секунду."
+msgstr[1] "Вихід з системи %s буде здійснено автоматично за %d секунди."
+msgstr[2] "Вихід з системи %s буде здійснено автоматично за %d секунд."
+
+#: src/end-session-dialog.c:171 src/ui/top-panel.ui:37
+msgid "Power Off"
+msgstr "Вимкнути"
+
+#: src/end-session-dialog.c:172
+#, c-format
+msgid "The system will power off automatically in %d second."
+msgid_plural "The system will power off automatically in %d seconds."
+msgstr[0] "Система автоматично вимкнеться за %d секунду."
+msgstr[1] "Система автоматично вимкнеться за %d секунди."
+msgstr[2] "Система автоматично вимкнеться за %d секунд."
+
+#: src/end-session-dialog.c:178 src/ui/top-panel.ui:30
+msgid "Restart"
+msgstr "Перезапустити"
+
+#: src/end-session-dialog.c:179
+#, c-format
+msgid "The system will restart automatically in %d second."
+msgid_plural "The system will restart automatically in %d seconds."
+msgstr[0] "Система автоматично перезапуститься за %d секунду."
+msgstr[1] "Система автоматично перезапуститься за %d секунди."
+msgstr[2] "Система автоматично перезапуститься за %d секунд."
+
+#: src/end-session-dialog.c:269
+msgid "Unknown application"
+msgstr "Невідома програма"
+
#. Translators: quiet and silent are fbd profiles names:
#. see https://source.puri.sm/Librem5/feedbackd#profiles
#. for details
@@ -67,51 +106,67 @@
msgid "Silent"
msgstr "Беззвучно"
-#: src/lockscreen.c:86 src/ui/lockscreen.ui:234
+#: src/location-manager.c:268
+#, c-format
+msgid "Allow '%s' to access your location information?"
+msgstr "Дозволити «%s» доступ до даних щодо вашого місця перебування?"
+
+#: src/location-manager.c:273
+msgid "Geolocation"
+msgstr "Геопозиціювання"
+
+#: src/location-manager.c:274
+msgid "Yes"
+msgstr "Так"
+
+#: src/location-manager.c:274
+msgid "No"
+msgstr "Ні"
+
+#: src/lockscreen.c:152 src/ui/lockscreen.ui:239
msgid "Enter Passcode"
msgstr "Уведіть пароль"
-#: src/lockscreen.c:265
+#: src/lockscreen.c:335
msgid "Checking…"
msgstr "Звіряю…"
#. Translators: This is a time format for a date in
#. long format
-#: src/lockscreen.c:343
+#: src/lockscreen.c:413
msgid "%A, %B %-e"
msgstr "%A, %-d %B"
#. Translators: Used when the title of a song is unknown
-#: src/media-player.c:277 src/ui/media-player.ui:107
+#: src/media-player.c:279 src/ui/media-player.ui:107
msgid "Unknown Title"
msgstr "Невідома назва"
#. Translators: Used when the artist of a song is unknown
-#: src/media-player.c:286 src/ui/media-player.ui:127
+#: src/media-player.c:288 src/ui/media-player.ui:127
msgid "Unknown Artist"
msgstr "Невідомий виконавець"
-#: src/monitor-manager.c:108
+#: src/monitor-manager.c:114
msgid "Built-in display"
msgstr "Вбудований дисплей"
-#: src/monitor-manager.c:126
+#: src/monitor-manager.c:132
#, c-format
-msgctxt ""
-"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
+msgctxt "This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
-#: src/monitor-manager.c:133
+#: src/monitor-manager.c:139
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
"inches could not be calculated, e.g. Dell U2414H"
-msgid "%s %sn"
-msgstr "%s %sn"
+msgid "%s %s"
+msgstr "%s %s"
#. Translators: An unknown monitor type
-#: src/monitor-manager.c:142
+#: src/monitor-manager.c:148
msgid "Unknown"
msgstr "Нетиповий"
@@ -125,11 +180,11 @@
msgid "Enter password for the wifi network “%s”"
msgstr "Введіть пароль до мережі wifi «%s»"
-#: src/notifications/mount-notification.c:137
+#: src/notifications/mount-notification.c:122
msgid "Open"
msgstr "Відкрити"
-#: src/notifications/notification.c:381 src/notifications/notification.c:637
+#: src/notifications/notification.c:383 src/notifications/notification.c:639
msgid "Notification"
msgstr "Сповіщення"
@@ -206,14 +261,12 @@
#. Translators: time difference "Over 5 years"
#: src/notifications/timestamp-label.c:189
#, c-format
-#| msgid "Over"
msgid "Over %dy"
msgstr "Понад %dр."
#. Translators: time difference "almost 5 years"
#: src/notifications/timestamp-label.c:193
#, c-format
-#| msgid "Almost"
msgid "Almost %dy"
msgstr "Майже %dр."
@@ -223,12 +276,13 @@
msgid "%s%d%s"
msgstr "%s%d%s"
-#: src/polkit-auth-agent.c:232
+#: src/polkit-auth-agent.c:228
msgid "Authentication dialog was dismissed by the user"
msgstr "Користувач перервав діалог автентифікації"
-#: src/polkit-auth-prompt.c:278 src/ui/network-auth-prompt.ui:130
-#: src/ui/polkit-auth-prompt.ui:41 src/ui/system-prompt.ui:39
+#: src/polkit-auth-prompt.c:278 src/ui/gtk-mount-prompt.ui:21
+#: src/ui/network-auth-prompt.ui:83 src/ui/polkit-auth-prompt.ui:57
+#: src/ui/system-prompt.ui:33
msgid "Password:"
msgstr "Пароль:"
@@ -236,23 +290,25 @@
msgid "Sorry, that didn’t work. Please try again."
msgstr "На жаль, це не спрацювало. Будь ласка, спробуйте ще."
-#: src/polkit-auth-prompt.c:470
-msgid "Authenticate"
-msgstr "Автентифікуватися"
-
-#: src/rotateinfo.c:65
+#: src/rotateinfo.c:81
msgid "Portrait"
msgstr "Книжкова"
-#: src/rotateinfo.c:68
+#: src/rotateinfo.c:84
msgid "Landscape"
msgstr "Альбомна"
-#: src/system-prompt.c:375
+#. Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled)
+#. Translators: Automatic screen orientation is off (locked/disabled)
+#: src/rotateinfo.c:103 src/rotateinfo.c:186
+msgid "Off"
+msgstr "○"
+
+#: src/system-prompt.c:364
msgid "Passwords do not match."
msgstr "Паролі не збігаються."
-#: src/system-prompt.c:382
+#: src/system-prompt.c:371
msgid "Password cannot be blank"
msgstr "Пароль не може бути порожнім"
@@ -260,6 +316,18 @@
msgid "Torch"
msgstr "Факел"
+#: src/ui/app-auth-prompt.ui:41
+msgid "Remember decision"
+msgstr "Запам'ятати вибір"
+
+#: src/ui/app-auth-prompt.ui:54 src/ui/end-session-dialog.ui:54
+msgid "Cancel"
+msgstr "Скасувати"
+
+#: src/ui/app-auth-prompt.ui:63 src/ui/end-session-dialog.ui:63
+msgid "Ok"
+msgstr "Гаразд"
+
#: src/ui/app-grid-button.ui:49
msgid "App"
msgstr "Програма"
@@ -272,59 +340,80 @@
msgid "Add to _Favorites"
msgstr "Додати до _вибраних"
-#: src/ui/app-grid.ui:21
+#: src/ui/app-grid.ui:22
msgid "Search apps…"
msgstr "Шукати серед програм…"
-#: src/ui/lockscreen.ui:37
+#: src/ui/app-grid.ui:169
+msgid "Show only adaptive apps"
+msgstr "Показувати лише адаптивні програми"
+
+#: src/ui/end-session-dialog.ui:32
+msgid "Some applications are busy or have unsaved work"
+msgstr "Деякі програми зайняті або мають незбережені дані"
+
+#: src/ui/gtk-mount-prompt.ui:95
+msgid "User:"
+msgstr "Користувач:"
+
+#: src/ui/gtk-mount-prompt.ui:118
+msgid "Domain:"
+msgstr "Домен:"
+
+#: src/ui/gtk-mount-prompt.ui:151
+msgid "Co_nnect"
+msgstr "З'єд_натися"
+
+#: src/ui/lockscreen.ui:43
msgid "Slide up to unlock"
msgstr "Протягніть угору, щоб розблокувати"
-#: src/ui/lockscreen.ui:280
+#: src/ui/lockscreen.ui:285
msgid "Emergency"
msgstr "Екстрений виклик"
-#: src/ui/lockscreen.ui:296
+#: src/ui/lockscreen.ui:301
msgid "Unlock"
msgstr "Розблокувати"
-#: src/ui/network-auth-prompt.ui:89
+#: src/ui/lockscreen.ui:341
+msgid "Back"
+msgstr ""
+"Назад"
+
+#: src/ui/network-auth-prompt.ui:6 src/ui/polkit-auth-prompt.ui:7
+msgid "Authentication required"
+msgstr "Слід пройти розпізнавання"
+
+#: src/ui/network-auth-prompt.ui:41
msgid "_Cancel"
msgstr "_Скасувати"
-#: src/ui/network-auth-prompt.ui:105
+#: src/ui/network-auth-prompt.ui:59
msgid "C_onnect"
msgstr "З'_єднатися"
-#: src/ui/polkit-auth-prompt.ui:105
-msgid "User:"
-msgstr "Користувач:"
+#: src/ui/polkit-auth-prompt.ui:123
+msgid "Authenticate"
+msgstr "Автентифікуватися"
-#: src/ui/system-prompt.ui:69
+#: src/ui/system-prompt.ui:63
msgid "Confirm:"
msgstr "Підтвердіть:"
-#: src/ui/top-panel.ui:15
+#: src/ui/top-panel.ui:16
msgid "Lock Screen"
msgstr "Заблокувати екран"
-#: src/ui/top-panel.ui:22
+#: src/ui/top-panel.ui:23
msgid "Logout"
msgstr "Вийти"
-#: src/ui/top-panel.ui:29
-msgid "Restart"
-msgstr "Перезапустити"
-
-#: src/ui/top-panel.ui:36
-msgid "Power Off"
-msgstr "Вимкнути"
-
#: src/wifiinfo.c:90
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: Refers to the cellular wireless network
-#: src/wwaninfo.c:170
+#: src/wwaninfo.c:172
msgid "Cellular"
msgstr "Стільниковий"
diff -Nru phosh-0.8.0/protocol/meson.build phosh-0.13.1/protocol/meson.build
--- phosh-0.8.0/protocol/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/protocol/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -13,13 +13,14 @@
'/'.join([wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml']),
'gamma-control.xml',
'idle.xml',
- 'wlr-screencopy-unstable-v1.xml',
'phosh-private.xml',
+ 'virtual-keyboard-unstable-v1.xml',
'wlr-foreign-toplevel-management-unstable-v1.xml',
'wlr-input-inhibitor-unstable-v1.xml',
'wlr-layer-shell-unstable-v1.xml',
'wlr-output-management-unstable-v1.xml',
'wlr-output-power-management-unstable-v1.xml',
+ 'wlr-screencopy-unstable-v1.xml',
]
wl_proto_sources = []
foreach proto: wl_protos
diff -Nru phosh-0.8.0/protocol/virtual-keyboard-unstable-v1.xml phosh-0.13.1/protocol/virtual-keyboard-unstable-v1.xml
--- phosh-0.8.0/protocol/virtual-keyboard-unstable-v1.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/protocol/virtual-keyboard-unstable-v1.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,113 @@
+
+
+
+ Copyright © 2008-2011 Kristian Høgsberg
+ Copyright © 2010-2013 Intel Corporation
+ Copyright © 2012-2013 Collabora, Ltd.
+ Copyright © 2018 Purism SPC
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+
+
+
+ The virtual keyboard provides an application with requests which emulate
+ the behaviour of a physical keyboard.
+
+ This interface can be used by clients on its own to provide raw input
+ events, or it can accompany the input method protocol.
+
+
+
+
+ Provide a file descriptor to the compositor which can be
+ memory-mapped to provide a keyboard mapping description.
+
+ Format carries a value from the keymap_format enumeration.
+
+
+
+
+
+
+
+
+
+
+
+
+ A key was pressed or released.
+ The time argument is a timestamp with millisecond granularity, with an
+ undefined base. All requests regarding a single object must share the
+ same clock.
+
+ Keymap must be set before issuing this request.
+
+ State carries a value from the key_state enumeration.
+
+
+
+
+
+
+
+
+ Notifies the compositor that the modifier and/or group state has
+ changed, and it should update state.
+
+ The client should use wl_keyboard.modifiers event to synchronize its
+ internal state with seat state.
+
+ Keymap must be set before issuing this request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A virtual keyboard manager allows an application to provide keyboard
+ input events as if they came from a physical keyboard.
+
+
+
+
+
+
+
+
+ Creates a new virtual keyboard associated to a seat.
+
+ If the compositor enables a keyboard to perform arbitrary actions, it
+ should present an error when an untrusted client requests a new
+ keyboard.
+
+
+
+
+
+
diff -Nru phosh-0.8.0/README.md phosh-0.13.1/README.md
--- phosh-0.8.0/README.md 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/README.md 2021-08-31 09:15:52.000000000 +0000
@@ -1,5 +1,4 @@
# Phosh
-[![Code coverage](https://source.puri.sm/Librem5/phosh/badges/master/coverage.svg)](https://source.puri.sm/Librem5/phosh/commits/master)
a pure wayland shell for mobile devices like Purism's Librem 5.
@@ -10,7 +9,7 @@
## Getting the source
```sh
- git clone https://source.puri.sm/Librem5/phosh
+ git clone https://gitlab.gnome.org/World/Phosh/phosh
cd phosh
```
@@ -27,7 +26,7 @@
For an explicit list of dependencies check the `Build-Depends` entry in the
[debian/control][] file.
-If your distro doesn't ship [libhandy](https://source.puri.sm/Librem5/libhandy)
+If your distro doesn't ship [libhandy](https://gitlab.gnome.org/GNOME/libhandy)
you need to build that from source. More details are in the [gitlab-ci.yml][]
file.
@@ -103,13 +102,17 @@
.
# Getting in Touch
-* Issue tracker: https://source.puri.sm/Librem5/phosh
+* Issue tracker: https://gitlab.gnome.org/World/Phosh/phosh/issues
* Mailing list: https://lists.community.puri.sm/listinfo/librem-5-dev
* Matrix: https://im.puri.sm/#/room/#phosh:talk.puri.sm
* XMPP: phosh@conference.sigxcpu.org
For details see the [developer documentation](https://developer.puri.sm/Contact.html).
-[gitlab-ci.yml]: https://source.puri.sm/Librem5/phosh/blob/master/.gitlab-ci.yml
-[debian/control]: https://source.puri.sm/Librem5/phosh/blob/master/debian/control
-[phoc]: https://source.puri.sm/Librem5/phoc
+### Development Documentation
+
+API documentation is at https://world.pages.gitlab.gnome.org/Phosh/phosh
+
+[gitlab-ci.yml]: https://gitlab.gnome.org/World/Phosh/phosh/blob/master/.gitlab-ci.yml
+[debian/control]: https://gitlab.gnome.org/World/Phosh/phosh/blob/master/debian/control
+[phoc]: https://gitlab.gnome.org/World/Phosh/phoc
diff -Nru phosh-0.8.0/src/app-auth-prompt.c phosh-0.13.1/src/app-auth-prompt.c
--- phosh-0.8.0/src/app-auth-prompt.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/app-auth-prompt.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-app-auth-prompt"
+
+#include "config.h"
+
+#include "app-auth-prompt.h"
+
+#include
+
+/**
+ * SECTION:app-auth-prompt
+ * @short_description: A system modal prompt to authorize applications
+ * @Title: PhoshAppAuthPrompt
+ *
+ * The #PhoshAppAuthPrompt is used to authorize applications. It's used
+ * by the #PhoshLocationManager and will later on be used for org.freedesktop.impl.Access.
+ */
+
+enum {
+ CLOSED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+
+enum {
+ PROP_0,
+
+ PROP_ICON,
+ PROP_SUBTITLE,
+ PROP_BODY,
+ PROP_DENY_LABEL,
+ PROP_GRANT_LABEL,
+ PROP_OFFER_REMEMBER,
+ PROP_LAST_PROP,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+
+typedef struct _PhoshAppAuthPrompt {
+ PhoshSystemModalDialog parent;
+
+ GIcon *icon;
+ char *subtitle;
+ char *body;
+ char *deny_label;
+ char *grant_label;
+ gboolean offer_remember;
+
+ GtkWidget *icon_app;
+ GtkWidget *lbl_subtitle;
+ GtkWidget *lbl_body;
+ GtkWidget *btn_grant;
+ GtkWidget *btn_deny;
+ GtkWidget *checkbtn_remember;
+
+ gboolean grant_access;
+ gboolean remember;
+} PhoshAppAuthPrompt;
+
+
+G_DEFINE_TYPE (PhoshAppAuthPrompt, phosh_app_auth_prompt, PHOSH_TYPE_SYSTEM_MODAL_DIALOG)
+
+
+static void
+phosh_app_auth_prompt_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshAppAuthPrompt *self = PHOSH_APP_AUTH_PROMPT (obj);
+
+ switch (prop_id) {
+ case PROP_ICON:
+ self->icon = g_value_dup_object (value);
+ break;
+ case PROP_SUBTITLE:
+ self->subtitle = g_value_dup_string (value);
+ break;
+ case PROP_BODY:
+ self->body = g_value_dup_string (value);
+ break;
+ case PROP_GRANT_LABEL:
+ self->grant_label = g_value_dup_string (value);
+ break;
+ case PROP_DENY_LABEL:
+ self->deny_label = g_value_dup_string (value);
+ break;
+ case PROP_OFFER_REMEMBER:
+ self->offer_remember = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_app_auth_prompt_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshAppAuthPrompt *self = PHOSH_APP_AUTH_PROMPT (obj);
+
+ switch (prop_id) {
+ case PROP_ICON:
+ g_value_set_object (value, self->icon);
+ break;
+ case PROP_SUBTITLE:
+ g_value_set_string (value, self->subtitle);
+ break;
+ case PROP_BODY:
+ g_value_set_string (value, self->body);
+ break;
+ case PROP_GRANT_LABEL:
+ g_value_set_string (value, self->grant_label);
+ break;
+ case PROP_DENY_LABEL:
+ g_value_set_string (value, self->deny_label);
+ break;
+ case PROP_OFFER_REMEMBER:
+ g_value_set_boolean (value, self->offer_remember);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+on_btn_grant_clicked (PhoshAppAuthPrompt *self, GtkButton *btn)
+{
+ self->grant_access = TRUE;
+ self->remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->checkbtn_remember));
+
+ g_signal_emit (self, signals[CLOSED], 0);
+ gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+
+static void
+on_dialog_canceled (PhoshAppAuthPrompt *self)
+{
+ g_return_if_fail (PHOSH_IS_APP_AUTH_PROMPT (self));
+ self->remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->checkbtn_remember));
+
+ g_signal_emit (self, signals[CLOSED], 0);
+ gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+
+
+static void
+phosh_app_auth_prompt_finalize (GObject *obj)
+{
+ PhoshAppAuthPrompt *self = PHOSH_APP_AUTH_PROMPT (obj);
+
+ g_clear_object (&self->icon);
+ g_clear_pointer (&self->subtitle, g_free);
+ g_clear_pointer (&self->body, g_free);
+ g_clear_pointer (&self->grant_label, g_free);
+ g_clear_pointer (&self->deny_label, g_free);
+
+ G_OBJECT_CLASS (phosh_app_auth_prompt_parent_class)->finalize (obj);
+}
+
+
+static void
+phosh_app_auth_prompt_constructed (GObject *object)
+{
+ PhoshAppAuthPrompt *self = PHOSH_APP_AUTH_PROMPT (object);
+
+ G_OBJECT_CLASS (phosh_app_auth_prompt_parent_class)->constructed (object);
+
+ g_object_bind_property (self, "subtitle", self->lbl_subtitle, "label", G_BINDING_DEFAULT);
+ g_object_bind_property (self, "body", self->lbl_body, "label", G_BINDING_DEFAULT);
+ g_object_bind_property (self, "grant-label", self->btn_grant, "label", G_BINDING_DEFAULT);
+ g_object_bind_property (self, "deny-label", self->btn_deny, "label", G_BINDING_DEFAULT);
+ g_object_bind_property (self, "icon", self->icon_app, "gicon", G_BINDING_DEFAULT);
+ g_object_bind_property (self, "offer-remember", self->checkbtn_remember, "visible", G_BINDING_DEFAULT);
+
+ gtk_widget_grab_default (self->btn_grant);
+}
+
+
+static void
+phosh_app_auth_prompt_class_init (PhoshAppAuthPromptClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *)klass;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = phosh_app_auth_prompt_get_property;
+ object_class->set_property = phosh_app_auth_prompt_set_property;
+ object_class->constructed = phosh_app_auth_prompt_constructed;
+ object_class->finalize = phosh_app_auth_prompt_finalize;
+
+ props[PROP_ICON] =
+ g_param_spec_object (
+ "icon",
+ "Icon",
+ "The auth dialog icon",
+ G_TYPE_ICON,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ props[PROP_SUBTITLE] =
+ g_param_spec_string (
+ "subtitle",
+ "Subtitle",
+ "The auth dialog subtitle",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ props[PROP_BODY] =
+ g_param_spec_string (
+ "body",
+ "Body",
+ "The auth dialog body",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ props[PROP_GRANT_LABEL] =
+ g_param_spec_string (
+ "grant-label",
+ "Grant label",
+ "The auth dialog's grant access button label",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ props[PROP_DENY_LABEL] =
+ g_param_spec_string (
+ "deny-label",
+ "Deny label",
+ "The auth dialog's deny access button label",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ props[PROP_OFFER_REMEMBER] =
+ g_param_spec_boolean (
+ "offer-remember",
+ "Offer Remember",
+ "Whether to offer to remember the auth decision result",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ signals[CLOSED] = g_signal_new ("closed",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/sm/puri/phosh/ui/app-auth-prompt.ui");
+ gtk_widget_class_bind_template_child (widget_class, PhoshAppAuthPrompt, icon_app);
+ gtk_widget_class_bind_template_child (widget_class, PhoshAppAuthPrompt, lbl_subtitle);
+ gtk_widget_class_bind_template_child (widget_class, PhoshAppAuthPrompt, lbl_body);
+ gtk_widget_class_bind_template_child (widget_class, PhoshAppAuthPrompt, btn_grant);
+ gtk_widget_class_bind_template_child (widget_class, PhoshAppAuthPrompt, btn_deny);
+ gtk_widget_class_bind_template_child (widget_class, PhoshAppAuthPrompt, checkbtn_remember);
+ gtk_widget_class_bind_template_callback (widget_class, on_btn_grant_clicked);
+ gtk_widget_class_bind_template_callback (widget_class, on_dialog_canceled);
+}
+
+
+static void
+phosh_app_auth_prompt_init (PhoshAppAuthPrompt *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+
+GtkWidget *
+phosh_app_auth_prompt_new (GIcon *icon,
+ const char *title,
+ const char *subtitle,
+ const char *body,
+ const char *grant_label,
+ const char *deny_label,
+ gboolean offer_remember)
+{
+ return g_object_new (PHOSH_TYPE_APP_AUTH_PROMPT,
+ "icon", icon,
+ "title", title,
+ "subtitle", subtitle,
+ "body", body,
+ "grant-label", grant_label,
+ "deny-label", deny_label,
+ "offer-remember", offer_remember,
+ NULL);
+}
+
+gboolean
+phosh_app_auth_prompt_get_grant_access (GtkWidget *self)
+{
+ g_return_val_if_fail (PHOSH_IS_APP_AUTH_PROMPT (self), FALSE);
+
+ return PHOSH_APP_AUTH_PROMPT (self)->grant_access;
+}
diff -Nru phosh-0.8.0/src/app-auth-prompt.h phosh-0.13.1/src/app-auth-prompt.h
--- phosh-0.8.0/src/app-auth-prompt.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/app-auth-prompt.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "system-modal-dialog.h"
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_APP_AUTH_PROMPT (phosh_app_auth_prompt_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshAppAuthPrompt, phosh_app_auth_prompt, PHOSH, APP_AUTH_PROMPT, PhoshSystemModalDialog)
+
+GtkWidget *phosh_app_auth_prompt_new (GIcon *icon,
+ const char *title,
+ const char *subtitle,
+ const char *body,
+ const char *grant_label,
+ const char *deny_label,
+ gboolean offer_remember);
+gboolean phosh_app_auth_prompt_get_grant_access (GtkWidget *self);
+gboolean phosh_app_auth_prompt_get_remember (GtkWidget *self);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/app-grid-button.c phosh-0.13.1/src/app-grid-button.c
--- phosh-0.8.0/src/app-grid-button.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/app-grid-button.c 2021-08-31 09:15:52.000000000 +0000
@@ -121,8 +121,8 @@
g_clear_object (&priv->actions);
g_clear_object (&priv->action_map);
- phosh_clear_handler (&priv->favorite_changed_watcher,
- phosh_favorite_list_model_get_default ());
+ g_clear_signal_handler (&priv->favorite_changed_watcher,
+ phosh_favorite_list_model_get_default ());
G_OBJECT_CLASS (phosh_app_grid_button_parent_class)->finalize (object);
}
@@ -468,7 +468,7 @@
list = phosh_favorite_list_model_get_default ();
- phosh_clear_handler (&priv->favorite_changed_watcher, list);
+ g_clear_signal_handler (&priv->favorite_changed_watcher, list);
if (info) {
priv->info = g_object_ref (info);
diff -Nru phosh-0.8.0/src/app-grid.c phosh-0.13.1/src/app-grid.c
--- phosh-0.8.0/src/app-grid.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/app-grid.c 2021-08-31 09:15:52.000000000 +0000
@@ -8,15 +8,32 @@
#define ACTIVE_SEARCH_CLASS "search-active"
+#define _GNU_SOURCE
+#include
+
#include "feedback-manager.h"
#include "app-grid.h"
#include "app-grid-button.h"
#include "app-list-model.h"
#include "favorite-list-model.h"
+#include "shell.h"
#include "gtk-list-models/gtksortlistmodel.h"
#include "gtk-list-models/gtkfilterlistmodel.h"
+enum {
+ PROP_0,
+ PROP_FILTER_ADAPTIVE,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+enum {
+ APP_LAUNCHED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
typedef struct _PhoshAppGridPrivate PhoshAppGridPrivate;
struct _PhoshAppGridPrivate {
GtkFilterListModel *model;
@@ -26,17 +43,56 @@
GtkWidget *favs;
GtkWidget *favs_revealer;
GtkWidget *scrolled_window;
+ GtkWidget *menu_button;
char *search_string;
+ gboolean filter_adaptive;
+ GSettings *settings;
+ GStrv force_adaptive;
+ GSimpleActionGroup *actions;
+ PhoshAppFilterModeFlags filter_mode;
};
G_DEFINE_TYPE_WITH_PRIVATE (PhoshAppGrid, phosh_app_grid, GTK_TYPE_BOX)
-enum {
- APP_LAUNCHED,
- N_SIGNALS
-};
-static guint signals[N_SIGNALS] = { 0 };
+static void
+phosh_app_grid_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshAppGrid *self = PHOSH_APP_GRID (object);
+
+ switch (property_id) {
+ case PROP_FILTER_ADAPTIVE:
+ phosh_app_grid_set_filter_adaptive (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_app_grid_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshAppGrid *self = PHOSH_APP_GRID (object);
+ PhoshAppGridPrivate *priv = phosh_app_grid_get_instance_private (self);
+
+ switch (property_id) {
+ case PROP_FILTER_ADAPTIVE:
+ g_value_set_boolean (value, priv->filter_adaptive);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
static void
app_launched_cb (GtkWidget *widget,
@@ -63,6 +119,64 @@
}
+
+static void
+on_filter_setting_changed (PhoshAppGrid *self,
+ GParamSpec *pspec,
+ gpointer *unused)
+{
+ PhoshAppGridPrivate *priv;
+ gboolean show;
+
+ g_return_if_fail (PHOSH_IS_APP_GRID (self));
+
+ priv = phosh_app_grid_get_instance_private (self);
+
+ g_strfreev (priv->force_adaptive);
+ priv->force_adaptive = g_settings_get_strv (priv->settings,
+ "force-adaptive");
+ priv->filter_mode = g_settings_get_flags (priv->settings,
+ "app-filter-mode");
+
+ show = !!(priv->filter_mode & PHOSH_APP_FILTER_MODE_FLAGS_ADAPTIVE);
+ gtk_widget_set_visible (priv->menu_button, show);
+
+ gtk_filter_list_model_refilter (priv->model);
+}
+
+
+static gboolean
+filter_adaptive (PhoshAppGrid *self, GDesktopAppInfo *info)
+{
+ PhoshAppGridPrivate *priv = phosh_app_grid_get_instance_private (self);
+ g_autofree char *mobile = NULL;
+ const char *id;
+
+ if (!(priv->filter_mode & PHOSH_APP_FILTER_MODE_FLAGS_ADAPTIVE))
+ return TRUE;
+
+ if (!priv->filter_adaptive)
+ return TRUE;
+
+ mobile = g_desktop_app_info_get_string (G_DESKTOP_APP_INFO (info),
+ "X-Purism-FormFactor");
+ if (mobile && strcasestr (mobile, "mobile;"))
+ return TRUE;
+
+ g_free (mobile);
+ mobile = g_desktop_app_info_get_string (G_DESKTOP_APP_INFO (info),
+ "X-KDE-FormFactor");
+ if (mobile && strcasestr (mobile, "handset;"))
+ return TRUE;
+
+ id = g_app_info_get_id (G_APP_INFO (info));
+ if (id && g_strv_contains ((const char * const*)priv->force_adaptive, id))
+ return TRUE;
+
+ return FALSE;
+}
+
+
static const char *(*app_attr[]) (GAppInfo *info) = {
g_app_info_get_display_name,
g_app_info_get_name,
@@ -91,6 +205,11 @@
search = priv->search_string;
+ if (G_IS_DESKTOP_APP_INFO (info)) {
+ if (!filter_adaptive (self, G_DESKTOP_APP_INFO (info)))
+ return FALSE;
+ }
+
/* filter out favorites when not searching */
if (search == NULL || strlen (search) == 0) {
if (phosh_favorite_list_model_app_is_favorite (NULL, info))
@@ -198,6 +317,7 @@
PhoshAppGridPrivate *priv = phosh_app_grid_get_instance_private (self);
GtkSortListModel *sorted;
PhoshFavoriteListModel *favorites;
+ g_autoptr (GAction) action = NULL;
gtk_widget_init_template (GTK_WIDGET (self));
@@ -220,20 +340,50 @@
search_apps,
self,
NULL);
+ g_object_unref (sorted);
gtk_flow_box_bind_model (GTK_FLOW_BOX (priv->apps),
G_LIST_MODEL (priv->model),
create_launcher, self, NULL);
+
+ priv->settings = g_settings_new ("sm.puri.phosh");
+ g_object_connect (priv->settings,
+ "swapped-signal::changed::force-adaptive",
+ G_CALLBACK (on_filter_setting_changed), self,
+ "swapped-signal::changed::app-filter-mode",
+ G_CALLBACK (on_filter_setting_changed), self,
+ NULL);
+ on_filter_setting_changed (self, NULL, NULL);
+
+ priv->actions = g_simple_action_group_new ();
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "app-grid",
+ G_ACTION_GROUP (priv->actions));
+ action = (GAction*) g_property_action_new ("filter-adaptive", self, "filter-adaptive");
+ g_action_map_add_action (G_ACTION_MAP (priv->actions), action);
}
static void
-phosh_app_grid_finalize (GObject *object)
+phosh_app_grid_dispose (GObject *object)
{
PhoshAppGrid *self = PHOSH_APP_GRID (object);
PhoshAppGridPrivate *priv = phosh_app_grid_get_instance_private (self);
+ g_clear_object (&priv->actions);
g_clear_object (&priv->model);
+ g_clear_object (&priv->settings);
+
+ G_OBJECT_CLASS (phosh_app_grid_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_app_grid_finalize (GObject *object)
+{
+ PhoshAppGrid *self = PHOSH_APP_GRID (object);
+ PhoshAppGridPrivate *priv = phosh_app_grid_get_instance_private (self);
+
g_clear_pointer (&priv->search_string, g_free);
+ g_strfreev (priv->force_adaptive);
G_OBJECT_CLASS (phosh_app_grid_parent_class)->finalize (object);
}
@@ -372,10 +522,28 @@
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = phosh_app_grid_dispose;
object_class->finalize = phosh_app_grid_finalize;
+ object_class->set_property = phosh_app_grid_set_property;
+ object_class->get_property = phosh_app_grid_get_property;
+
widget_class->key_press_event = phosh_app_grid_key_press_event;
+ /**
+ * PhoshAppGrid:filter-adaptive:
+ *
+ * Whether only adaptive apps should be shown
+ */
+ props[PROP_FILTER_ADAPTIVE] =
+ g_param_spec_boolean ("filter-adaptive",
+ "",
+ "",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/phosh/ui/app-grid.ui");
gtk_widget_class_bind_template_child_private (widget_class, PhoshAppGrid, search);
@@ -383,6 +551,7 @@
gtk_widget_class_bind_template_child_private (widget_class, PhoshAppGrid, favs);
gtk_widget_class_bind_template_child_private (widget_class, PhoshAppGrid, favs_revealer);
gtk_widget_class_bind_template_child_private (widget_class, PhoshAppGrid, scrolled_window);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshAppGrid, menu_button);
gtk_widget_class_bind_template_callback (widget_class, search_changed);
gtk_widget_class_bind_template_callback (widget_class, search_preedit_changed);
@@ -434,3 +603,40 @@
priv = phosh_app_grid_get_instance_private (self);
gtk_widget_grab_focus (priv->search);
}
+
+
+gboolean
+phosh_app_grid_handle_search (PhoshAppGrid *self, GdkEvent *event)
+{
+ PhoshAppGridPrivate *priv;
+ gboolean ret;
+
+ g_return_val_if_fail (PHOSH_IS_APP_GRID (self), GDK_EVENT_PROPAGATE);
+ priv = phosh_app_grid_get_instance_private (self);
+ ret = gtk_search_entry_handle_event (GTK_SEARCH_ENTRY (priv->search), event);
+ if (ret == GDK_EVENT_STOP)
+ gtk_entry_grab_focus_without_selecting (GTK_ENTRY (priv->search));
+
+ return ret;
+}
+
+
+void
+phosh_app_grid_set_filter_adaptive (PhoshAppGrid *self, gboolean enable)
+{
+ PhoshAppGridPrivate *priv;
+
+ g_debug ("Filter-adaptive: %d", enable);
+
+ g_return_if_fail (PHOSH_IS_APP_GRID (self));
+ priv = phosh_app_grid_get_instance_private (self);
+
+ if (priv->filter_adaptive == enable)
+ return;
+
+ priv->filter_adaptive = enable;
+
+ gtk_filter_list_model_refilter (priv->model);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FILTER_ADAPTIVE]);
+}
diff -Nru phosh-0.8.0/src/app-grid.h phosh-0.13.1/src/app-grid.h
--- phosh-0.8.0/src/app-grid.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/app-grid.h 2021-08-31 09:15:52.000000000 +0000
@@ -13,6 +13,19 @@
G_BEGIN_DECLS
+/**
+ * PhoshAppFilterModeFlags:
+ * @PHOSH_APP_FILTER_MODE_FLAGS_NONE: No filtering
+ * @PHOSH_APP_FILTER_MODE_FLAGS_ADAPTIVE: Only show apps in mobile mode that adapt
+ * to smalls screen sizes.
+ *
+ * Controls what kind of app filtering is done.
+*/
+typedef enum {
+ PHOSH_APP_FILTER_MODE_FLAGS_NONE = 0,
+ PHOSH_APP_FILTER_MODE_FLAGS_ADAPTIVE = (1 << 0),
+} PhoshAppFilterModeFlags;
+
#define PHOSH_TYPE_APP_GRID phosh_app_grid_get_type()
G_DECLARE_DERIVABLE_TYPE (PhoshAppGrid, phosh_app_grid, PHOSH, APP_GRID, GtkBox)
@@ -24,5 +37,8 @@
GtkWidget *phosh_app_grid_new (void);
void phosh_app_grid_reset (PhoshAppGrid *self);
void phosh_app_grid_focus_search (PhoshAppGrid *self);
+gboolean phosh_app_grid_handle_search (PhoshAppGrid *self, GdkEvent *event);
+void phosh_app_grid_set_filter_adaptive (PhoshAppGrid *self, gboolean enable);
+
G_END_DECLS
diff -Nru phosh-0.8.0/src/app-list-model.c phosh-0.13.1/src/app-list-model.c
--- phosh-0.8.0/src/app-list-model.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/app-list-model.c 2021-08-31 09:15:52.000000000 +0000
@@ -169,7 +169,7 @@
g_source_remove (priv->debounce);
}
priv->debounce = g_timeout_add (500, items_changed, data);
- g_source_set_name_by_id (priv->debounce, "debounce app changes");
+ g_source_set_name_by_id (priv->debounce, "[phosh] debounce app changes");
}
diff -Nru phosh-0.8.0/src/background.c phosh-0.13.1/src/background.c
--- phosh-0.8.0/src/background.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/background.c 2021-08-31 09:15:52.000000000 +0000
@@ -15,7 +15,8 @@
#include "background.h"
#include "shell.h"
-#include "panel.h"
+#include "top-panel.h"
+#include "util.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include
@@ -68,7 +69,7 @@
GdkRGBA color;
gboolean primary;
- guint scale;
+ float scale;
GdkPixbuf *pixbuf;
GSettings *settings;
gboolean configured;
@@ -95,7 +96,7 @@
phosh_background_set_primary (self, g_value_get_boolean (value));
break;
case PROP_SCALE:
- phosh_background_set_scale (self, g_value_get_uint (value));
+ phosh_background_set_scale (self, g_value_get_float (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -117,7 +118,7 @@
g_value_set_boolean (value, self->primary);
break;
case PROP_SCALE:
- g_value_set_uint (value, self->scale);
+ g_value_set_float (value, self->scale);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -270,7 +271,7 @@
else
g_object_get (self, "configured-width", &width, "configured-height", &height, NULL);
- g_debug ("Scaling %p to %dx%d, scale %d", self, width, height, self->scale);
+ g_debug ("Scaling %p to %dx%d, scale %f", self, width, height, self->scale);
self->pixbuf = image_background (pixbuf, width * self->scale, height * self->scale, style, &self->color);
/* force background redraw */
gtk_widget_queue_draw (GTK_WIDGET (self));
@@ -303,18 +304,13 @@
image = gdk_pixbuf_new_from_stream_finish (res, &err);
if (!image) {
- if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- /* Do nothing we expect a new load to be triggered */
- g_debug ("Load of %s canceled", self->uri);
- } else {
- g_warning ("Failed to load background %s: %s", self->uri, err->message);
- }
- if (!self->pixbuf)
+ /* Do nothing on cancel since we expect a new load to be triggered */
+ if (!phosh_async_error_warn (err, "Failed to load background"))
background_fallback (self);
g_object_unref (self);
return;
}
- g_debug ("loaded %s", self->uri);
+ g_debug ("Loaded %s", self->uri);
background_update (self, image, self->style);
g_object_unref (self);
}
@@ -361,7 +357,7 @@
g_return_if_fail (PHOSH_IS_BACKGROUND (self));
if (!g_task_propagate_boolean (G_TASK (res), &err)) {
- g_warning ("Failed to load %s: %s", self->uri, err->message);
+ phosh_async_error_warn (err, "%s", self->uri);
goto out;
}
@@ -398,6 +394,7 @@
g_warning ("Couldn't get filename for %s: %s", self->uri, err->message);
return FALSE;
}
+ g_clear_object (&self->slideshow);
self->slideshow = gnome_bg_slide_show_new (filename);
self->cancel = g_cancellable_new ();
@@ -534,6 +531,9 @@
{
PhoshBackground *self = PHOSH_BACKGROUND (object);
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
g_clear_object (&self->slideshow);
G_OBJECT_CLASS (phosh_background_parent_class)->dispose (object);
@@ -585,16 +585,16 @@
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_CONSTRUCT);
props[PROP_SCALE] =
- g_param_spec_uint ("scale",
- "Scale",
- "The output scale",
- 1,
- G_MAXUINT,
- 1,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS |
- G_PARAM_EXPLICIT_NOTIFY |
- G_PARAM_CONSTRUCT);
+ g_param_spec_float ("scale",
+ "Scale",
+ "The output scale",
+ 1.0,
+ G_MAXFLOAT,
+ 1.0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_CONSTRUCT);
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
@@ -610,7 +610,7 @@
GtkWidget *
phosh_background_new (gpointer layer_shell,
gpointer wl_output,
- guint scale,
+ float scale,
gboolean primary)
{
return g_object_new (PHOSH_TYPE_BACKGROUND,
@@ -644,9 +644,9 @@
void
-phosh_background_set_scale (PhoshBackground *self, guint scale)
+phosh_background_set_scale (PhoshBackground *self, float scale)
{
- if (self->scale == scale)
+ if ((int)(self->scale * 1000) == (int)(scale * 1000))
return;
self->scale = scale;
diff -Nru phosh-0.8.0/src/background.h phosh-0.13.1/src/background.h
--- phosh-0.8.0/src/background.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/background.h 2021-08-31 09:15:52.000000000 +0000
@@ -18,7 +18,7 @@
GtkWidget *phosh_background_new (gpointer layer_shell,
gpointer wl_output,
- guint scale,
+ float scale,
gboolean primary);
void phosh_background_set_primary (PhoshBackground *self, gboolean primary);
-void phosh_background_set_scale (PhoshBackground *self, guint scale);
+void phosh_background_set_scale (PhoshBackground *self, float scale);
diff -Nru phosh-0.8.0/src/background-manager.c phosh-0.13.1/src/background-manager.c
--- phosh-0.8.0/src/background-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/background-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -44,7 +44,7 @@
background = g_object_ref_sink(PHOSH_BACKGROUND (phosh_background_new (
phosh_wayland_get_zwlr_layer_shell_v1(wl),
monitor->wl_output,
- MAX(1, monitor->scale),
+ MAX(1.0, phosh_monitor_get_fractional_scale (monitor)),
monitor == self->primary_monitor)));
g_hash_table_insert (self->backgrounds,
g_object_ref (monitor),
@@ -71,14 +71,16 @@
PhoshMonitor *monitor)
{
PhoshBackground *background;
+ float scale;
g_return_if_fail (PHOSH_IS_MONITOR (monitor));
- g_debug ("Monitor %p (%s) configured", monitor, monitor->name);
+ scale = phosh_monitor_get_fractional_scale (monitor);
+ g_debug ("Monitor %p (%s) configured, scale %f", monitor, monitor->name, scale);
background = g_hash_table_lookup (self->backgrounds, monitor);
g_return_if_fail (background);
- phosh_background_set_scale (background, monitor->scale);
+ phosh_background_set_scale (background, scale);
gtk_widget_show (GTK_WIDGET (background));
}
@@ -204,3 +206,18 @@
{
return g_object_new (PHOSH_TYPE_BACKGROUND_MANAGER, NULL);
}
+
+
+/**
+ * phosh_background_manager_get_backgrounds:
+ * @self: The #PhoshBackgroundManager
+ *
+ * Returns: (transfer container) (element-type PhoshBackground): The current backgrounds
+ */
+GList *
+phosh_background_manager_get_backgrounds (PhoshBackgroundManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_BACKGROUND_MANAGER (self), NULL);
+
+ return g_hash_table_get_values (self->backgrounds);
+}
diff -Nru phosh-0.8.0/src/background-manager.h phosh-0.13.1/src/background-manager.h
--- phosh-0.8.0/src/background-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/background-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -16,4 +16,5 @@
BACKGROUND_MANAGER,
GObject)
-PhoshBackgroundManager *phosh_background_manager_new (void);
+PhoshBackgroundManager *phosh_background_manager_new (void);
+GList *phosh_background_manager_get_backgrounds (PhoshBackgroundManager *self);
diff -Nru phosh-0.8.0/src/batteryinfo.c phosh-0.13.1/src/batteryinfo.c
--- phosh-0.8.0/src/batteryinfo.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/batteryinfo.c 2021-08-31 09:15:52.000000000 +0000
@@ -14,6 +14,7 @@
#include "batteryinfo.h"
#include "upower.h"
+#include "util.h"
/**
* SECTION:batteryinfo
@@ -21,10 +22,19 @@
* @Title: PhoshBatteryInfo
*/
+enum {
+ PROP_0,
+ PROP_SHOW_DETAIL,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+
typedef struct _PhoshBatteryInfo {
- PhoshStatusIcon parent;
- UpClient *upower;
- UpDevice *device;
+ PhoshStatusIcon parent;
+ UpClient *upower;
+ UpDevice *device;
+ gboolean show_detail;
} PhoshBatteryInfo;
@@ -32,14 +42,51 @@
static void
+phosh_battery_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshBatteryInfo *self = PHOSH_BATTERY_INFO (object);
+
+ switch (property_id) {
+ case PROP_SHOW_DETAIL:
+ phosh_battery_info_set_show_detail (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_battery_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshBatteryInfo *self = PHOSH_BATTERY_INFO (object);
+
+ switch (property_id) {
+ case PROP_SHOW_DETAIL:
+ g_value_set_boolean (value, self->show_detail);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
setup_display_device (PhoshBatteryInfo *self)
{
- GError *err = NULL;
+ g_autoptr (GError) err = NULL;
self->upower = up_client_new_full (NULL, &err);
if (self->upower == NULL) {
- g_warning ("Failed to connect to upowerd: %s", err->message);
- g_clear_error (&err);
+ phosh_dbus_service_error_warn (err, "Failed to connect to upowerd");
return;
}
@@ -57,7 +104,8 @@
const GValue *from_value,
GValue *to_value,
gpointer user_data) {
- g_value_set_string(to_value, g_strdup_printf ("%d%%", (int)(g_value_get_double(from_value) + 0.5)));
+ g_value_take_string (to_value,
+ g_strdup_printf ("%d%%", (int) (g_value_get_double (from_value) + 0.5)));
return TRUE;
}
@@ -81,6 +129,11 @@
NULL,
NULL,
NULL);
+ g_object_bind_property (self,
+ "info",
+ phosh_status_icon_get_extra_widget (PHOSH_STATUS_ICON (self)),
+ "label",
+ G_BINDING_SYNC_CREATE);
}
}
@@ -90,11 +143,8 @@
{
PhoshBatteryInfo *self = PHOSH_BATTERY_INFO (object);
- if (self->device)
- g_clear_object (&self->device);
-
- if (self->upower)
- g_clear_object (&self->upower);
+ g_clear_object (&self->device);
+ g_clear_object (&self->upower);
G_OBJECT_CLASS (phosh_battery_info_parent_class)->dispose (object);
}
@@ -104,15 +154,38 @@
phosh_battery_info_class_init (PhoshBatteryInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_battery_info_constructed;
object_class->dispose = phosh_battery_info_dispose;
+ object_class->get_property = phosh_battery_info_get_property;
+ object_class->set_property = phosh_battery_info_set_property;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-battery-info");
+
+ props[PROP_SHOW_DETAIL] =
+ g_param_spec_boolean (
+ "show-detail",
+ "",
+ "",
+ FALSE,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
static void
phosh_battery_info_init (PhoshBatteryInfo *self)
{
+ GtkWidget *percentage = gtk_label_new (NULL);
+ phosh_status_icon_set_extra_widget (PHOSH_STATUS_ICON (self), percentage);
+
+ g_object_bind_property (self,
+ "show-detail",
+ percentage,
+ "visible",
+ G_BINDING_SYNC_CREATE);
}
@@ -121,3 +194,25 @@
{
return g_object_new (PHOSH_TYPE_BATTERY_INFO, NULL);
}
+
+
+void
+phosh_battery_info_set_show_detail (PhoshBatteryInfo *self, gboolean show)
+{
+ g_return_if_fail (PHOSH_IS_BATTERY_INFO (self));
+
+ if (self->show_detail == show)
+ return;
+
+ self->show_detail = !!show;
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SHOW_DETAIL]);
+}
+
+
+gboolean
+phosh_battery_info_get_show_detail (PhoshBatteryInfo *self)
+{
+ g_return_val_if_fail (PHOSH_IS_BATTERY_INFO (self), FALSE);
+
+ return self->show_detail;
+}
diff -Nru phosh-0.8.0/src/batteryinfo.h phosh-0.13.1/src/batteryinfo.h
--- phosh-0.8.0/src/batteryinfo.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/batteryinfo.h 2021-08-31 09:15:52.000000000 +0000
@@ -17,5 +17,7 @@
G_DECLARE_FINAL_TYPE (PhoshBatteryInfo, phosh_battery_info, PHOSH, BATTERY_INFO, PhoshStatusIcon)
GtkWidget * phosh_battery_info_new (void);
+void phosh_battery_info_set_show_detail (PhoshBatteryInfo *self, gboolean show);
+gboolean phosh_battery_info_get_show_detail (PhoshBatteryInfo *self);
G_END_DECLS
diff -Nru phosh-0.8.0/src/bt-info.c phosh-0.13.1/src/bt-info.c
--- phosh-0.8.0/src/bt-info.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/bt-info.c 2021-08-31 09:15:52.000000000 +0000
@@ -130,13 +130,14 @@
}
-static gboolean
-on_idle (PhoshBtInfo *self)
+static void
+phosh_bt_info_idle_init (PhoshStatusIcon *icon)
{
+ PhoshBtInfo *self = PHOSH_BT_INFO (icon);
+
update_icon (self, NULL, self->bt);
update_info (self);
on_bt_enabled (self, NULL, self->bt);
- return G_SOURCE_REMOVE;
}
@@ -177,8 +178,6 @@
"notify::present",
G_CALLBACK (on_bt_present),
self);
-
- g_idle_add ((GSourceFunc) on_idle, self);
}
@@ -200,11 +199,17 @@
phosh_bt_info_class_init (PhoshBtInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshStatusIconClass *status_icon_class = PHOSH_STATUS_ICON_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_bt_info_constructed;
object_class->dispose = phosh_bt_info_dispose;
object_class->get_property = phosh_bt_info_get_property;
+ status_icon_class->idle_init = phosh_bt_info_idle_init;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-bt-info");
+
props[PROP_ENABLED] =
g_param_spec_boolean ("enabled",
"enabled",
diff -Nru phosh-0.8.0/src/bt-manager.c phosh-0.13.1/src/bt-manager.c
--- phosh-0.8.0/src/bt-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/bt-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -13,6 +13,7 @@
#include "bt-manager.h"
#include "shell.h"
#include "dbus/gsd-rfkill-dbus.h"
+#include "util.h"
#define BUS_NAME "org.gnome.SettingsDaemon.Rfkill"
#define OBJECT_PATH "/org/gnome/SettingsDaemon/Rfkill"
@@ -39,7 +40,7 @@
static GParamSpec *props[PROP_LAST_PROP];
struct _PhoshBtManager {
- GObject parent;
+ PhoshManager manager;
/* Whether bt radio is on */
gboolean enabled;
@@ -49,7 +50,7 @@
PhoshRfkillDBusRfkill *proxy;
};
-G_DEFINE_TYPE (PhoshBtManager, phosh_bt_manager, G_TYPE_OBJECT);
+G_DEFINE_TYPE (PhoshBtManager, phosh_bt_manager, PHOSH_TYPE_MANAGER);
static void
@@ -134,42 +135,6 @@
static void
-phosh_bt_manager_class_init (PhoshBtManagerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = phosh_bt_manager_get_property;
-
- props[PROP_ICON_NAME] =
- g_param_spec_string ("icon-name",
- "icon name",
- "The bt icon name",
- "bluetooth-disabled-symbolic",
- G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
-
- props[PROP_ENABLED] =
- g_param_spec_boolean ("enabled",
- "enabled",
- "Whether bluetooth hardware is enabled",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_EXPLICIT_NOTIFY |
- G_PARAM_STATIC_STRINGS);
-
- props[PROP_PRESENT] =
- g_param_spec_boolean ("present",
- "Present",
- "Whether bluettoh hardware is present",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_EXPLICIT_NOTIFY |
- G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
-}
-
-
-static void
on_proxy_new_for_bus_finish (GObject *source_object,
GAsyncResult *res,
PhoshBtManager *self)
@@ -181,7 +146,7 @@
self->proxy = phosh_rfkill_dbus_rfkill_proxy_new_for_bus_finish (res, &err);
if (!self->proxy) {
- g_warning ("Failed to get gsd rfkill proxy: %s", err->message);
+ phosh_dbus_service_error_warn (err, "Failed to get gsd rfkill proxy");
goto out;
}
@@ -202,9 +167,11 @@
}
-static gboolean
-on_idle (PhoshBtManager *self)
+static void
+phosh_bt_manager_idle_init (PhoshManager *manager)
{
+ PhoshBtManager *self = PHOSH_BT_MANAGER (manager);
+
phosh_rfkill_dbus_rfkill_proxy_new_for_bus (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_NONE,
BUS_NAME,
@@ -212,7 +179,58 @@
NULL,
(GAsyncReadyCallback) on_proxy_new_for_bus_finish,
g_object_ref (self));
- return G_SOURCE_REMOVE;
+}
+
+
+static void
+phosh_bt_manager_dispose (GObject *object)
+{
+ PhoshBtManager *self = PHOSH_BT_MANAGER (object);
+
+ g_clear_object (&self->proxy);
+
+ G_OBJECT_CLASS (phosh_bt_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_bt_manager_class_init (PhoshBtManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshManagerClass *manager_class = PHOSH_MANAGER_CLASS (klass);
+
+ object_class->dispose = phosh_bt_manager_dispose;
+
+ object_class->get_property = phosh_bt_manager_get_property;
+
+ manager_class->idle_init = phosh_bt_manager_idle_init;
+
+ props[PROP_ICON_NAME] =
+ g_param_spec_string ("icon-name",
+ "icon name",
+ "The bt icon name",
+ "bluetooth-disabled-symbolic",
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_ENABLED] =
+ g_param_spec_boolean ("enabled",
+ "enabled",
+ "Whether bluetooth hardware is enabled",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_PRESENT] =
+ g_param_spec_boolean ("present",
+ "Present",
+ "Whether bluettoh hardware is present",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
@@ -220,8 +238,6 @@
phosh_bt_manager_init (PhoshBtManager *self)
{
self->icon_name = "bluetooth-disabled-symbolic";
- /* Perform DBus setup when idle */
- g_idle_add ((GSourceFunc)on_idle, self);
}
@@ -250,6 +266,24 @@
}
+void
+phosh_bt_manager_set_enabled (PhoshBtManager *self, gboolean enabled)
+{
+ g_return_if_fail (PHOSH_IS_BT_MANAGER (self));
+
+ if (!self->present)
+ return;
+
+ if (enabled == self->enabled)
+ return;
+
+ g_return_if_fail (self->proxy);
+
+ self->enabled = enabled;
+ phosh_rfkill_dbus_rfkill_set_bluetooth_airplane_mode (self->proxy, !enabled);
+}
+
+
gboolean
phosh_bt_manager_get_present (PhoshBtManager *self)
{
diff -Nru phosh-0.8.0/src/bt-manager.h phosh-0.13.1/src/bt-manager.h
--- phosh-0.8.0/src/bt-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/bt-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,17 +6,20 @@
#pragma once
+#include
+
#include
G_BEGIN_DECLS
#define PHOSH_TYPE_BT_MANAGER (phosh_bt_manager_get_type ())
-G_DECLARE_FINAL_TYPE (PhoshBtManager, phosh_bt_manager, PHOSH, BT_MANAGER, GObject)
+G_DECLARE_FINAL_TYPE (PhoshBtManager, phosh_bt_manager, PHOSH, BT_MANAGER, PhoshManager)
PhoshBtManager *phosh_bt_manager_new (void);
const char *phosh_bt_manager_get_icon_name (PhoshBtManager *self);
gboolean phosh_bt_manager_get_enabled (PhoshBtManager *self);
+void phosh_bt_manager_set_enabled (PhoshBtManager *self, gboolean enabled);
gboolean phosh_bt_manager_get_present (PhoshBtManager *self);
G_END_DECLS
diff -Nru phosh-0.8.0/src/call.c phosh-0.13.1/src/call.c
--- phosh-0.8.0/src/call.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/call.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-call"
+
+#include "call.h"
+#include "util.h"
+
+#include
+
+
+enum {
+ PROP_0,
+ PROP_DBUS_PROXY,
+ PROP_DISPLAY_NAME,
+ PROP_ID,
+ PROP_STATE,
+ PROP_ENCRYPTED,
+ PROP_CAN_DTMF,
+ PROP_LAST_PROP = PROP_DISPLAY_NAME,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+
+typedef struct _PhoshCall {
+ GObject parent;
+
+ PhoshCallsDBusCallsCall *proxy; /* DBus proxy to a single call on for gnome-calls' DBus service */
+ GCancellable *cancel;
+
+ gboolean can_dtmf;
+} PhoshCall;
+
+
+static void phosh_call_cui_call_interface_init (CuiCallInterface *iface);
+G_DEFINE_TYPE_WITH_CODE (PhoshCall, phosh_call, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (CUI_TYPE_CALL,
+ phosh_call_cui_call_interface_init))
+
+
+static const char *
+phosh_call_get_id (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_val_if_fail (PHOSH_IS_CALL (call), NULL);
+ self = PHOSH_CALL (call);
+
+ return phosh_calls_dbus_calls_call_get_id (self->proxy);
+}
+
+
+static const char *
+phosh_call_get_display_name (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_val_if_fail (PHOSH_IS_CALL (call), NULL);
+ self = PHOSH_CALL (call);
+
+ return phosh_calls_dbus_calls_call_get_display_name (self->proxy);
+}
+
+
+static CuiCallState
+phosh_call_get_state (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_val_if_fail (PHOSH_IS_CALL (call), CUI_CALL_STATE_UNKNOWN);
+ self = PHOSH_CALL (call);
+
+ return phosh_calls_dbus_calls_call_get_state (self->proxy);
+}
+
+
+static gboolean
+phosh_call_get_encrypted (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_val_if_fail (PHOSH_IS_CALL (call), CUI_CALL_STATE_UNKNOWN);
+ self = PHOSH_CALL (call);
+
+ return phosh_calls_dbus_calls_call_get_encrypted (self->proxy);
+}
+
+
+static gboolean
+phosh_call_get_can_dtmf (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_val_if_fail (PHOSH_IS_CALL (call), CUI_CALL_STATE_UNKNOWN);
+ self = PHOSH_CALL (call);
+
+ return self->can_dtmf;
+}
+
+
+static void
+on_prop_changed (PhoshCall *self, GParamSpec *pspec)
+{
+ const char *name = g_param_spec_get_name (pspec);
+
+ /* Just forward any property changes, we fetch them from the DBus proxy anyway */
+ if (g_strcmp0 (name, "state") == 0 ||
+ g_strcmp0 (name, "encrypted") == 0 ||
+ g_strcmp0 (name, "id") == 0 ||
+ g_strcmp0 (name, "display-name") == 0) {
+ g_object_notify (G_OBJECT (self), name);
+ }
+}
+
+
+static void
+phosh_call_set_dbus_proxy (PhoshCall *self, PhoshCallsDBusCallsCall *proxy)
+{
+ self->proxy = g_object_ref (proxy);
+
+ g_object_connect (self->proxy,
+ "swapped-signal::notify::state", G_CALLBACK (on_prop_changed), self,
+ "swapped-signal::notify::encrypted", G_CALLBACK (on_prop_changed), self,
+ "swapped-signal::notify::id", G_CALLBACK (on_prop_changed), self,
+ "swapped-signal::notify::display-name", G_CALLBACK (on_prop_changed), self,
+ NULL);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DBUS_PROXY]);
+}
+
+
+static void
+phosh_call_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshCall *self = PHOSH_CALL (object);
+
+ switch (property_id) {
+ case PROP_DBUS_PROXY:
+ /* construct only */
+ phosh_call_set_dbus_proxy (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_call_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshCall *self = PHOSH_CALL (object);
+ CuiCall *iface = CUI_CALL (object);
+
+ switch (property_id) {
+ case PROP_DBUS_PROXY:
+ g_value_set_object (value, self->proxy);
+ break;
+ case PROP_ID:
+ g_value_set_string (value, phosh_call_get_id (iface));
+ break;
+ case PROP_DISPLAY_NAME:
+ g_value_set_string (value, phosh_call_get_display_name (iface));
+ break;
+ case PROP_STATE:
+ g_value_set_enum (value, phosh_call_get_state (iface));
+ break;
+ case PROP_ENCRYPTED:
+ g_value_set_boolean (value, phosh_call_get_encrypted (iface));
+ break;
+ case PROP_CAN_DTMF:
+ g_value_set_boolean (value, phosh_call_get_can_dtmf (iface));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_call_dispose (GObject *object)
+{
+ PhoshCall *self = PHOSH_CALL (object);
+
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+ g_signal_handlers_disconnect_by_data (self->proxy, self);
+ g_clear_object (&self->proxy);
+
+ G_OBJECT_CLASS (phosh_call_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_call_class_init (PhoshCallClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = phosh_call_dispose;
+ object_class->set_property = phosh_call_set_property;
+ object_class->get_property = phosh_call_get_property;
+
+ /**
+ * PhoshCall:dbus-proxy:
+ *
+ * The DBus proxy object to a call on gnome-calls DBus interface
+ */
+ props[PROP_DBUS_PROXY] = g_param_spec_object ("dbus-proxy",
+ "",
+ "",
+ PHOSH_CALLS_DBUS_TYPE_CALLS_CALL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ g_object_class_override_property (object_class,
+ PROP_DISPLAY_NAME,
+ "id");
+
+ g_object_class_override_property (object_class,
+ PROP_ID,
+ "display-name");
+
+ g_object_class_override_property (object_class,
+ PROP_STATE,
+ "state");
+
+ g_object_class_override_property (object_class,
+ PROP_ENCRYPTED,
+ "encrypted");
+
+ g_object_class_override_property (object_class,
+ PROP_CAN_DTMF,
+ "can-dtmf");
+}
+
+
+static void
+on_call_accept_finish (PhoshCallsDBusCallsCall *proxy,
+ GAsyncResult *res,
+ gpointer unused)
+{
+ g_autoptr (GError) err = NULL;
+
+ g_return_if_fail (PHOSH_CALLS_DBUS_IS_CALLS_CALL_PROXY (proxy));
+
+ if (!phosh_calls_dbus_calls_call_call_accept_finish (proxy, res, &err))
+ phosh_async_error_warn (err, "Failed to accept call %p", proxy);
+}
+
+
+static void
+phosh_call_accept (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_if_fail (PHOSH_IS_CALL (call));
+ self = PHOSH_CALL (call);
+
+ phosh_calls_dbus_calls_call_call_accept (self->proxy,
+ self->cancel,
+ (GAsyncReadyCallback) on_call_accept_finish,
+ NULL);
+}
+
+static void
+on_call_hangup_finish (PhoshCallsDBusCallsCall *proxy,
+ GAsyncResult *res,
+ gpointer unused)
+{
+ g_autoptr (GError) err = NULL;
+
+ g_return_if_fail (PHOSH_CALLS_DBUS_IS_CALLS_CALL_PROXY (proxy));
+
+ if (!phosh_calls_dbus_calls_call_call_hangup_finish (proxy, res, &err))
+ phosh_async_error_warn (err, "Failed to hangup call %p", proxy);
+}
+
+
+static void
+phosh_call_hang_up (CuiCall *call)
+{
+ PhoshCall *self;
+
+ g_return_if_fail (PHOSH_IS_CALL (call));
+ self = PHOSH_CALL (call);
+
+ phosh_calls_dbus_calls_call_call_hangup (self->proxy,
+ self->cancel,
+ (GAsyncReadyCallback) on_call_hangup_finish,
+ NULL);
+}
+
+
+static void
+phosh_call_send_dtmf (CuiCall *call, const char *dtmf)
+{
+ g_return_if_fail (PHOSH_IS_CALL (call));
+
+ /* TBD */
+}
+
+
+static void
+phosh_call_cui_call_interface_init (CuiCallInterface *iface)
+{
+ iface->get_id = phosh_call_get_id;
+ iface->get_display_name = phosh_call_get_display_name;
+ iface->get_state = phosh_call_get_state;
+ iface->get_encrypted = phosh_call_get_encrypted;
+ iface->get_can_dtmf = phosh_call_get_can_dtmf;
+
+ iface->accept = phosh_call_accept;
+ iface->hang_up = phosh_call_hang_up;
+ iface->send_dtmf = phosh_call_send_dtmf;
+}
+
+
+static void
+phosh_call_init (PhoshCall *self)
+{
+ self->cancel = g_cancellable_new ();
+
+ /* TODO: once DBus handles it */
+ self->can_dtmf = FALSE;
+}
+
+
+PhoshCall *
+phosh_call_new (PhoshCallsDBusCallsCall *proxy)
+{
+ return g_object_new (PHOSH_TYPE_CALL,
+ "dbus-proxy", proxy,
+ NULL);
+}
diff -Nru phosh-0.8.0/src/call.h phosh-0.13.1/src/call.h
--- phosh-0.8.0/src/call.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/call.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#pragma once
+
+#include "calls-dbus.h"
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_CALL (phosh_call_get_type())
+
+G_DECLARE_FINAL_TYPE (PhoshCall, phosh_call, PHOSH, CALL, GObject)
+
+PhoshCall * phosh_call_new (PhoshCallsDBusCallsCall *proxy);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/calls-manager.c phosh-0.13.1/src/calls-manager.c
--- phosh-0.8.0/src/calls-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/calls-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-calls-manager"
+
+#include "config.h"
+
+#include "call.h"
+#include "calls-manager.h"
+#include "shell.h"
+#include "util.h"
+#include "dbus/calls-dbus.h"
+
+#define BUS_NAME "org.gnome.Calls"
+#define OBJECT_PATH "/org/gnome/Calls"
+#define OBJECT_PATHS_CALLS_PREFIX OBJECT_PATH "/Call/"
+
+/**
+ * SECTION:calls-manager
+ * @short_description: Track ongoing phone calls
+ * @Title: PhoshCallsManager
+ *
+ * #PhoshCallsManager tracks on going calls on the org.gnome.Calls DBus
+ * interface and allows interaction with them by wrapping the
+ * #PhoshCallsDBusCallsCall proxies in #PhoshCall so all DBus and
+ * ObjectManager related logic stays local within #PhoshCallsManager.
+ */
+
+enum {
+ PROP_0,
+ PROP_PRESENT,
+ PROP_ACTIVE_CALL,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+
+enum {
+ CALL_INBOUND,
+ CALL_REMOVED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+
+struct _PhoshCallsManager {
+ PhoshManager parent;
+
+ gboolean present;
+ gboolean incoming;
+ char *active_call;
+
+ PhoshCallsDBusObjectManagerClient *om_client;
+ GCancellable *cancel;
+ GHashTable *calls;
+};
+G_DEFINE_TYPE (PhoshCallsManager, phosh_calls_manager, PHOSH_TYPE_MANAGER);
+
+
+static gboolean
+is_active (PhoshCallState state)
+{
+ gboolean ret = FALSE;
+
+ if (state == PHOSH_CALL_STATE_ACTIVE ||
+ state == PHOSH_CALL_STATE_ALERTING ||
+ state == PHOSH_CALL_STATE_DIALING)
+ ret = TRUE;
+
+ return ret;
+}
+
+
+static void
+on_call_state_changed (PhoshCallsManager *self,
+ GParamSpec *pspec,
+ PhoshCallsDBusCallsCall *proxy)
+{
+ const char *path;
+ PhoshCallState state;
+ PhoshCall *call;
+
+ g_return_if_fail (PHOSH_IS_CALLS_MANAGER (self));
+ g_return_if_fail (PHOSH_CALLS_DBUS_IS_CALLS_CALL (proxy));
+
+ call = g_object_get_data (G_OBJECT (proxy), "call");
+ g_return_if_fail (call);
+
+ path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (proxy));
+ state = phosh_calls_dbus_calls_call_get_state (proxy);
+
+ g_debug ("Call %s, state %d", path, state);
+ if (g_strcmp0 (path, self->active_call) == 0) {
+ /* current active call became inactive> */
+ if (!is_active (state)) {
+ g_debug ("No active call, was %s", path);
+ g_clear_pointer (&self->active_call, g_free);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVE_CALL]);
+ /* TODO: pick new active call from list once calls supports multiple active calls */
+ }
+ return;
+ }
+
+ if (!is_active (state))
+ return;
+
+ /* New active call */
+ g_free (self->active_call);
+ self->active_call = g_strdup (path);
+ g_debug ("New active call %s", path);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVE_CALL]);
+}
+
+
+static void
+on_call_proxy_new_for_bus_finish (GObject *source_object,
+ GAsyncResult *res,
+ gpointer *data)
+{
+ const char *path;
+ gboolean inbound;
+ PhoshCallsManager *self;
+ g_autoptr (PhoshCallsDBusCallsCall) proxy = NULL;
+ g_autoptr (PhoshCall) call = NULL;
+ g_autoptr (GError) err = NULL;
+
+ proxy = phosh_calls_dbus_calls_call_proxy_new_for_bus_finish (res, &err);
+ if (!proxy) {
+ phosh_async_error_warn (err, "Failed to get call proxy");
+ return;
+ }
+
+ self = PHOSH_CALLS_MANAGER (data);
+ path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (proxy));
+
+ /* Wrap DBus proxy in PhoshCall */
+ call = phosh_call_new (proxy);
+ g_object_set_data (G_OBJECT (proxy), "call", call);
+
+ if (g_hash_table_contains (self->calls, path))
+ g_critical ("Already got a call with path %s", path);
+ else
+ g_hash_table_insert (self->calls, g_strdup (path), g_steal_pointer (&call));
+
+
+ g_signal_connect_swapped (proxy,
+ "notify::state",
+ G_CALLBACK (on_call_state_changed),
+ self);
+ on_call_state_changed (self, NULL, proxy);
+
+ inbound = phosh_calls_dbus_calls_call_get_inbound (proxy);
+ g_debug ("Added call %s, inbound: %d", path, inbound);
+
+ if (inbound)
+ g_signal_emit (self, signals[CALL_INBOUND], 0, path);
+}
+
+
+static void
+on_call_obj_added (PhoshCallsManager *self,
+ GDBusObject *object)
+{
+ const char *path;
+
+ g_return_if_fail (PHOSH_IS_CALLS_MANAGER (self));
+
+ path = g_dbus_object_get_object_path (object);
+ g_debug ("New call obj at %s", path);
+ if (!g_str_has_prefix (path, OBJECT_PATHS_CALLS_PREFIX))
+ return;
+
+ phosh_calls_dbus_calls_call_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ BUS_NAME,
+ path,
+ self->cancel,
+ (GAsyncReadyCallback) on_call_proxy_new_for_bus_finish,
+ self);
+}
+
+
+static void
+on_call_obj_removed (PhoshCallsManager *self,
+ GDBusObject *object)
+{
+ const char *path;
+
+ g_return_if_fail (PHOSH_IS_CALLS_MANAGER (self));
+
+ path = g_dbus_object_get_object_path (object);
+ g_debug ("Call obj at %s gone", path);
+ if (!g_str_has_prefix (path, OBJECT_PATHS_CALLS_PREFIX))
+ return;
+
+ if (g_strcmp0 (path, self->active_call) == 0) {
+ g_clear_pointer (&self->active_call, g_free);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVE_CALL]);
+ /* TODO: pick new active call from list once calls supports multiple active calls */
+ }
+
+ g_debug ("Removed call %s", path);
+ g_signal_emit (self, signals[CALL_REMOVED], 0, path);
+ /* This disposes the call object and hence the proxy */
+ g_return_if_fail (g_hash_table_remove (self->calls, path));
+}
+
+
+static void
+phosh_calls_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshCallsManager *self = PHOSH_CALLS_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_PRESENT:
+ g_value_set_boolean (value, self->present);
+ break;
+ case PROP_ACTIVE_CALL:
+ g_value_set_string (value, self->active_call);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+on_name_owner_changed (PhoshCallsManager *self,
+ GParamSpec *pspec,
+ GDBusObjectManagerClient *om)
+{
+ g_autofree char *owner = NULL;
+ gboolean present;
+
+ g_return_if_fail (PHOSH_IS_CALLS_MANAGER (self));
+ g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (om));
+
+ owner = g_dbus_object_manager_client_get_name_owner (om);
+ present = owner ? TRUE : FALSE;
+
+ if (present) {
+ g_autolist (GDBusObject) objs = g_dbus_object_manager_get_objects (
+ G_DBUS_OBJECT_MANAGER (self->om_client));
+
+ /* Catch up on ongoing calls */
+ for (GList *elem = objs; elem; elem = elem->next) {
+ on_call_obj_added (self, elem->data);
+ }
+ } /* else {} is not necessary since we get object-removed signals
+ * when name owner quits
+ */
+
+ if (present != self->present) {
+ self->present = present;
+ g_debug ("Calls present: %d", self->present);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PRESENT]);
+ }
+}
+
+
+static void
+on_om_new_for_bus_finish (GObject *source_object,
+ GAsyncResult *res,
+ gpointer data)
+{
+ g_autoptr (GError) err = NULL;
+ PhoshCallsManager *self;
+ GDBusObjectManager *om;
+ GDBusObjectManagerClient *om_client;
+
+ om = phosh_calls_dbus_object_manager_client_new_for_bus_finish (res, &err);
+ if (om == NULL) {
+ g_message ("Failed to get calls object manager client: %s", err->message);
+ return;
+ }
+
+ self = PHOSH_CALLS_MANAGER (data);
+ self->om_client = PHOSH_CALLS_DBUS_OBJECT_MANAGER_CLIENT (om);
+ om_client = G_DBUS_OBJECT_MANAGER_CLIENT (om);
+
+ g_signal_connect_object (self->om_client,
+ "notify::name-owner",
+ G_CALLBACK (on_name_owner_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ on_name_owner_changed (self, NULL, G_DBUS_OBJECT_MANAGER_CLIENT (om));
+
+ g_signal_connect_object (self->om_client,
+ "object-added",
+ G_CALLBACK (on_call_obj_added),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->om_client,
+ "object-removed",
+ G_CALLBACK (on_call_obj_removed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_debug ("Calls manager initialized for name %s at %s",
+ g_dbus_object_manager_client_get_name (om_client),
+ g_dbus_object_manager_get_object_path (om));
+}
+
+
+static void
+phosh_calls_manager_idle_init (PhoshManager *manager)
+{
+ PhoshCallsManager *self = PHOSH_CALLS_MANAGER (manager);
+
+ phosh_calls_dbus_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
+ BUS_NAME,
+ OBJECT_PATH,
+ self->cancel,
+ on_om_new_for_bus_finish,
+ self);
+}
+
+
+static void
+phosh_calls_manager_dispose (GObject *object)
+{
+ PhoshCallsManager *self = PHOSH_CALLS_MANAGER (object);
+
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+ g_clear_object (&self->om_client);
+ g_clear_pointer (&self->calls, g_hash_table_unref);
+ g_clear_pointer (&self->active_call, g_free);
+
+ G_OBJECT_CLASS (phosh_calls_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_calls_manager_class_init (PhoshCallsManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshManagerClass *manager_class = PHOSH_MANAGER_CLASS (klass);
+
+ object_class->get_property = phosh_calls_manager_get_property;
+ object_class->dispose = phosh_calls_manager_dispose;
+
+ manager_class->idle_init = phosh_calls_manager_idle_init;
+
+ /**
+ * PhoshCallsManager:present:
+ *
+ * Whether the call interface is present on the bus
+ */
+ props[PROP_PRESENT] =
+ g_param_spec_boolean ("present",
+ "",
+ "",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PhoshCallsManager:active-call:
+ *
+ * The currently active call
+ */
+ props[PROP_ACTIVE_CALL] =
+ g_param_spec_string ("active-call",
+ "",
+ "",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ signals[CALL_INBOUND] = g_signal_new ("call-inbound",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[CALL_REMOVED] = g_signal_new ("call-removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+}
+
+
+static void
+phosh_calls_manager_init (PhoshCallsManager *self)
+{
+ self->calls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ self->cancel = g_cancellable_new ();
+}
+
+
+PhoshCallsManager *
+phosh_calls_manager_new (void)
+{
+ return g_object_new (PHOSH_TYPE_CALLS_MANAGER, NULL);
+}
+
+
+gboolean
+phosh_calls_manager_get_present (PhoshCallsManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_CALLS_MANAGER (self), FALSE);
+
+ return self->present;
+}
+
+
+int
+phosh_calls_manager_get_incoming (PhoshCallsManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_CALLS_MANAGER (self), FALSE);
+
+ return self->incoming;
+}
+
+
+const char *
+phosh_calls_manager_get_active_call_handle (PhoshCallsManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_CALLS_MANAGER (self), NULL);
+
+ return self->active_call;
+}
+
+
+PhoshCall *
+phosh_calls_manager_get_call (PhoshCallsManager *self, const char *handle)
+{
+ g_return_val_if_fail (PHOSH_IS_CALLS_MANAGER (self), NULL);
+
+ return g_hash_table_lookup (self->calls, handle);
+}
diff -Nru phosh-0.8.0/src/calls-manager.h phosh-0.13.1/src/calls-manager.h
--- phosh-0.8.0/src/calls-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/calls-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "call.h"
+#include "manager.h"
+
+#include
+
+G_BEGIN_DECLS
+
+/**
+ * PhoshCallState:
+ *
+ * The call state. Must match call's CallsCallState.
+ */
+typedef enum
+{
+ /*< private >*/
+ PHOSH_CALL_STATE_ACTIVE = 1,
+ PHOSH_CALL_STATE_HELD,
+ PHOSH_CALL_STATE_DIALING,
+ PHOSH_CALL_STATE_ALERTING,
+ PHOSH_CALL_STATE_INCOMING,
+ PHOSH_CALL_STATE_WAITING,
+ PHOSH_CALL_STATE_DISCONNECTED
+} PhoshCallState;
+
+
+#define PHOSH_TYPE_CALLS_MANAGER (phosh_calls_manager_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshCallsManager, phosh_calls_manager, PHOSH, CALLS_MANAGER, PhoshManager)
+
+PhoshCallsManager *phosh_calls_manager_new (void);
+gboolean phosh_calls_manager_get_present (PhoshCallsManager *self);
+gboolean phosh_calls_manager_get_incoming (PhoshCallsManager *self);
+const char *phosh_calls_manager_get_active_call_handle (PhoshCallsManager *self);
+PhoshCall *phosh_calls_manager_get_call (PhoshCallsManager *self, const char *handle);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/connectivity-info.c phosh-0.13.1/src/connectivity-info.c
--- phosh-0.8.0/src/connectivity-info.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/connectivity-info.c 2021-08-31 09:15:52.000000000 +0000
@@ -11,6 +11,7 @@
#include "config.h"
#include "connectivity-info.h"
+#include "util.h"
#include
@@ -38,6 +39,7 @@
gboolean connectivity;
NMClient *nmclient;
+ GCancellable *cancel;
};
G_DEFINE_TYPE (PhoshConnectivityInfo, phosh_connectivity_info, PHOSH_TYPE_STATUS_ICON);
@@ -112,15 +114,17 @@
on_nm_client_ready (GObject *obj, GAsyncResult *res, PhoshConnectivityInfo *self)
{
g_autoptr (GError) err = NULL;
+ NMClient *nmclient;
- g_return_if_fail (PHOSH_IS_CONNECTIVITY_INFO (self));
-
- self->nmclient = nm_client_new_finish (res, &err);
- if (err) {
- g_warning ("Failed to init NM: %s", err->message);
+ nmclient = nm_client_new_finish (res, &err);
+ if (!nmclient) {
+ phosh_async_error_warn (err, "Failed to init NM");
return;
}
+ g_return_if_fail (PHOSH_IS_CONNECTIVITY_INFO (self));
+ self->nmclient = nmclient;
+
g_return_if_fail (NM_IS_CLIENT (self->nmclient));
g_signal_connect_swapped (self->nmclient, "notify::connectivity",
@@ -137,7 +141,8 @@
G_OBJECT_CLASS (phosh_connectivity_info_parent_class)->constructed (object);
- nm_client_new_async (NULL, (GAsyncReadyCallback)on_nm_client_ready, self);
+ self->cancel = g_cancellable_new ();
+ nm_client_new_async (self->cancel, (GAsyncReadyCallback)on_nm_client_ready, self);
}
@@ -146,6 +151,9 @@
{
PhoshConnectivityInfo *self = PHOSH_CONNECTIVITY_INFO (object);
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
g_clear_object (&self->nmclient);
G_OBJECT_CLASS (phosh_connectivity_info_parent_class)->dispose (object);
@@ -156,11 +164,14 @@
phosh_connectivity_info_class_init (PhoshConnectivityInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_connectivity_info_constructed;
object_class->dispose = phosh_connectivity_info_dispose;
object_class->get_property = phosh_connectivity_info_get_property;
+ gtk_widget_class_set_css_name (widget_class, "phosh-connectivity-info");
+
props[PROP_CONNECTIVITY] =
g_param_spec_boolean ("connectivity",
"Connectivity",
diff -Nru phosh-0.8.0/src/dbus/meson.build phosh-0.13.1/src/dbus/meson.build
--- phosh-0.8.0/src/dbus/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/dbus/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -6,6 +6,11 @@
'net.hadess.SensorProxy.xml',
interface_prefix: 'net.hadess',
namespace: 'PhoshDBus')
+# Geoclue
+generated_dbus_sources += gnome.gdbus_codegen('geoclue-manager-dbus',
+ 'org.freedesktop.GeoClue2.Manager.xml',
+ interface_prefix: 'org.freedesktop.GeoClue2',
+ namespace: 'PhoshGeoClueDBus')
# org.freedesktop.hostname1
generated_dbus_sources += gnome.gdbus_codegen('hostname1-dbus',
'org.freedesktop.hostname1.xml',
@@ -21,11 +26,17 @@
'org.freedesktop.login1.Manager.xml',
interface_prefix: 'org.freedesktop.login1',
namespace: 'PhoshLogin1ManagerDBus')
-# org.freedesktop.UPower.Torch
-generated_dbus_sources += gnome.gdbus_codegen('upower-torch-dbus',
- 'org.freedesktop.UPower.Torch.xml',
- interface_prefix: 'org.freedesktop.UPower',
- namespace: 'PhoshUPowerDBus')
+
+generated_dbus_sources += gnome.gdbus_codegen('phosh-wwan-mm-dbus',
+ 'org.freedesktop.ModemManager1.xml',
+ namespace: 'Phosh_MM_DBus',
+ interface_prefix: 'org.freedesktop.ModemManager1',
+ object_manager: true)
+generated_dbus_sources += gnome.gdbus_codegen('calls-dbus',
+ 'org.gnome.Calls.Call.xml',
+ object_manager: true,
+ interface_prefix: 'org.gnome',
+ namespace: 'PhoshCallsDBus')
# org.gnome.SessionManager
generated_dbus_sources += gnome.gdbus_codegen('gnome-session-dbus',
'org.gnome.SessionManager.xml',
@@ -52,7 +63,21 @@
interface_prefix: 'org.mpris',
namespace: 'PhoshMprisDBus')
+generated_dbus_sources += gnome.gdbus_codegen('phosh-wwan-ofono-dbus',
+ 'org.ofono.xml',
+ namespace: 'PhoshOfonoDBus',
+ interface_prefix: 'org.ofono')
+
+generated_dbus_sources += gnome.gdbus_codegen('phosh-osk0-dbus',
+ 'sm.puri.OSK0.xml',
+ namespace: 'PhoshOsk0')
+
# DBus server protocols
+generated_dbus_sources += gnome.gdbus_codegen('geoclue-agent-dbus',
+ 'org.freedesktop.GeoClue2.Agent.xml',
+ interface_prefix: 'org.freedesktop.Agent',
+ namespace: 'PhoshGeoClueDBus')
+
generated_dbus_sources += gnome.gdbus_codegen('notify-dbus',
'org.freedesktop.Notifications.xml',
interface_prefix: 'org.freedesktop',
@@ -63,13 +88,33 @@
interface_prefix: 'org.gnome',
namespace: 'PhoshGnomeShellDBus')
+generated_dbus_sources += gnome.gdbus_codegen('phosh-display-dbus',
+ 'org.gnome.Mutter.DisplayConfig.xml',
+ interface_prefix: 'org.gnome.Mutter',
+ namespace: 'PhoshDBus')
+
generated_dbus_sources += gnome.gdbus_codegen('phosh-idle-dbus',
- 'org.gnome.Mutter.IdleMonitor.xml',
- interface_prefix: 'org.gnome.Mutter',
- object_manager: true,
- namespace: 'PhoshIdleDBus')
+ 'org.gnome.Mutter.IdleMonitor.xml',
+ interface_prefix: 'org.gnome.Mutter',
+ object_manager: true,
+ namespace: 'PhoshIdleDBus')
generated_dbus_sources += gnome.gdbus_codegen('phosh-screen-saver-dbus',
'org.gnome.ScreenSaver.xml',
interface_prefix: 'org.gnome',
namespace: 'PhoshScreenSaverDBus')
+
+generated_dbus_sources += gnome.gdbus_codegen('phosh-screenshot-dbus',
+ 'org.gnome.Shell.Screenshot.xml',
+ interface_prefix: 'org.gnome.Shell',
+ namespace: 'PhoshDBus')
+
+generated_dbus_sources += gnome.gdbus_codegen('phosh-end-session-dialog-dbus',
+ 'org.gnome.SessionManager.EndSessionDialog.xml',
+ interface_prefix: 'org.gnome.SessionManager',
+ namespace: 'PhoshDBus')
+
+generated_dbus_sources += gnome.gdbus_codegen('phosh-gtk-mountoperation-dbus',
+ 'org.Gtk.MountOperationHandler.xml',
+ interface_prefix: 'org.Gtk',
+ namespace: 'PhoshDBus')
diff -Nru phosh-0.8.0/src/dbus/org.freedesktop.GeoClue2.Agent.xml phosh-0.13.1/src/dbus/org.freedesktop.GeoClue2.Agent.xml
--- phosh-0.8.0/src/dbus/org.freedesktop.GeoClue2.Agent.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.freedesktop.GeoClue2.Agent.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.freedesktop.GeoClue2.Manager.xml phosh-0.13.1/src/dbus/org.freedesktop.GeoClue2.Manager.xml
--- phosh-0.8.0/src/dbus/org.freedesktop.GeoClue2.Manager.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.freedesktop.GeoClue2.Manager.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.freedesktop.login1.Session.xml phosh-0.13.1/src/dbus/org.freedesktop.login1.Session.xml
--- phosh-0.8.0/src/dbus/org.freedesktop.login1.Session.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.freedesktop.login1.Session.xml 2021-08-31 09:15:52.000000000 +0000
@@ -13,6 +13,12 @@
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.freedesktop.ModemManager1.xml phosh-0.13.1/src/dbus/org.freedesktop.ModemManager1.xml
--- phosh-0.8.0/src/dbus/org.freedesktop.ModemManager1.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.freedesktop.ModemManager1.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.freedesktop.UPower.Torch.xml phosh-0.13.1/src/dbus/org.freedesktop.UPower.Torch.xml
--- phosh-0.8.0/src/dbus/org.freedesktop.UPower.Torch.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.freedesktop.UPower.Torch.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,148 +0,0 @@
-
-]>
-
-
-
-
-
- org.freedesktop.UPower.Torch is a DBus interface implemented
- by UPower.
- It allows a torch (if present) to be controlled.
-
-
-
-
-
-
-
-
-
- The maximum value of the torch brightness.
-
-
-
-
-
-
- Get the maximum brightness level for the torch.
-
-
-
- if an error occured while getting the maximum brightness
-
-
-
-
-
-
-
-
-
- The current value of the torch brightness.
-
-
-
-
-
-
- Get the brightness level of the torch.
-
-
-
- if an error occured while getting the brightness
-
-
-
-
-
-
-
-
-
- The value to set the torch brightness.
-
-
-
-
-
-
- Set the brightness level of the torch.
-
-
-
- if an error occured while setting the brightness
-
-
-
-
-
-
-
-
-
- The new brightness value of the torch.
-
-
-
-
-
-
- The torch brightness level has changed.
-
-
-
-
-
-
-
-
-
- The new brightness value of the torch.
-
-
-
-
-
-
- Source of the torch brightness change, either
- "external" if SetBrightness was called, or "internal" if the
- hardware changed the keyboard brightness itself.
-
-
-
-
-
-
- The torch brightness level has changed including
- information about the source of the change.
-
-
-
-
-
-
-
-
-
- The maximum value of the torch brightness.
-
-
-
-
-
-
-
-
-
- The current value of the torch brightness.
-
-
-
-
-
-
-
-
diff -Nru phosh-0.8.0/src/dbus/org.gnome.Calls.Call.xml phosh-0.13.1/src/dbus/org.gnome.Calls.Call.xml
--- phosh-0.8.0/src/dbus/org.gnome.Calls.Call.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.gnome.Calls.Call.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The Id identifying the call, e.g. a phone number
+
+
+
+
+
+
+ The DisplayName of the calling party, e.g. from address book
+
+
+
+
+
+
+ The protocol used for this call
+
+
+
+
+
+
+ Whether the call is encrypted. This does not indicate anything about the
+ type of encryption being used.
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.gnome.Mutter.DisplayConfig.xml phosh-0.13.1/src/dbus/org.gnome.Mutter.DisplayConfig.xml
--- phosh-0.8.0/src/dbus/org.gnome.Mutter.DisplayConfig.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.gnome.Mutter.DisplayConfig.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,459 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.gnome.SessionManager.EndSessionDialog.xml phosh-0.13.1/src/dbus/org.gnome.SessionManager.EndSessionDialog.xml
--- phosh-0.8.0/src/dbus/org.gnome.SessionManager.EndSessionDialog.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.gnome.SessionManager.EndSessionDialog.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+ The type of dialog to show.
+ 0 for logout, 1 for shutdown, 2 for restart, 3 for hibernate,
+ 4 for suspend and 5 hybrid sleep.
+
+
+
+
+
+
+ Timestamp of the user-initiated event which triggered
+ the call, or 0 if the call was not triggered by an event.
+
+
+
+
+
+
+ The number of seconds which the dialog should stay open
+ before automatic action is taken.
+
+
+
+
+
+
+ The object paths of all inhibitors that are registered
+ for the action.
+
+
+
+
+
+ This function opens a dialog which asks the user for confirmation
+ of a logout, poweroff or reboot action. The dialog has a timeout
+ after which the action is automatically taken, and it should show
+ the inhibitors to the user.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.gnome.Shell.Screenshot.xml phosh-0.13.1/src/dbus/org.gnome.Shell.Screenshot.xml
--- phosh-0.8.0/src/dbus/org.gnome.Shell.Screenshot.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.gnome.Shell.Screenshot.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.gnome.Shell.xml phosh-0.13.1/src/dbus/org.gnome.Shell.xml
--- phosh-0.8.0/src/dbus/org.gnome.Shell.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.gnome.Shell.xml 2021-08-31 09:15:52.000000000 +0000
@@ -25,6 +25,9 @@
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.Gtk.MountOperationHandler.xml phosh-0.13.1/src/dbus/org.Gtk.MountOperationHandler.xml
--- phosh-0.8.0/src/dbus/org.Gtk.MountOperationHandler.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.Gtk.MountOperationHandler.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/org.ofono.xml phosh-0.13.1/src/dbus/org.ofono.xml
--- phosh-0.8.0/src/dbus/org.ofono.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/org.ofono.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/dbus/sm.puri.OSK0.xml phosh-0.13.1/src/dbus/sm.puri.OSK0.xml
--- phosh-0.8.0/src/dbus/sm.puri.OSK0.xml 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/dbus/sm.puri.OSK0.xml 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Switch keyboard visibility
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/docked-info.c phosh-0.13.1/src/docked-info.c
--- phosh-0.8.0/src/docked-info.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/docked-info.c 2021-08-31 09:15:52.000000000 +0000
@@ -101,9 +101,11 @@
}
-static gboolean
-on_idle (PhoshDockedInfo *self)
+static void
+phosh_docked_info_idle_init (PhoshStatusIcon *icon)
{
+ PhoshDockedInfo *self = PHOSH_DOCKED_INFO (icon);
+
g_object_bind_property (self->manager, "icon-name", self, "icon-name",
G_BINDING_SYNC_CREATE);
@@ -120,8 +122,6 @@
G_CALLBACK (on_docked_mode_enabled),
self);
on_docked_mode_enabled (self, NULL, self->manager);
-
- return FALSE;
}
@@ -140,8 +140,6 @@
g_warning ("Failed to get docked manager");
return;
}
-
- g_idle_add ((GSourceFunc) on_idle, self);
}
@@ -163,11 +161,17 @@
phosh_docked_info_class_init (PhoshDockedInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshStatusIconClass *status_icon_class = PHOSH_STATUS_ICON_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_docked_info_constructed;
object_class->dispose = phosh_docked_info_dispose;
object_class->get_property = phosh_docked_info_get_property;
+ status_icon_class->idle_init = phosh_docked_info_idle_init;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-docked-info");
+
props[PROP_ENABLED] =
g_param_spec_boolean ("enabled",
"enabled",
diff -Nru phosh-0.8.0/src/docked-manager.c phosh-0.13.1/src/docked-manager.c
--- phosh-0.8.0/src/docked-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/docked-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -276,6 +276,7 @@
const gchar *icon_name;
g_return_if_fail (PHOSH_IS_DOCKED_MANAGER (self));
+ g_return_if_fail ((enable && self->can_dock) || !enable);
if (self->enabled == enable)
return;
diff -Nru phosh-0.8.0/src/end-session-dialog.c phosh-0.13.1/src/end-session-dialog.c
--- phosh-0.8.0/src/end-session-dialog.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/end-session-dialog.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,557 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Parts taken from gnome-flashback which is:
+ *
+ * Copyright (C) 2008 William Jon McCann
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-end-session-dialog"
+
+#include "config.h"
+#include "end-session-dialog.h"
+
+#include
+#include
+
+
+/**
+ * SECTION:end-session-dialog
+ * @short_description: A system modal prompt to authorize applications
+ * @Title: PhoshEndSessionDialog
+ *
+ * The #PhoshEndSessionDialog is used to confirm/decline the end of the session
+ * and is spawned by the #PhoshSessionManager.
+ */
+
+#define SYNC_DBUS_TIMEOUT 500
+
+enum {
+ CLOSED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+
+enum {
+ PROP_0,
+ PROP_ACTION,
+ PROP_TIMEOUT,
+ PROP_INHIBITOR_PATHS,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+static void end_session_dialog_update (PhoshEndSessionDialog *self);
+
+typedef struct _PhoshEndSessionDialog {
+ PhoshSystemModalDialog parent;
+
+ int action;
+ gboolean action_confirmed;
+ int timeout;
+ int timeout_id;
+ GStrv inhibitor_paths;
+
+ GtkWidget *lbl_subtitle;
+ GtkWidget *lbl_warn;
+ GtkWidget *listbox;
+ GtkWidget *btn_confirm;
+ GtkWidget *btn_cancel;
+
+} PhoshEndSessionDialog;
+
+
+G_DEFINE_TYPE (PhoshEndSessionDialog, phosh_end_session_dialog, PHOSH_TYPE_SYSTEM_MODAL_DIALOG)
+
+static gboolean
+is_inhibited (PhoshEndSessionDialog *self)
+{
+ return (self->inhibitor_paths && g_strv_length (self->inhibitor_paths));
+}
+
+
+static char *
+get_user_name (void)
+{
+ char *name;
+
+ name = g_locale_to_utf8 (g_get_real_name (), -1, NULL, NULL, NULL);
+
+ if (g_strcmp0 (name, "Unknown") == 0 || g_strcmp0 (name, "") == 0) {
+ g_free (name);
+ name = g_locale_to_utf8 (g_get_user_name (), -1, NULL, NULL, NULL);
+ }
+
+ if (!name)
+ name = g_strdup (g_get_user_name ());
+
+ return name;
+}
+
+
+static void
+on_btn_confirm_clicked (PhoshEndSessionDialog *self, GtkButton *btn)
+{
+ self->action_confirmed = TRUE;
+
+ g_signal_emit (self, signals[CLOSED], 0);
+}
+
+
+static void
+on_dialog_canceled (PhoshEndSessionDialog *self)
+{
+ g_return_if_fail (PHOSH_IS_END_SESSION_DIALOG (self));
+
+ g_signal_emit (self, signals[CLOSED], 0);
+}
+
+
+static gboolean
+end_session_dialog_timeout (gpointer data)
+{
+ PhoshEndSessionDialog *self = PHOSH_END_SESSION_DIALOG (data);
+
+ if (self->timeout == 0) {
+ on_btn_confirm_clicked (self, GTK_BUTTON (self->btn_confirm));
+ self->timeout_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ end_session_dialog_update (self);
+ self->timeout--;
+
+ return G_SOURCE_CONTINUE;
+}
+
+
+static void
+maybe_start_timer (PhoshEndSessionDialog *self)
+{
+ if (self->timeout_id == 0 && self->timeout) {
+ self->timeout_id = g_timeout_add_seconds (1, end_session_dialog_timeout, self);
+ g_source_set_name_by_id (self->timeout_id, "[phosh] end_session_dialog_timeout");
+ }
+}
+
+
+static void
+end_session_dialog_update (PhoshEndSessionDialog *self)
+{
+ gboolean inhibited;
+ gint seconds;
+ const char *title;
+ g_autofree char *description = NULL;
+ g_autofree char *user_name = NULL;
+
+ maybe_start_timer (self);
+ seconds = self->timeout;
+ inhibited = is_inhibited (self);
+
+ g_debug ("Action: %d, seconds: %d, inhibit: %d",
+ self->action, seconds, inhibited);
+
+ switch (self->action) {
+ case PHOSH_END_SESSION_ACTION_LOGOUT:
+ title = _("Log Out");
+
+ user_name = get_user_name ();
+ description = g_strdup_printf (ngettext ("%s will be logged out automatically in %d second.",
+ "%s will be logged out automatically in %d seconds.",
+ seconds),
+ user_name, seconds);
+ break;
+ case PHOSH_END_SESSION_ACTION_SHUTDOWN:
+ title = _("Power Off");
+ description = g_strdup_printf (ngettext ("The system will power off automatically in %d second.",
+ "The system will power off automatically in %d seconds.",
+ seconds),
+ seconds);
+ break;
+ case PHOSH_END_SESSION_ACTION_REBOOT:
+ title = _("Restart");
+ description = g_strdup_printf (ngettext ("The system will restart automatically in %d second.",
+ "The system will restart automatically in %d seconds.",
+ seconds),
+ seconds);
+ break;
+ default:
+ g_return_if_reached ();
+ }
+
+ phosh_system_modal_dialog_set_title (PHOSH_SYSTEM_MODAL_DIALOG (self), title);
+
+ gtk_label_set_label (GTK_LABEL (self->lbl_subtitle), description);
+ gtk_button_set_label (GTK_BUTTON (self->btn_confirm), title);
+}
+
+
+static char *
+inhibitor_get_app_id (GDBusProxy *proxy)
+{
+ g_autoptr (GError) error = NULL;
+ g_autoptr (GVariant) res = NULL;
+ char *app_id;
+
+ res = g_dbus_proxy_call_sync (proxy, "GetAppId", NULL,
+ 0, SYNC_DBUS_TIMEOUT, NULL, &error);
+ if (!res) {
+ g_warning ("Failed to get Inhibitor app id: %s", error->message);
+ return NULL;
+ }
+ g_variant_get (res, "(s)", &app_id);
+
+ return app_id;
+}
+
+
+static char *
+inhibitor_get_reason (GDBusProxy *proxy)
+{
+ g_autoptr (GError) error = NULL;
+ g_autoptr (GVariant) res = NULL;
+ char *reason;
+
+ res = g_dbus_proxy_call_sync (proxy, "GetReason", NULL,
+ 0, SYNC_DBUS_TIMEOUT, NULL, &error);
+ if (!res) {
+ g_warning ("Failed to get inhibit reason: %s", error->message);
+ return NULL;
+ }
+ g_variant_get (res, "(s)", &reason);
+
+ return reason;
+}
+
+
+static void
+add_inhibitor (PhoshEndSessionDialog *self,
+ GDBusProxy *inhibitor)
+{
+ g_autofree char *app_id = NULL;
+ g_autofree char *reason = NULL;
+ g_autofree char *desktop_file = NULL;
+
+ g_autoptr (GDesktopAppInfo) app_info = NULL;
+ const char *icon_name = NULL;
+ const char *name = NULL;
+ GIcon *icon = NULL;
+ GtkWidget *box;
+ GtkWidget *box_text;
+ GtkWidget *label;
+ GtkWidget *lbl_reason;
+ GtkWidget *img;
+
+ app_id = inhibitor_get_app_id (inhibitor);
+ reason = inhibitor_get_reason (inhibitor);
+
+ if (app_id) {
+ if (g_str_has_suffix (app_id, ".desktop")) {
+ app_info = g_desktop_app_info_new (app_id);
+ } else {
+ desktop_file = g_strdup_printf ("%s.desktop", app_id);
+ app_info = g_desktop_app_info_new (desktop_file);
+ }
+ }
+
+ if (app_info) {
+ icon = g_app_info_get_icon (G_APP_INFO (app_info));
+ name = g_app_info_get_display_name (G_APP_INFO (app_info));
+ }
+
+ if (!name)
+ name = _("Unknown application");
+
+ if (!icon)
+ icon_name = "app-icon-unknown";
+
+ img = g_object_new (GTK_TYPE_IMAGE,
+ "visible", TRUE,
+ "can-focus", FALSE,
+ "gicon", icon,
+ "halign", GTK_ALIGN_START,
+ "pixel_size", 64,
+ NULL);
+ if (!icon)
+ g_object_set (img, "icon-name", icon_name, NULL);
+
+ box_text = g_object_new (GTK_TYPE_BOX,
+ "visible", TRUE,
+ "can-focus", FALSE,
+ "halign", GTK_ALIGN_START,
+ "homogeneous", TRUE,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "spacing", 0,
+ NULL);
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "visible", TRUE,
+ "can-focus", FALSE,
+ "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
+ "halign", GTK_ALIGN_START,
+ "label", name,
+ "valign", GTK_ALIGN_END,
+ NULL);
+ gtk_box_pack_start (GTK_BOX (box_text), label, TRUE, TRUE, 0);
+
+
+ if (reason) {
+ lbl_reason = g_object_new (GTK_TYPE_LABEL,
+ "visible", TRUE,
+ "can-focus", FALSE,
+ "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
+ "halign", GTK_ALIGN_START,
+ "label", reason,
+ "valign", GTK_ALIGN_START,
+ NULL);
+ gtk_box_pack_end (GTK_BOX (box_text), lbl_reason, TRUE, TRUE, 0);
+ } else {
+ gtk_widget_set_valign (label, GTK_ALIGN_FILL);
+ }
+
+ box = g_object_new (GTK_TYPE_BOX,
+ "visible", TRUE,
+ "can-focus", FALSE,
+ "halign", GTK_ALIGN_START,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "spacing", 12,
+ NULL);
+
+ gtk_box_pack_start (GTK_BOX (box), img, TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (box), box_text, FALSE, FALSE, 0);
+
+ gtk_list_box_insert (GTK_LIST_BOX (self->listbox), GTK_WIDGET (box), -1);
+}
+
+
+static void
+on_inhibitor_created (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PhoshEndSessionDialog *self = PHOSH_END_SESSION_DIALOG (user_data);
+
+ g_autoptr (GError) error = NULL;
+ g_autoptr (GDBusProxy) proxy = NULL;
+
+ proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+
+ if (!proxy) {
+ g_warning ("Failed to create Inhibitor proxy: %s", error->message);
+ return;
+ }
+
+ add_inhibitor (self, proxy);
+ g_object_unref (self);
+}
+
+
+static void
+clear_inhibitors (PhoshEndSessionDialog *self)
+{
+ g_autoptr (GList) children = NULL;
+
+ g_return_if_fail (GTK_IS_LIST_BOX (self->listbox));
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->listbox));
+ for (GList *child = children; child; child = child->next)
+ gtk_container_remove (GTK_CONTAINER (self->listbox), child->data);
+}
+
+
+static void
+end_session_dialog_update_inhibitors (PhoshEndSessionDialog *self, GStrv paths)
+{
+ g_strfreev (self->inhibitor_paths);
+ self->inhibitor_paths = g_strdupv ((char **) paths);
+
+ clear_inhibitors (self);
+
+ if (!is_inhibited (self)) {
+ gtk_widget_hide (self->listbox);
+ return;
+ }
+
+ for (int i = 0; self->inhibitor_paths[i]; i++) {
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, 0, NULL,
+ "org.gnome.SessionManager",
+ self->inhibitor_paths[i],
+ "org.gnome.SessionManager.Inhibitor",
+ NULL, on_inhibitor_created, g_object_ref (self));
+ }
+ gtk_widget_show (GTK_WIDGET (self->listbox));
+}
+
+
+static void
+phosh_end_session_dialog_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshEndSessionDialog *self = PHOSH_END_SESSION_DIALOG (obj);
+
+ switch (prop_id) {
+ case PROP_ACTION:
+ self->action = g_value_get_int (value);
+ end_session_dialog_update (self);
+ break;
+ case PROP_TIMEOUT:
+ self->timeout = g_value_get_int (value);
+ end_session_dialog_update (self);
+ break;
+ case PROP_INHIBITOR_PATHS:
+ end_session_dialog_update_inhibitors (self, g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_end_session_dialog_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshEndSessionDialog *self = PHOSH_END_SESSION_DIALOG (obj);
+
+ switch (prop_id) {
+ case PROP_ACTION:
+ g_value_set_int (value, self->action);
+ break;
+ case PROP_TIMEOUT:
+ g_value_set_int (value, self->timeout);
+ break;
+ case PROP_INHIBITOR_PATHS:
+ g_value_set_boxed (value, self->inhibitor_paths);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_end_session_dialog_dispose (GObject *obj)
+{
+ PhoshEndSessionDialog *self = PHOSH_END_SESSION_DIALOG (obj);
+
+ if (self->listbox)
+ clear_inhibitors (self);
+
+ G_OBJECT_CLASS (phosh_end_session_dialog_parent_class)->dispose (obj);
+}
+
+
+static void
+phosh_end_session_dialog_finalize (GObject *obj)
+{
+ PhoshEndSessionDialog *self = PHOSH_END_SESSION_DIALOG (obj);
+
+ g_clear_handle_id (&self->timeout_id, g_source_remove);
+ g_clear_pointer (&self->inhibitor_paths, g_strfreev);
+
+ G_OBJECT_CLASS (phosh_end_session_dialog_parent_class)->finalize (obj);
+}
+
+
+static void
+phosh_end_session_dialog_class_init (PhoshEndSessionDialogClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *)klass;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = phosh_end_session_dialog_get_property;
+ object_class->set_property = phosh_end_session_dialog_set_property;
+ object_class->dispose = phosh_end_session_dialog_dispose;
+ object_class->finalize = phosh_end_session_dialog_finalize;
+
+ props[PROP_ACTION] =
+ g_param_spec_int ("action",
+ "Action",
+ "The requested action",
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_TIMEOUT] =
+ g_param_spec_int ("timeout",
+ "Timeout",
+ "Timeout in seconds after which the action is performed",
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_INHIBITOR_PATHS] =
+ g_param_spec_boxed ("inhibitor-paths",
+ "Inhibitor paths",
+ "Paths to inhibitors that prevent atction",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ signals[CLOSED] = g_signal_new ("closed",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/sm/puri/phosh/ui/end-session-dialog.ui");
+ gtk_widget_class_bind_template_child (widget_class, PhoshEndSessionDialog, lbl_subtitle);
+ gtk_widget_class_bind_template_child (widget_class, PhoshEndSessionDialog, lbl_warn);
+ gtk_widget_class_bind_template_child (widget_class, PhoshEndSessionDialog, listbox);
+ gtk_widget_class_bind_template_child (widget_class, PhoshEndSessionDialog, btn_confirm);
+ gtk_widget_class_bind_template_child (widget_class, PhoshEndSessionDialog, btn_cancel);
+ gtk_widget_class_bind_template_callback (widget_class, on_btn_confirm_clicked);
+ gtk_widget_class_bind_template_callback (widget_class, on_dialog_canceled);
+}
+
+
+static void
+phosh_end_session_dialog_init (PhoshEndSessionDialog *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+
+GtkWidget *
+phosh_end_session_dialog_new (gint action,
+ gint timeout,
+ const char *const *inhibitor_paths)
+{
+ return g_object_new (PHOSH_TYPE_END_SESSION_DIALOG,
+ "action", action,
+ "timeout", timeout,
+ "inhibitor-paths", inhibitor_paths,
+ NULL);
+}
+
+
+gboolean
+phosh_end_session_dialog_get_action_confirmed (PhoshEndSessionDialog *self)
+{
+ g_return_val_if_fail (PHOSH_END_SESSION_DIALOG (self), FALSE);
+
+ return self->action_confirmed;
+}
+
+
+gboolean
+phosh_end_session_dialog_get_action (PhoshEndSessionDialog *self)
+{
+ g_return_val_if_fail (PHOSH_END_SESSION_DIALOG (self), 0);
+
+ return self->action;
+}
diff -Nru phosh-0.8.0/src/end-session-dialog.h phosh-0.13.1/src/end-session-dialog.h
--- phosh-0.8.0/src/end-session-dialog.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/end-session-dialog.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "system-modal-dialog.h"
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_END_SESSION_DIALOG (phosh_end_session_dialog_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshEndSessionDialog, phosh_end_session_dialog, PHOSH,
+ END_SESSION_DIALOG, PhoshSystemModalDialog)
+
+/**
+ * PhoshLogoutAction:
+ * @PHOSH_END_SESSION_ACTION_LOGOUT: Loguout
+ * @PHOSH_END_SESSION_ACTION_SHUTDOWN: Shutdown
+ * @PHOSH_END_SESSION_ACTION_REBOOT: Reboot
+ *
+ * The requested action the #PhoshEndSessionDialog should display. This matches
+ * the values of the DBus protocols 'open' request..
+ */
+typedef enum {
+ PHOSH_END_SESSION_ACTION_LOGOUT,
+ PHOSH_END_SESSION_ACTION_SHUTDOWN,
+ PHOSH_END_SESSION_ACTION_REBOOT,
+ /* Not used by gnome-session */
+ /**/
+ PHOSH_END_SESSION_ACTION_HIBERNATE,
+ PHOSH_END_SESSION_ACTION_SUSPEND,
+ PHOSH_END_SESSION_ACTION_HYBRID_SLEEP,
+} PhoshLogoutAction;
+
+GtkWidget *phosh_end_session_dialog_new (gint action,
+ gint seconds,
+ const char *const * paths);
+gboolean phosh_end_session_dialog_get_action_confirmed (PhoshEndSessionDialog *self);
+gint phosh_end_session_dialog_get_action (PhoshEndSessionDialog *self);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/fader.c phosh-0.13.1/src/fader.c
--- phosh-0.8.0/src/fader.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/fader.c 2021-08-31 09:15:52.000000000 +0000
@@ -19,28 +19,89 @@
* @short_description: A fader
* @Title: PhoshFader
*
- * A fullsreen surface that fades in
+ * A fullsreen surface that fades in or out.
*/
+#define PHOSH_FADER_DEFAULT_STYLE_CLASS "phosh-fader-default-fade"
+
+enum {
+ PROP_0,
+ PROP_MONITOR,
+ PROP_STYLE_CLASS,
+ PROP_LAST_PROP,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
typedef struct _PhoshFader
{
- PhoshLayerSurface parent;
-
+ PhoshLayerSurface parent;
+ PhoshMonitor *monitor;
+ char *style_class;
} PhoshFader;
G_DEFINE_TYPE (PhoshFader, phosh_fader, PHOSH_TYPE_LAYER_SURFACE)
static void
+phosh_fader_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshFader *self = PHOSH_FADER (obj);
+
+ switch (prop_id) {
+ case PROP_MONITOR:
+ /* construct only */
+ g_set_object (&self->monitor, g_value_get_object (value));
+ break;
+ case PROP_STYLE_CLASS:
+ g_free (self->style_class);
+ self->style_class = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_fader_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshFader *self = PHOSH_FADER (obj);
+
+ switch (prop_id) {
+ case PROP_MONITOR:
+ g_value_set_object (value, self->monitor);
+ break;
+ case PROP_STYLE_CLASS:
+ g_value_set_string (value, self->style_class);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
phosh_fader_show (GtkWidget *widget)
{
+ PhoshFader *self = PHOSH_FADER (widget);
gboolean enable_animations;
GtkStyleContext *context;
enable_animations = hdy_get_enable_animations (widget);
if (enable_animations) {
- context = gtk_widget_get_style_context(widget);
- gtk_style_context_add_class (context, "phosh-fader-fade-in");
+ const char *style_class;
+
+ style_class = self->style_class ?: PHOSH_FADER_DEFAULT_STYLE_CLASS;
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_add_class (context, style_class);
}
GTK_WIDGET_CLASS (phosh_fader_parent_class)->show (widget);
@@ -48,37 +109,89 @@
static void
+phosh_fader_dispose (GObject *object)
+{
+ PhoshFader *self = PHOSH_FADER (object);
+
+ g_clear_object (&self->monitor);
+ g_clear_pointer (&self->style_class, g_free);
+
+ G_OBJECT_CLASS (phosh_fader_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_fader_constructed (GObject *object)
+{
+ PhoshFader *self = PHOSH_FADER (object);
+ PhoshWayland *wl = phosh_wayland_get_default ();
+
+ if (self->monitor == NULL)
+ self->monitor = g_object_ref (phosh_shell_get_primary_monitor (phosh_shell_get_default ()));
+
+ g_object_set (PHOSH_LAYER_SURFACE (self),
+ "layer-shell", phosh_wayland_get_zwlr_layer_shell_v1 (wl),
+ "wl-output", phosh_monitor_get_wl_output (self->monitor),
+ "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
+ "layer", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
+ "kbd-interactivity", FALSE,
+ "exclusive-zone", -1,
+ "namespace", "phosh fader",
+ NULL);
+
+ G_OBJECT_CLASS (phosh_fader_parent_class)->constructed (object);
+}
+
+
+static void
phosh_fader_class_init (PhoshFaderClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->get_property = phosh_fader_get_property;
+ object_class->set_property = phosh_fader_set_property;
+ object_class->constructed = phosh_fader_constructed;
+ object_class->dispose = phosh_fader_dispose;
widget_class->show = phosh_fader_show;
+
+ props[PROP_MONITOR] = g_param_spec_object ("monitor",
+ "",
+ "",
+ PHOSH_TYPE_MONITOR,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PhoshFader:style-class
+ *
+ * The CSS style class used for the animation
+ */
+ props[PROP_STYLE_CLASS] = g_param_spec_string ("style-class",
+ "",
+ "",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
static void
phosh_fader_init (PhoshFader *self)
{
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context(GTK_WIDGET (self));
- gtk_style_context_remove_class(context, "phosh-fader-fade-in");
+ self->style_class = g_strdup (PHOSH_FADER_DEFAULT_STYLE_CLASS);
}
PhoshFader *
-phosh_fader_new (gpointer layer_shell, gpointer wl_output)
+phosh_fader_new (PhoshMonitor *monitor)
{
- return g_object_new (PHOSH_TYPE_FADER,
- "layer-shell", layer_shell,
- "wl-output", wl_output,
- "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
- "layer", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
- "kbd-interactivity", FALSE,
- "exclusive-zone", -1,
- "namespace", "phosh fader",
- NULL);
+ return g_object_new (PHOSH_TYPE_FADER, "monitor", monitor, NULL);
}
diff -Nru phosh-0.8.0/src/fader.h phosh-0.13.1/src/fader.h
--- phosh-0.8.0/src/fader.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/fader.h 2021-08-31 09:15:52.000000000 +0000
@@ -5,6 +5,8 @@
*/
#pragma once
+#include "monitor/monitor.h"
+
#include
G_BEGIN_DECLS
@@ -13,6 +15,6 @@
G_DECLARE_FINAL_TYPE (PhoshFader, phosh_fader, PHOSH, FADER, PhoshLayerSurface)
-PhoshFader *phosh_fader_new (gpointer layer_shell,
- gpointer wl_output);
+PhoshFader *phosh_fader_new (PhoshMonitor *monitor);
+
G_END_DECLS
diff -Nru phosh-0.8.0/src/feedbackinfo.c phosh-0.13.1/src/feedbackinfo.c
--- phosh-0.8.0/src/feedbackinfo.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/feedbackinfo.c 2021-08-31 09:15:52.000000000 +0000
@@ -93,9 +93,12 @@
phosh_feedback_info_class_init (PhoshFeedbackInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_feedback_info_constructed;
object_class->dispose = phosh_feedback_info_dispose;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-feedback-info");
}
diff -Nru phosh-0.8.0/src/feedback-manager.c phosh-0.13.1/src/feedback-manager.c
--- phosh-0.8.0/src/feedback-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/feedback-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -21,6 +21,7 @@
*/
#define PHOSH_FEEDBACK_ICON_FULL "preferences-system-notifications-symbolic"
+#define PHOSH_FEEDBACK_ICON_QUIET "feedback-quiet-symbolic"
#define PHOSH_FEEDBACK_ICON_SILENT "notifications-disabled-symbolic"
enum {
@@ -94,10 +95,12 @@
const char *profile = self->profile;
self->profile = lfb_get_feedback_profile ();
- if (g_strcmp0 (self->profile, "quiet") && g_strcmp0 (self->profile, "silent"))
- self->icon_name = PHOSH_FEEDBACK_ICON_FULL;
- else
+ if (g_strcmp0 (self->profile, "quiet") == 0)
+ self->icon_name = PHOSH_FEEDBACK_ICON_QUIET;
+ else if (g_strcmp0 (self->profile, "silent") == 0)
self->icon_name = PHOSH_FEEDBACK_ICON_SILENT;
+ else
+ self->icon_name = PHOSH_FEEDBACK_ICON_FULL;
g_debug("Feedback profile set to: '%s', icon '%s'", self->profile, self->icon_name);
@@ -215,12 +218,14 @@
void
phosh_feedback_manager_toggle (PhoshFeedbackManager *self)
{
- const char *profile = "silent";
+ const char *profile = "silent", *old = lfb_get_feedback_profile ();
- if (g_strcmp0 (lfb_get_feedback_profile (), "full"))
+ if (!g_strcmp0 (old, "silent"))
profile = "full";
+ else if (!g_strcmp0 (old, "full"))
+ profile = "quiet";
- g_debug ("Setting feedback profile to %s", profile);
+ g_debug ("Setting feedback profile to %s, was %s", profile, old);
lfb_set_feedback_profile (profile);
}
diff -Nru phosh-0.8.0/src/gnome-shell-manager.c phosh-0.13.1/src/gnome-shell-manager.c
--- phosh-0.8.0/src/gnome-shell-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/gnome-shell-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -12,7 +12,10 @@
#include "../config.h"
#include "gnome-shell-manager.h"
+#include "osd-window.h"
#include "shell.h"
+#include "util.h"
+#include "lockscreen-manager.h"
/**
* SECTION:gnome-shell-manager
@@ -21,17 +24,29 @@
*
*/
-#define NOTIFY_DBUS_NAME "org.gnome.Shell"
-
+#define GNOME_SHELL_DBUS_NAME "org.gnome.Shell"
+#define OSD_HIDE_TIMEOUT 1 /* seconds */
static void phosh_gnome_shell_manager_shell_iface_init (PhoshGnomeShellDBusShellIface *iface);
+enum {
+ PROP_0,
+ PROP_ACTION_MODE,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
typedef struct _PhoshGnomeShellManager {
PhoshGnomeShellDBusShellSkeleton parent;
GHashTable *info_by_action;
guint last_action_id;
int dbus_name_id;
+ ShellActionMode action_mode;
+
+ PhoshOsdWindow *osd;
+ gint osd_timeoutid;
+ gboolean osd_continue;
} PhoshGnomeShellManager;
G_DEFINE_TYPE_WITH_CODE (PhoshGnomeShellManager,
@@ -47,18 +62,17 @@
guint action_id;
gchar *accelerator;
gchar *sender;
+ guint mode_flags;
+ guint grab_flags;
} AcceleratorInfo;
static void
-remove_action_entries (const gchar *accelerator)
+remove_action_entries (gchar *accelerator)
{
- const GActionEntry action_entries[] = {
- { accelerator, accelerator_activated_action, },
- };
+ GStrv action_names = (char*[]){ accelerator, NULL };
phosh_shell_remove_global_keyboard_action_entries (phosh_shell_get_default (),
- action_entries,
- G_N_ELEMENTS (action_entries));
+ action_names);
}
static void
@@ -107,6 +121,80 @@
static gboolean
+on_osd_timeout (PhoshGnomeShellManager *self)
+{
+ gboolean ret;
+ ret = self->osd_continue ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
+ if (!self->osd_continue) {
+ g_debug ("Closing osd");
+ self->osd_timeoutid = 0;
+ if (self->osd)
+ gtk_widget_destroy (GTK_WIDGET (self->osd));
+ }
+ self->osd_continue = FALSE;
+ return ret;
+}
+
+static void
+on_osd_destroyed (PhoshGnomeShellManager *self)
+{
+ self->osd = NULL;
+ g_clear_handle_id (&self->osd_timeoutid, g_source_remove);
+}
+
+
+static gboolean
+handle_show_osd (PhoshGnomeShellDBusShell *skeleton,
+ GDBusMethodInvocation *invocation,
+ GVariant *arg_params)
+{
+ PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (skeleton);
+ GVariantDict dict;
+ g_autofree char *connector = NULL, *icon = NULL, *label = NULL;
+ gdouble level = 0.0, maxlevel = 1.0;
+
+ g_return_val_if_fail (PHOSH_IS_GNOME_SHELL_MANAGER (self), FALSE);
+
+ g_variant_dict_init (&dict, arg_params);
+ g_variant_dict_lookup (&dict, "connector", "s", &connector);
+ g_variant_dict_lookup (&dict, "icon", "s", &icon);
+ g_variant_dict_lookup (&dict, "label", "s", &label);
+ g_variant_dict_lookup (&dict, "level", "d", &level);
+ g_variant_dict_lookup (&dict, "max_level", "d", &maxlevel);
+
+ g_debug ("DBus show osd: connector: %s icon: %s, label: %s, level %f/%f",
+ connector, icon, label, level, maxlevel);
+
+ if (self->osd) {
+ self->osd_continue = TRUE;
+ g_object_set (self->osd,
+ "connector", connector,
+ "label", label,
+ "icon-name", icon,
+ "level", level,
+ "max-level", maxlevel,
+ NULL);
+ } else {
+ self->osd = PHOSH_OSD_WINDOW (phosh_osd_window_new (connector, label, icon, level, maxlevel));
+ g_signal_connect_swapped (self->osd, "destroy", G_CALLBACK (on_osd_destroyed), self);
+ gtk_widget_show (GTK_WIDGET (self->osd));
+ }
+
+ if (!self->osd_timeoutid) {
+ self->osd_timeoutid = g_timeout_add_seconds (OSD_HIDE_TIMEOUT,
+ (GSourceFunc)on_osd_timeout,
+ self);
+ g_source_set_name_by_id (self->osd_timeoutid, "[phosh] osd-timeout");
+ }
+
+ phosh_gnome_shell_dbus_shell_complete_show_osd (
+ skeleton, invocation);
+
+ return TRUE;
+}
+
+
+static gboolean
grab_single_accelerator (PhoshGnomeShellManager *self,
const gchar *accelerator,
guint mode_flags,
@@ -129,6 +217,8 @@
info->accelerator = g_strdup (accelerator);
info->action_id = ++(self->last_action_id);
info->sender = g_strdup (sender);
+ info->mode_flags = mode_flags;
+ info->grab_flags = grab_flags;
g_debug ("Using action id %d for accelerator %s", info->action_id, info->accelerator);
@@ -192,7 +282,7 @@
{
PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (skeleton);
g_autoptr (GVariantBuilder) builder = NULL;
- GVariantIter *arg_iter;
+ g_autoptr (GVariantIter) arg_iter = NULL;
gchar *accelerator_name;
guint accelerator_mode_flags;
guint accelerator_grab_flags;
@@ -349,12 +439,37 @@
{
iface->handle_show_monitor_labels = handle_show_monitor_labels;
iface->handle_hide_monitor_labels = handle_hide_monitor_labels;
+ iface->handle_show_osd = handle_show_osd;
iface->handle_grab_accelerator = handle_grab_accelerator;
iface->handle_grab_accelerators = handle_grab_accelerators;
iface->handle_ungrab_accelerator = handle_ungrab_accelerator;
iface->handle_ungrab_accelerators = handle_ungrab_accelerators;
}
+static ShellActionMode
+get_action_mode (PhoshShellStateFlags state)
+{
+ PhoshShell *shell = phosh_shell_get_default ();
+
+ if (state & PHOSH_STATE_LOCKED) {
+ PhoshLockscreenManager *lockscreen_manager = phosh_shell_get_lockscreen_manager (shell);
+ PhoshLockscreenPage page = phosh_lockscreen_manager_get_page (lockscreen_manager);
+
+ if (page == PHOSH_LOCKSCREEN_PAGE_UNLOCK)
+ return SHELL_ACTION_MODE_UNLOCK_SCREEN;
+ else
+ return SHELL_ACTION_MODE_LOCK_SCREEN;
+ }
+
+ if (state & PHOSH_STATE_MODAL_SYSTEM_PROMPT)
+ return SHELL_ACTION_MODE_SYSTEM_MODAL;
+
+ if (state & PHOSH_STATE_OVERVIEW)
+ return SHELL_ACTION_MODE_OVERVIEW;
+
+ return SHELL_ACTION_MODE_NORMAL;
+}
+
static void
accelerator_activated_action (GSimpleAction *action,
GVariant *param,
@@ -362,13 +477,22 @@
{
AcceleratorInfo *info = (AcceleratorInfo *) data;
PhoshGnomeShellManager *self = phosh_gnome_shell_manager_get_default ();
- g_autoptr (GVariantBuilder) builder;
+ g_autoptr (GVariantBuilder) builder = NULL;
GVariant *parameters;
uint32_t action_id;
action_id = info->action_id;
g_debug ("accelerator action activated for id %u", action_id);
+ if ((info->mode_flags & self->action_mode) == 0) {
+ g_autofree gchar *str_shell_mode = g_flags_to_string (SHELL_TYPE_ACTION_MODE, self->action_mode);
+ g_autofree gchar *str_grabbed_mode = g_flags_to_string (SHELL_TYPE_ACTION_MODE, info->mode_flags);
+ g_debug ("Accelerator registered for mode %s, but shell is currently in %s",
+ str_grabbed_mode,
+ str_shell_mode);
+ return;
+ }
+
builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
/*
* Fill some dummy values
@@ -412,31 +536,86 @@
const char *name,
gpointer user_data)
{
- PhoshGnomeShellManager *self = user_data;
+ g_autoptr (GError) err = NULL;
+ PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (user_data);
+ PhoshSessionManager *sm;
+ gboolean success;
- g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
- connection,
- "/org/gnome/Shell",
- NULL);
+ success = g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
+ connection,
+ "/org/gnome/Shell",
+ NULL);
+ if (!success) {
+ g_warning ("Failed to export shell interface: %s", err->message);
+ return;
+ }
+
+ sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
+ phosh_session_manager_export_end_session (sm, connection);
}
+static gboolean
+transform_state_to_action_mode (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer unused)
+{
+ PhoshShellStateFlags shell_state = g_value_get_flags (from_value);
+ ShellActionMode action_mode = get_action_mode (shell_state);
+
+ g_value_set_flags (to_value, action_mode);
+ return TRUE;
+}
+
static void
-phosh_gnome_shell_manager_dispose (GObject *object)
+phosh_gnome_shell_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (object);
- GList *grabbed;
- guint n = 0;
- for (grabbed = g_hash_table_get_keys (self->info_by_action); grabbed != NULL; grabbed = grabbed->next) {
- AcceleratorInfo *info = grabbed->data;
+ switch (property_id) {
+ case PROP_ACTION_MODE:
+ self->action_mode = g_value_get_flags (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
- g_hash_table_remove (self->info_by_action, GUINT_TO_POINTER (info->action_id));
- ++n;
+
+static void
+phosh_gnome_shell_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_ACTION_MODE:
+ g_value_set_flags (value, self->action_mode);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
- g_hash_table_unref (self->info_by_action);
+}
+
+static void
+phosh_gnome_shell_manager_dispose (GObject *object)
+{
+ PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (object);
+
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
- g_debug ("%d accelerators needed to be cleaned up!", n);
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_pointer (&self->info_by_action, g_hash_table_unref);
G_OBJECT_CLASS (phosh_gnome_shell_manager_parent_class)->dispose (object);
}
@@ -446,17 +625,25 @@
phosh_gnome_shell_manager_constructed (GObject *object)
{
PhoshGnomeShellManager *self = PHOSH_GNOME_SHELL_MANAGER (object);
+ PhoshShell *shell = phosh_shell_get_default ();
G_OBJECT_CLASS (phosh_gnome_shell_manager_parent_class)->constructed (object);
+
+ g_object_bind_property_full (shell, "shell-state",
+ object, "shell-action-mode",
+ G_BINDING_SYNC_CREATE,
+ (GBindingTransformFunc) transform_state_to_action_mode,
+ NULL, NULL, NULL);
+
self->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
- NOTIFY_DBUS_NAME,
+ GNOME_SHELL_DBUS_NAME,
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
G_BUS_NAME_OWNER_FLAGS_REPLACE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
- g_object_ref (self),
- g_object_unref);
+ self,
+ NULL);
}
@@ -465,8 +652,21 @@
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = phosh_gnome_shell_manager_get_property;
+ object_class->set_property = phosh_gnome_shell_manager_set_property;
object_class->constructed = phosh_gnome_shell_manager_constructed;
object_class->dispose = phosh_gnome_shell_manager_dispose;
+
+ props[PROP_ACTION_MODE] =
+ g_param_spec_flags ("shell-action-mode",
+ "Shell Action Mode",
+ "The active action mode (used for keygrabbing)",
+ SHELL_TYPE_ACTION_MODE,
+ SHELL_ACTION_MODE_NONE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
}
diff -Nru phosh-0.8.0/src/gnome-shell-manager.h phosh-0.13.1/src/gnome-shell-manager.h
--- phosh-0.8.0/src/gnome-shell-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/gnome-shell-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -5,12 +5,51 @@
*
* Author: Guido Günther
* Evangelos Ribeiro Tzaras
+ *
+ * ShellActionMode is from GNOME Shell's shell-action-modes.h
+ * which is GPL-2.0-or-later and authored by
+ * Florian Müllner
*/
#pragma once
#include "dbus/phosh-gnome-shell-dbus.h"
#include
+/**
+ * ShellActionMode:
+ * @SHELL_ACTION_MODE_NONE: block action
+ * @SHELL_ACTION_MODE_NORMAL: allow action when in window mode,
+ * e.g. when the focus is in an application window
+ * @SHELL_ACTION_MODE_OVERVIEW: allow action while the overview
+ * is active
+ * @SHELL_ACTION_MODE_LOCK_SCREEN: allow action when the screen
+ * is locked, e.g. when the screen shield is shown
+ * @SHELL_ACTION_MODE_UNLOCK_SCREEN: allow action in the unlock
+ * dialog
+ * @SHELL_ACTION_MODE_LOGIN_SCREEN: allow action in the login screen
+ * @SHELL_ACTION_MODE_SYSTEM_MODAL: allow action when a system modal
+ * dialog (e.g. authentication or session dialogs) is open
+ * @SHELL_ACTION_MODE_LOOKING_GLASS: allow action in looking glass
+ * @SHELL_ACTION_MODE_POPUP: allow action while a shell menu is open
+ * @SHELL_ACTION_MODE_ALL: always allow action
+ *
+ * Controls in which GNOME Shell states an action (like keybindings and gestures)
+ * should be handled.
+*/
+typedef enum {
+ SHELL_ACTION_MODE_NONE = 0,
+ SHELL_ACTION_MODE_NORMAL = 1 << 0,
+ SHELL_ACTION_MODE_OVERVIEW = 1 << 1,
+ SHELL_ACTION_MODE_LOCK_SCREEN = 1 << 2,
+ SHELL_ACTION_MODE_UNLOCK_SCREEN = 1 << 3,
+ SHELL_ACTION_MODE_LOGIN_SCREEN = 1 << 4,
+ SHELL_ACTION_MODE_SYSTEM_MODAL = 1 << 5,
+ SHELL_ACTION_MODE_LOOKING_GLASS = 1 << 6,
+ SHELL_ACTION_MODE_POPUP = 1 << 7,
+
+ SHELL_ACTION_MODE_ALL = ~0,
+} ShellActionMode;
+
G_BEGIN_DECLS
#define PHOSH_TYPE_GNOME_SHELL_MANAGER (phosh_gnome_shell_manager_get_type ())
diff -Nru phosh-0.8.0/src/gtk-mount-manager.c phosh-0.13.1/src/gtk-mount-manager.c
--- phosh-0.8.0/src/gtk-mount-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/gtk-mount-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-gtk-mount-manager"
+
+#include "gtk-mount-manager.h"
+#include "gtk-mount-prompt.h"
+#include "shell.h"
+#include "util.h"
+
+#include
+
+/**
+ * SECTION:gtk-mount-manager
+ * @short_description: Provides the org.Gtk.GtkMountOperationHandler DBus interface
+ * @Title: PhoshGtkMountManager
+ *
+ * The interface is responsible to handle the ui parts of a #GtkMountOperation.
+ */
+
+#define GTK_MOUNT_DBUS_NAME "org.gtk.MountOperationHandler"
+
+enum {
+ NEW_PROMPT,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+static void phosh_gtk_mount_manager_gtk_mount_iface_init (
+ PhoshDBusMountOperationHandlerIface *iface);
+
+typedef struct _PhoshGtkMountManager {
+ PhoshDBusMountOperationHandlerSkeleton parent;
+
+ int dbus_name_id;
+ PhoshGtkMountPrompt *prompt;
+ char *object_id;
+
+ GDBusMethodInvocation *invocation;
+} PhoshGtkMountManager;
+
+G_DEFINE_TYPE_WITH_CODE (PhoshGtkMountManager,
+ phosh_gtk_mount_manager,
+ PHOSH_DBUS_TYPE_MOUNT_OPERATION_HANDLER_SKELETON,
+ G_IMPLEMENT_INTERFACE (
+ PHOSH_DBUS_TYPE_MOUNT_OPERATION_HANDLER,
+ phosh_gtk_mount_manager_gtk_mount_iface_init));
+
+
+static void
+on_prompt_done (PhoshGtkMountManager *self, PhoshGtkMountPrompt *prompt)
+{
+ gboolean cancelled;
+ GMountOperationResult response = G_MOUNT_OPERATION_ABORTED;
+ g_autoptr (GVariantDict) response_details = g_variant_dict_new (NULL);
+
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (prompt));
+
+ cancelled = phosh_gtk_mount_prompt_get_cancelled (prompt);
+ g_debug ("Prompt done, cancelled: %d", cancelled);
+
+ if (phosh_gtk_mount_prompt_get_choices (prompt)) { /* AskQuestion / ShowProcesses */
+ int choice = phosh_gtk_mount_prompt_get_choice (prompt);
+
+ if (!cancelled) {
+ response = G_MOUNT_OPERATION_HANDLED;
+ g_variant_dict_insert (response_details, "choice", "i", choice);
+ }
+ } else { /* AskPassword / Default buttons */
+ if (!cancelled) {
+ const char *password;
+
+ response = G_MOUNT_OPERATION_HANDLED;
+ password = phosh_gtk_mount_prompt_get_password (prompt);
+ g_variant_dict_insert (response_details, "password", "s", password ?: "", NULL);
+ /*
+ * GTKs gtkmountoperation:call_password_proxy_cb only cares about
+ * 'password', 'password_save', 'hidden_volume', 'system_volume' and 'pim'
+ * so no need to bother with usernames and domains here
+ */
+ /* TODO: 'password_save' */
+ }
+ }
+
+ if (self->invocation) {
+ /*
+ * phosh_dbus_mount_operation_handler_complete_ask_question has the same
+ * signature and params so we can use either one
+ */
+ phosh_dbus_mount_operation_handler_complete_ask_password (
+ PHOSH_DBUS_MOUNT_OPERATION_HANDLER (self),
+ self->invocation, response,
+ g_variant_dict_end (response_details));
+ self->invocation = NULL;
+ } else {
+ g_warning ("No invocation!");
+ }
+}
+
+
+static void
+end_ask_invocation (PhoshGtkMountManager *self)
+{
+ g_autoptr (GVariantDict) response_details = g_variant_dict_new (NULL);
+
+ if (!self->invocation)
+ return;
+
+ /*
+ * phosh_dbus_mount_operation_handler_complete_* all have the same
+ * signature and params so we can any of them:
+ */
+ phosh_dbus_mount_operation_handler_complete_ask_password (
+ PHOSH_DBUS_MOUNT_OPERATION_HANDLER (self),
+ self->invocation, G_MOUNT_OPERATION_UNHANDLED,
+ g_variant_dict_end (response_details));
+ self->invocation = NULL;
+}
+
+
+static void
+new_prompt (PhoshGtkMountManager *self,
+ const char *message,
+ const char *icon_name,
+ const char *default_user,
+ const char *default_domain,
+ GVariant *pids,
+ const char *const *choices,
+ GAskPasswordFlags ask_flags)
+{
+ g_debug ("New prompt for '%s'", message);
+
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+
+ self->prompt = PHOSH_GTK_MOUNT_PROMPT (phosh_gtk_mount_prompt_new (
+ message,
+ icon_name,
+ default_user,
+ default_domain,
+ pids,
+ choices,
+ ask_flags));
+ g_signal_connect_swapped (self->prompt,
+ "closed",
+ G_CALLBACK (on_prompt_done),
+ self);
+
+ gtk_widget_show (GTK_WIDGET (self->prompt));
+
+ g_signal_emit (self, signals[NEW_PROMPT], 0);
+}
+
+
+static gboolean
+handle_ask_password (PhoshDBusMountOperationHandler *object,
+ GDBusMethodInvocation *invocation,
+ const char *arg_object_id,
+ const char *arg_message,
+ const char *arg_icon_name,
+ const char *arg_default_user,
+ const char *arg_default_domain,
+ guint arg_flags)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ g_debug ("DBus call AskPassword for '%s'", arg_object_id);
+
+ if (self->invocation)
+ end_ask_invocation (self);
+ self->invocation = invocation;
+
+ new_prompt (self,
+ arg_message,
+ arg_icon_name,
+ arg_default_user,
+ arg_default_domain,
+ NULL,
+ NULL,
+ arg_flags);
+
+ return TRUE;
+}
+
+static gboolean
+handle_ask_question ( PhoshDBusMountOperationHandler *object,
+ GDBusMethodInvocation *invocation,
+ const char *arg_object_id,
+ const char *arg_message,
+ const char *arg_icon_name,
+ const char *const *arg_choices)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ g_debug ("DBus call AskQuestion: %s", arg_object_id);
+
+ /* Cancel an ongoing dialog */
+ if (self->invocation)
+ end_ask_invocation (self);
+ self->invocation = invocation;
+
+ new_prompt (self,
+ arg_message,
+ arg_icon_name,
+ NULL,
+ NULL,
+ NULL,
+ arg_choices,
+ 0);
+
+ return TRUE;
+}
+
+static gboolean
+handle_show_processes (PhoshDBusMountOperationHandler *object,
+ GDBusMethodInvocation *invocation,
+ const char *arg_object_id,
+ const char *arg_message,
+ const char *arg_icon_name,
+ GVariant *arg_application_pids,
+ const char *const *arg_choices)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ g_debug ("DBus call ShowProcesses: %s", arg_object_id);
+
+ if (arg_object_id == NULL) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "No object id");
+ invocation = NULL;
+ return TRUE;
+ }
+
+ if (!g_strcmp0 (arg_object_id, self->object_id) && self->prompt) {
+ g_debug ("Updating dialog %s", self->object_id);
+
+ phosh_gtk_mount_prompt_set_pids (self->prompt, arg_application_pids);
+ self->invocation = invocation;
+ return TRUE;
+ }
+
+ g_clear_pointer (&self->object_id, g_free);
+ self->object_id = g_strdup (arg_object_id);
+
+ if (self->invocation)
+ end_ask_invocation (self);
+ self->invocation = invocation;
+
+ new_prompt (self,
+ arg_message,
+ arg_icon_name,
+ NULL,
+ NULL,
+ arg_application_pids,
+ arg_choices,
+ 0);
+
+ return TRUE;
+}
+
+static gboolean
+handle_close (PhoshDBusMountOperationHandler *object,
+ GDBusMethodInvocation *invocation)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ g_debug ("DBus call Close");
+
+ end_ask_invocation (self);
+
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+ g_clear_pointer (&self->object_id, g_free);
+
+ phosh_dbus_mount_operation_handler_complete_close (
+ object, invocation);
+
+ return TRUE;
+}
+
+static void
+phosh_gtk_mount_manager_gtk_mount_iface_init (PhoshDBusMountOperationHandlerIface *iface)
+{
+ iface->handle_ask_password = handle_ask_password;
+ iface->handle_ask_question = handle_ask_question;
+ iface->handle_close = handle_close;
+ iface->handle_show_processes = handle_show_processes;
+}
+
+
+static void
+on_name_acquired (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (user_data);
+
+ g_debug ("Acquired name %s", name);
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_MANAGER (self));
+}
+
+
+static void
+on_name_lost (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ g_debug ("Lost or failed to acquire name %s", name);
+}
+
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ PhoshGtkMountManager *self = user_data;
+
+ g_autoptr (GError) err = NULL;
+
+ if (g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
+ connection,
+ "/org/gtk/MountOperationHandler",
+ &err)) {
+ g_debug ("Mount operation handler exported");
+ } else {
+ g_warning ("Failed to export on %s: %s", GTK_MOUNT_DBUS_NAME, err->message);
+ }
+}
+
+
+static void
+phosh_gtk_mount_manager_dispose (GObject *object)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ end_ask_invocation (self);
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
+
+ G_OBJECT_CLASS (phosh_gtk_mount_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_gtk_mount_manager_finalize (GObject *object)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ g_clear_pointer (&self->object_id, g_free);
+
+ G_OBJECT_CLASS (phosh_gtk_mount_manager_parent_class)->finalize (object);
+}
+
+
+static void
+phosh_gtk_mount_manager_constructed (GObject *object)
+{
+ PhoshGtkMountManager *self = PHOSH_GTK_MOUNT_MANAGER (object);
+
+ G_OBJECT_CLASS (phosh_gtk_mount_manager_parent_class)->constructed (object);
+ self->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+ GTK_MOUNT_DBUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ self,
+ NULL);
+}
+
+
+static void
+phosh_gtk_mount_manager_class_init (PhoshGtkMountManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = phosh_gtk_mount_manager_constructed;
+ object_class->dispose = phosh_gtk_mount_manager_dispose;
+ object_class->finalize = phosh_gtk_mount_manager_finalize;
+
+ /**
+ * PhoshGtkMountManager::new-prompt
+ * @self: The #PhoshGtkMountManager emitting this signal
+ *
+ * Emitted when a new prompt is shown
+ */
+ signals[NEW_PROMPT] = g_signal_new (
+ "new-prompt",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
+}
+
+
+static void
+phosh_gtk_mount_manager_init (PhoshGtkMountManager *self)
+{
+}
+
+
+PhoshGtkMountManager *
+phosh_gtk_mount_manager_new (void)
+{
+ return g_object_new (PHOSH_TYPE_GTK_MOUNT_MANAGER, NULL);
+}
diff -Nru phosh-0.8.0/src/gtk-mount-manager.h phosh-0.13.1/src/gtk-mount-manager.h
--- phosh-0.8.0/src/gtk-mount-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/gtk-mount-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#pragma once
+
+#include "dbus/phosh-gtk-mountoperation-dbus.h"
+#include
+
+#define PHOSH_TYPE_GTK_MOUNT_MANAGER (phosh_gtk_mount_manager_get_type ())
+G_DECLARE_FINAL_TYPE (PhoshGtkMountManager, phosh_gtk_mount_manager, PHOSH, GTK_MOUNT_MANAGER,
+ PhoshDBusMountOperationHandlerSkeleton)
+
+PhoshGtkMountManager *phosh_gtk_mount_manager_new (void);
diff -Nru phosh-0.8.0/src/gtk-mount-prompt.c phosh-0.13.1/src/gtk-mount-prompt.c
--- phosh-0.8.0/src/gtk-mount-prompt.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/gtk-mount-prompt.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-gtk-mount-prompt"
+
+#include "config.h"
+
+#include "gtk-mount-prompt.h"
+
+#include
+
+/**
+ * SECTION:gtk-mount-prompt
+ * @short_description: A modal prompt for #PhoshGtkMountManager
+ * @Title: PhoshGtkMountPrompt
+ *
+ * The #PhoshGtkMountPrompt is used to query the needed information
+ * for the #PhoshGtkMountManager.
+ */
+
+enum {
+ PROP_0,
+ PROP_MESSAGE,
+ PROP_ICON_NAME,
+ PROP_DEFAULT_USER,
+ PROP_DEFAULT_DOMAIN,
+ PROP_PIDS,
+ PROP_CHOICES,
+ PROP_ASK_FLAGS,
+ PROP_LAST_PROP,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+
+enum {
+ CLOSED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+
+struct _PhoshGtkMountPrompt {
+ PhoshSystemModalDialog parent;
+
+ GtkWidget *lbl_msg;
+ GtkWidget *lbl_password;
+ GtkWidget *img_icon;
+ GtkWidget *lbl_user;
+ GtkWidget *entry_user;
+ GtkWidget *lbl_domain;
+ GtkWidget *entry_domain;
+ GtkWidget *entry_password;
+ GtkEntryBuffer *password_buffer;
+ gboolean pw_visible;
+
+ char *message;
+ char *icon_name;
+ char *default_user;
+ char *default_domain;
+ GStrv choices;
+ int choice;
+ GVariant *pids;
+ GAskPasswordFlags ask_flags;
+
+ gboolean cancelled;
+};
+G_DEFINE_TYPE (PhoshGtkMountPrompt, phosh_gtk_mount_prompt, PHOSH_TYPE_SYSTEM_MODAL_DIALOG);
+
+
+static void G_GNUC_NULL_TERMINATED
+set_visible (gboolean visible, ...)
+{
+ va_list args;
+ GtkWidget *widget;
+
+ va_start (args, visible);
+ do {
+ widget = va_arg (args, gpointer);
+ if (widget == NULL)
+ break;
+ gtk_widget_set_visible (widget, visible);
+ } while (TRUE);
+ va_end (args);
+}
+
+
+static void
+set_entries_visible (PhoshGtkMountPrompt *self, gboolean visible)
+{
+ set_visible (visible, self->lbl_password, self->entry_password, NULL);
+ set_visible (visible, self->lbl_user, self->entry_user, NULL);
+ set_visible (visible, self->lbl_domain, self->entry_domain, NULL);
+}
+
+
+static void
+set_message (PhoshGtkMountPrompt *self, const char *message)
+{
+ g_autofree char *primary = NULL;
+ char *secondary = NULL;
+
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (!g_strcmp0 (self->message, message))
+ return;
+
+ g_clear_pointer (&self->message, g_free);
+ self->message = g_strdup (message);
+
+ primary = strstr (message, "\n");
+ if (primary) {
+ secondary = primary + 1;
+ primary = g_strndup (message, primary - message);
+ }
+
+ phosh_system_modal_dialog_set_title (PHOSH_SYSTEM_MODAL_DIALOG (self), primary ?: message);
+ if (secondary) {
+ gtk_label_set_label (GTK_LABEL (self->lbl_msg), secondary);
+ gtk_widget_show (self->lbl_msg);
+ } else {
+ gtk_widget_hide (self->lbl_msg);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_MESSAGE]);
+}
+
+
+static void
+set_icon_name (PhoshGtkMountPrompt *self, const char *icon_name)
+{
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (!g_strcmp0 (self->icon_name, icon_name))
+ return;
+
+ g_clear_pointer (&self->icon_name, g_free);
+ self->icon_name = g_strdup (icon_name);
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (self->img_icon),
+ (icon_name && strlen (icon_name)) ?
+ self->icon_name : "dialog-password",
+ GTK_ICON_SIZE_DIALOG);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
+}
+
+
+static void
+set_default_user (PhoshGtkMountPrompt *self, const char *default_user)
+{
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (!g_strcmp0 (self->default_user, default_user))
+ return;
+
+ g_clear_pointer (&self->default_user, g_free);
+ self->default_user = g_strdup (default_user);
+
+ gtk_entry_set_text (GTK_ENTRY (self->entry_domain), self->default_user);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEFAULT_USER]);
+}
+
+
+static void
+set_default_domain (PhoshGtkMountPrompt *self, const char *default_domain)
+{
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (!g_strcmp0 (self->default_domain, default_domain))
+ return;
+
+ g_clear_pointer (&self->default_domain, g_free);
+ self->default_domain = g_strdup (default_domain);
+
+ gtk_entry_set_text (GTK_ENTRY (self->entry_domain), self->default_domain);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEFAULT_DOMAIN]);
+}
+
+
+static void
+on_button_clicked (PhoshGtkMountPrompt *self, GtkButton *btn)
+{
+ int num;
+
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+ g_return_if_fail (GTK_IS_BUTTON (btn));
+
+ num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (btn), "phosh-num"));
+ self->choice = num;
+
+ g_signal_emit (self, signals[CLOSED], 0);
+}
+
+
+static void
+set_choices (PhoshGtkMountPrompt *self, GStrv choices)
+{
+ g_autoptr (GList) buttons = NULL;
+
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (choices == NULL)
+ return;
+
+ g_clear_pointer (&self->choices, g_strfreev);
+ self->choices = g_strdupv (choices);
+ buttons = phosh_system_modal_dialog_get_buttons (PHOSH_SYSTEM_MODAL_DIALOG (self));
+ for (GList *elem = buttons; elem; elem = elem->next)
+ gtk_widget_destroy (GTK_WIDGET (elem->data));
+
+ for (int i = 0; i < g_strv_length (self->choices); i++) {
+ GtkWidget *btn = gtk_button_new_with_label (self->choices[i]);
+ g_object_set_data (G_OBJECT (btn), "phosh-num", GINT_TO_POINTER (i));
+ gtk_widget_show (GTK_WIDGET (btn));
+ phosh_system_modal_dialog_add_button (PHOSH_SYSTEM_MODAL_DIALOG (self), btn, -1);
+ g_signal_connect_swapped (btn, "clicked", G_CALLBACK (on_button_clicked), self);
+
+ if (i == 0) {
+ GtkStyleContext *context = gtk_widget_get_style_context (btn);
+ gtk_style_context_add_class (context, "suggested-action");
+ gtk_widget_grab_focus (btn);
+ }
+ }
+ set_entries_visible (self, FALSE);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CHOICES]);
+}
+
+
+static void
+set_ask_flags (PhoshGtkMountPrompt *self, GAskPasswordFlags flags)
+{
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (self->ask_flags == flags)
+ return;
+
+ self->ask_flags = flags;
+ g_debug ("Flags 0x%.2x", flags);
+
+ if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED) {
+ /* TODO */
+ }
+
+ set_visible (!!(flags & G_ASK_PASSWORD_NEED_PASSWORD),
+ self->lbl_password, self->entry_password, NULL);
+
+ set_visible (!!(flags & G_ASK_PASSWORD_NEED_USERNAME),
+ self->lbl_user, self->entry_user, NULL);
+
+ set_visible (!!(flags & G_ASK_PASSWORD_NEED_DOMAIN),
+ self->lbl_domain, self->entry_domain, NULL);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ASK_FLAGS]);
+}
+
+
+static void
+phosh_gtk_mount_prompt_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshGtkMountPrompt *self = PHOSH_GTK_MOUNT_PROMPT (obj);
+
+ switch (prop_id) {
+ case PROP_MESSAGE:
+ set_message (self, g_value_get_string (value));
+ break;
+ case PROP_ICON_NAME:
+ set_icon_name (self, g_value_get_string (value));
+ break;
+ case PROP_DEFAULT_USER:
+ set_default_user (self, g_value_get_string (value));
+ break;
+ case PROP_DEFAULT_DOMAIN:
+ set_default_domain (self, g_value_get_string (value));
+ break;
+ case PROP_CHOICES:
+ set_choices (self, g_value_get_boxed (value));
+ break;
+ case PROP_PIDS:
+ phosh_gtk_mount_prompt_set_pids (self, g_value_get_variant (value));
+ break;
+ case PROP_ASK_FLAGS:
+ set_ask_flags (self, g_value_get_flags (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_gtk_mount_prompt_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshGtkMountPrompt *self = PHOSH_GTK_MOUNT_PROMPT (obj);
+
+ switch (prop_id) {
+ case PROP_MESSAGE:
+ g_value_set_string (value, self->message ?: "");
+ break;
+ case PROP_ICON_NAME:
+ g_value_set_string (value, self->icon_name ?: "");
+ break;
+ case PROP_DEFAULT_USER:
+ g_value_set_string (value, self->default_user ?: "");
+ break;
+ case PROP_DEFAULT_DOMAIN:
+ g_value_set_string (value, self->default_domain ?: "");
+ break;
+ case PROP_CHOICES:
+ g_value_set_boxed (value, self->choices);
+ break;
+ case PROP_PIDS:
+ g_value_set_variant (value, self->pids);
+ break;
+ case PROP_ASK_FLAGS:
+ g_value_set_enum (value, self->ask_flags);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+on_connect_clicked (PhoshGtkMountPrompt *self)
+{
+ g_signal_emit (self, signals[CLOSED], 0);
+}
+
+
+static void
+on_dialog_canceled (PhoshGtkMountPrompt *self)
+{
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ self->cancelled = TRUE;
+
+ g_signal_emit (self, signals[CLOSED], 0);
+}
+
+
+static void
+on_pw_vis_icon_press (PhoshGtkMountPrompt *self,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event,
+ GtkEntry *entry)
+{
+ const char *icon_name = "eye-not-looking-symbolic";
+
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+ g_return_if_fail (icon_pos == GTK_ENTRY_ICON_SECONDARY);
+
+ self->pw_visible = !self->pw_visible;
+ gtk_entry_set_visibility (entry, self->pw_visible);
+ if (self->pw_visible)
+ icon_name = "eye-open-negative-filled-symbolic";
+
+ gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY,
+ icon_name);
+}
+
+
+static void
+phosh_gtk_mount_prompt_finalize (GObject *obj)
+{
+ PhoshGtkMountPrompt *self = PHOSH_GTK_MOUNT_PROMPT (obj);
+
+ g_free (self->message);
+ g_free (self->icon_name);
+ g_free (self->default_user);
+ g_free (self->default_domain);
+ g_clear_pointer (&self->choices, g_strfreev);
+ g_clear_pointer (&self->pids, g_variant_unref);
+
+ G_OBJECT_CLASS (phosh_gtk_mount_prompt_parent_class)->finalize (obj);
+}
+
+
+static void
+phosh_gtk_mount_prompt_class_init (PhoshGtkMountPromptClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *)klass;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = phosh_gtk_mount_prompt_get_property;
+ object_class->set_property = phosh_gtk_mount_prompt_set_property;
+ object_class->finalize = phosh_gtk_mount_prompt_finalize;
+
+ props[PROP_MESSAGE] =
+ g_param_spec_string ("message",
+ "",
+ "",
+ "",
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_ICON_NAME] =
+ g_param_spec_string ("icon-name",
+ "",
+ "",
+ "",
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_DEFAULT_USER] =
+ g_param_spec_string ("default-user",
+ "",
+ "",
+ "",
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_DEFAULT_DOMAIN] =
+ g_param_spec_string ("default-domain",
+ "",
+ "",
+ "",
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_CHOICES] =
+ g_param_spec_boxed ("choices",
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_PIDS] =
+ g_param_spec_variant ("pids",
+ "",
+ "",
+ G_VARIANT_TYPE_ARRAY,
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ props[PROP_ASK_FLAGS] =
+ g_param_spec_flags ("ask-flags",
+ "",
+ "",
+ G_TYPE_ASK_PASSWORD_FLAGS,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ signals[CLOSED] = g_signal_new ("closed",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/sm/puri/phosh/ui/gtk-mount-prompt.ui");
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, lbl_msg);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, lbl_password);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, lbl_user);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, lbl_domain);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, img_icon);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, entry_password);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, entry_user);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, entry_domain);
+ gtk_widget_class_bind_template_child (widget_class, PhoshGtkMountPrompt, password_buffer);
+ gtk_widget_class_bind_template_callback (widget_class, on_connect_clicked);
+ gtk_widget_class_bind_template_callback (widget_class, on_dialog_canceled);
+ gtk_widget_class_bind_template_callback (widget_class, on_pw_vis_icon_press);
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-gtk-mount-prompt");
+}
+
+
+static void
+phosh_gtk_mount_prompt_init (PhoshGtkMountPrompt *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+
+GtkWidget *
+phosh_gtk_mount_prompt_new (const char *message,
+ const char *icon_name,
+ const char *default_user,
+ const char *default_domain,
+ GVariant *pids,
+ const char *const *choices,
+ GAskPasswordFlags ask_flags)
+{
+ return g_object_new (PHOSH_TYPE_GTK_MOUNT_PROMPT,
+ "message", message,
+ "icon-name", icon_name,
+ "ask-flags", ask_flags,
+ "default-user", default_user,
+ "default-domain", default_domain,
+ "pids", pids,
+ "choices", choices,
+ NULL);
+}
+
+
+const char *
+phosh_gtk_mount_prompt_get_password (PhoshGtkMountPrompt *self)
+{
+ g_return_val_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self), NULL);
+
+ return gtk_entry_buffer_get_text (self->password_buffer);
+}
+
+
+GAskPasswordFlags
+phosh_gtk_mount_prompt_get_ask_flags (PhoshGtkMountPrompt *self)
+{
+ g_return_val_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self), 0);
+
+ return self->ask_flags;
+}
+
+
+/**
+ * phosh_gtk_mount_prompt_get_cancelled:
+ * @self: The #PhoshGtkMountPrompt
+ *
+ * Returns: %TRUE if the dialog was cancelled (e.g. via swipe
+ * away or pressing the Esc-key.
+ */
+gboolean
+phosh_gtk_mount_prompt_get_cancelled (PhoshGtkMountPrompt *self)
+{
+ g_return_val_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self), FALSE);
+
+ return self->cancelled;
+}
+
+
+const GStrv
+phosh_gtk_mount_prompt_get_choices (PhoshGtkMountPrompt *self)
+{
+ g_return_val_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self), NULL);
+
+ return self->choices;
+}
+
+
+int
+phosh_gtk_mount_prompt_get_choice (PhoshGtkMountPrompt *self)
+{
+ g_return_val_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self), -1);
+
+ return self->choice;
+}
+
+
+void
+phosh_gtk_mount_prompt_set_pids (PhoshGtkMountPrompt *self, GVariant *pids)
+{
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (self));
+
+ if (self->pids == pids)
+ return;
+
+ g_clear_pointer (&self->pids, g_variant_unref);
+
+ if (pids)
+ self->pids = g_variant_ref (pids);
+
+ /* TODO: update ui */
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PIDS]);
+}
diff -Nru phosh-0.8.0/src/gtk-mount-prompt.h phosh-0.13.1/src/gtk-mount-prompt.h
--- phosh-0.8.0/src/gtk-mount-prompt.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/gtk-mount-prompt.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "system-modal-dialog.h"
+
+#define PHOSH_TYPE_GTK_MOUNT_PROMPT (phosh_gtk_mount_prompt_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshGtkMountPrompt, phosh_gtk_mount_prompt, PHOSH, GTK_MOUNT_PROMPT, PhoshSystemModalDialog)
+
+GtkWidget *phosh_gtk_mount_prompt_new (const char *message,
+ const char *icon_name,
+ const char *default_user,
+ const char *default_domain,
+ GVariant *pids,
+ const char *const *choices,
+ GAskPasswordFlags ask_flags);
+const gchar *phosh_gtk_mount_prompt_get_password (PhoshGtkMountPrompt *self);
+GAskPasswordFlags phosh_gtk_mount_prompt_get_ask_flags (PhoshGtkMountPrompt *self);
+gboolean phosh_gtk_mount_prompt_get_cancelled (PhoshGtkMountPrompt *self);
+int phosh_gtk_mount_prompt_get_choice (PhoshGtkMountPrompt *self);
+const GStrv phosh_gtk_mount_prompt_get_choices (PhoshGtkMountPrompt *self);
+void phosh_gtk_mount_prompt_set_pids (PhoshGtkMountPrompt *self, GVariant *pids);
diff -Nru phosh-0.8.0/src/hks-info.c phosh-0.13.1/src/hks-info.c
--- phosh-0.8.0/src/hks-info.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/hks-info.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-hks-info"
+
+#include "config.h"
+
+#include "shell.h"
+#include "hks-info.h"
+#include "hks-manager.h"
+
+/**
+ * SECTION:hks-info
+ * @short_description: A widget to display the HKS status of a device
+ * @Title: PhoshHksInfo
+ *
+ * #PhoshHksInfo displays whether a device is disabled via a hardware
+ * kill switch (HKS).
+ */
+
+enum {
+ PROP_0,
+ PROP_DEV_TYPE,
+ PROP_BLOCKED,
+ PROP_PRESENT,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+
+struct _PhoshHksInfo {
+ PhoshStatusIcon parent;
+
+ char *dev_type;
+ gboolean blocked;
+ gboolean present;
+ PhoshHksManager *manager;
+};
+G_DEFINE_TYPE (PhoshHksInfo, phosh_hks_info, PHOSH_TYPE_STATUS_ICON);
+
+
+static void
+phosh_hks_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshHksInfo *self = PHOSH_HKS_INFO (object);
+
+ switch (property_id) {
+ case PROP_BLOCKED:
+ g_value_set_boolean (value, self->blocked);
+ break;
+ case PROP_PRESENT:
+ g_value_set_boolean (value, self->present);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_hks_info_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshHksInfo *self = PHOSH_HKS_INFO (object);
+
+ switch (prop_id) {
+ case PROP_DEV_TYPE:
+ /* construct only */
+ self->dev_type = g_value_dup_string (value);
+ break;
+ case PROP_BLOCKED:
+ self->blocked = g_value_get_boolean (value);
+ break;
+ case PROP_PRESENT:
+ self->present = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+
+static void
+phosh_hks_info_constructed (GObject *object)
+{
+ PhoshHksInfo *self = PHOSH_HKS_INFO (object);
+ PhoshShell *shell;
+ g_autofree gchar *propname = NULL;
+
+ G_OBJECT_CLASS (phosh_hks_info_parent_class)->constructed (object);
+
+ shell = phosh_shell_get_default ();
+ self->manager = g_object_ref (phosh_shell_get_hks_manager (shell));
+
+ if (self->manager == NULL) {
+ g_warning ("Failed to get hks manager");
+ return;
+ }
+
+ propname = g_strdup_printf ("%s-present", self->dev_type);
+ g_object_bind_property (self->manager,
+ propname,
+ self,
+ "present",
+ G_BINDING_SYNC_CREATE);
+
+ g_free (propname);
+ propname = g_strdup_printf ("%s-blocked", self->dev_type);
+ g_object_bind_property (self->manager,
+ propname,
+ self,
+ "blocked",
+ G_BINDING_SYNC_CREATE);
+
+ g_free (propname);
+ propname = g_strdup_printf ("%s-icon-name", self->dev_type);
+ g_object_bind_property (self->manager,
+ propname,
+ self,
+ "icon-name",
+ G_BINDING_SYNC_CREATE);
+}
+
+
+static void
+phosh_hks_info_dispose (GObject *object)
+{
+ PhoshHksInfo *self = PHOSH_HKS_INFO (object);
+
+ g_clear_object (&self->manager);
+
+ G_OBJECT_CLASS (phosh_hks_info_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_hks_info_finalize (GObject *object)
+{
+ PhoshHksInfo *self = PHOSH_HKS_INFO (object);
+
+ g_clear_pointer (&self->dev_type, g_free);
+
+ G_OBJECT_CLASS (phosh_hks_info_parent_class)->finalize (object);
+}
+
+
+static void
+phosh_hks_info_class_init (PhoshHksInfoClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = phosh_hks_info_constructed;
+ object_class->dispose = phosh_hks_info_dispose;
+ object_class->finalize = phosh_hks_info_finalize;
+ object_class->get_property = phosh_hks_info_get_property;
+ object_class->set_property = phosh_hks_info_set_property;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-hks-info");
+
+ props[PROP_DEV_TYPE] =
+ g_param_spec_string ("device-type",
+ "Device type",
+ "The moniored device type",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_BLOCKED] =
+ g_param_spec_boolean ("blocked",
+ "blocked",
+ "Whether the device is blocked",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ props[PROP_PRESENT] =
+ g_param_spec_boolean ("present",
+ "Present",
+ "Whether hks hardware is present",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+}
+
+
+static void
+phosh_hks_info_init (PhoshHksInfo *self)
+{
+ phosh_status_icon_set_info (PHOSH_STATUS_ICON (self), "HKS");
+}
+
+
+GtkWidget *
+phosh_hks_info_new (void)
+{
+ return g_object_new (PHOSH_TYPE_HKS_INFO, NULL);
+}
diff -Nru phosh-0.8.0/src/hks-info.h phosh-0.13.1/src/hks-info.h
--- phosh-0.8.0/src/hks-info.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/hks-info.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "status-icon.h"
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_HKS_INFO (phosh_hks_info_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshHksInfo, phosh_hks_info, PHOSH, HKS_INFO, PhoshStatusIcon)
+
+GtkWidget * phosh_hks_info_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/hks-manager.c phosh-0.13.1/src/hks-manager.c
--- phosh-0.8.0/src/hks-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/hks-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-hks-manager"
+
+#include "config.h"
+
+#include "hks-manager.h"
+#include "shell.h"
+
+#include
+#include
+#include
+#include
+#include
+
+
+#ifdef HAVE_RFKILL_EVENT_EXT
+typedef struct rfkill_event_ext RfKillEvent;
+#else
+typedef struct rfkill_event RfKillEvent;
+#endif
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (RfKillEvent, g_free);
+
+/* rfkill types not yet upstream */
+#define RFKILL_TYPE_CAMERA_ 9
+#define RFKILL_TYPE_MIC_ 10
+
+/**
+ * SECTION:hks-manager
+ * @short_description: Tracks hardware kill switch state
+ * @Title: PhoshHksManager
+ *
+ * Monitor hardware kill switch state. This will be submitted to gnome-settings-daemon
+ * once we figured out the kernel interfaces.
+ */
+
+typedef enum {
+ PROP_0,
+ /* Each hks must be in the order of present, blocked, icon_name */
+ PROP_MIC_PRESENT,
+ PROP_MIC_BLOCKED,
+ PROP_MIC_ICON_NAME,
+ PROP_CAMERA_PRESENT,
+ PROP_CAMERA_BLOCKED,
+ PROP_CAMERA_ICON_NAME,
+ PROP_LAST_PROP
+} PhoshHksManagerProps;
+static GParamSpec *props[PROP_LAST_PROP];
+
+
+enum {
+ HKS_STATE_BLOCKED = 0,
+ HKS_STATE_UNBLOCKED = 1,
+};
+
+
+typedef struct {
+ gboolean present;
+ gboolean blocked;
+ gchar *blocked_icon_name;
+ gchar *unblocked_icon_name;
+ GHashTable *killswitches;
+} Hks;
+
+
+struct _PhoshHksManager {
+ GObject parent;
+
+ GIOChannel *channel;
+ int watch_id;
+
+ Hks mic;
+ Hks camera;
+};
+G_DEFINE_TYPE (PhoshHksManager, phosh_hks_manager, G_TYPE_OBJECT);
+
+
+static void
+phosh_hks_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshHksManager *self = PHOSH_HKS_MANAGER (object);
+ const gchar *icon_name;
+
+ switch (property_id) {
+ case PROP_MIC_PRESENT:
+ g_value_set_boolean (value, self->mic.present);
+ break;
+ case PROP_MIC_BLOCKED:
+ g_value_set_boolean (value, self->mic.blocked);
+ break;
+ case PROP_MIC_ICON_NAME:
+ icon_name = self->mic.blocked ?
+ self->mic.blocked_icon_name : self->mic.unblocked_icon_name;
+ g_value_set_string (value, icon_name);
+ break;
+ case PROP_CAMERA_PRESENT:
+ g_value_set_boolean (value, self->camera.present);
+ break;
+ case PROP_CAMERA_BLOCKED:
+ g_value_set_boolean (value, self->camera.blocked);
+ break;
+ case PROP_CAMERA_ICON_NAME:
+ icon_name = self->camera.blocked ?
+ self->camera.blocked_icon_name : self->camera.unblocked_icon_name;
+ g_value_set_string (value, icon_name);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static const char *
+type_to_string (unsigned int type)
+{
+ switch (type) {
+ case RFKILL_TYPE_ALL:
+ return "ALL";
+ case RFKILL_TYPE_WLAN:
+ return "WLAN";
+ case RFKILL_TYPE_BLUETOOTH:
+ return "BLUETOOTH";
+ case RFKILL_TYPE_UWB:
+ return "UWB";
+ case RFKILL_TYPE_WIMAX:
+ return "WIMAX";
+ case RFKILL_TYPE_WWAN:
+ return "WWAN";
+ case RFKILL_TYPE_CAMERA_:
+ return "CAMERA";
+ case RFKILL_TYPE_MIC_:
+ return "MIC";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+
+static const char *
+op_to_string (unsigned int op)
+{
+ switch (op) {
+ case RFKILL_OP_ADD:
+ return "ADD";
+ case RFKILL_OP_DEL:
+ return "DEL";
+ case RFKILL_OP_CHANGE:
+ return "CHANGE";
+ case RFKILL_OP_CHANGE_ALL:
+ return "CHANGE_ALL";
+ default:
+ return "Unknown";
+ }
+}
+
+
+static void
+print_event (RfKillEvent *event)
+{
+ g_debug ("RFKILL event: idx %u type %u (%s) op %u (%s) soft %u hard %u",
+ event->idx,
+ event->type, type_to_string (event->type),
+ event->op, op_to_string (event->op),
+ event->soft, event->hard);
+}
+
+
+static void
+update_props (PhoshHksManager *self, Hks *hks, PhoshHksManagerProps prop)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ gboolean blocked = FALSE;
+
+ if (g_hash_table_size (hks->killswitches) == 0) {
+ if (!hks->present)
+ return;
+
+ if (hks->blocked) {
+ hks->blocked = FALSE;
+ g_object_notify_by_pspec (G_OBJECT (self), props[prop+1]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[prop+2]);
+ }
+
+ hks->present = FALSE;
+ g_object_notify_by_pspec (G_OBJECT (self), props[prop]);
+ return;
+ }
+
+ g_hash_table_iter_init (&iter, hks->killswitches);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ int state;
+
+ state = GPOINTER_TO_INT (value);
+ /* A single blocked switch is enough */
+ if (state == HKS_STATE_BLOCKED) {
+ blocked = TRUE;
+ break;
+ }
+ }
+
+ if (!hks->present) {
+ hks->present = TRUE;
+ g_object_notify_by_pspec (G_OBJECT (self), props[prop]);
+ }
+
+ if (blocked == hks->blocked)
+ return;
+ hks->blocked = blocked;
+
+ /* blocked property */
+ g_object_notify_by_pspec (G_OBJECT (self), props[prop + 1]);
+ /* icon_name property */
+ g_object_notify_by_pspec (G_OBJECT (self), props[prop + 2]);
+}
+
+
+static void
+process_events (PhoshHksManager *self, GList *events)
+{
+ GList *l;
+ int value;
+
+ for (l = events; l != NULL; l = l->next) {
+ RfKillEvent *event = l->data;
+
+ switch (event->op) {
+ case RFKILL_OP_ADD:
+ case RFKILL_OP_CHANGE:
+ value = event->hard ? HKS_STATE_BLOCKED : HKS_STATE_UNBLOCKED;
+
+ if (event->type == RFKILL_TYPE_MIC_) {
+ g_hash_table_insert (self->mic.killswitches,
+ GINT_TO_POINTER (event->idx),
+ GINT_TO_POINTER (value));
+ } else if (event->type == RFKILL_TYPE_CAMERA_) {
+ g_hash_table_insert (self->camera.killswitches,
+ GINT_TO_POINTER (event->idx),
+ GINT_TO_POINTER (value));
+ }
+ g_debug ("%s rfkill type %d, ID %d",
+ event->op == RFKILL_OP_ADD ? "Added" : "Changed",
+ event->type, event->idx);
+ break;
+ case RFKILL_OP_DEL:
+ if (event->type == RFKILL_TYPE_MIC_) {
+ g_hash_table_remove (self->mic.killswitches,
+ GINT_TO_POINTER (event->idx));
+ } else if (event->type == RFKILL_TYPE_CAMERA_) {
+ g_hash_table_remove (self->camera.killswitches,
+ GINT_TO_POINTER (event->idx));
+ }
+ g_debug ("Removed rfkill type %d, ID %d",
+ event->type, event->idx);
+ break;
+ default:
+ /* Nothing to do */
+ break;
+ }
+ }
+
+ g_object_freeze_notify (G_OBJECT (self));
+ update_props (self, &self->mic, PROP_MIC_PRESENT);
+ update_props (self, &self->camera, PROP_CAMERA_PRESENT);
+ g_object_thaw_notify (G_OBJECT (self));
+
+
+}
+
+
+static gboolean
+rfkill_event_cb (GIOChannel *source,
+ GIOCondition condition,
+ PhoshHksManager *self)
+{
+ g_autolist (RfKillEvent) events = NULL;
+
+ if (condition & G_IO_IN) {
+ GIOStatus status;
+ RfKillEvent event = { 0 };
+ RfKillEvent *event_ptr;
+ gsize read;
+
+ status = g_io_channel_read_chars (source,
+ (char *) &event,
+ sizeof(event),
+ &read,
+ NULL);
+
+ while (status == G_IO_STATUS_NORMAL && read >= RFKILL_EVENT_SIZE_V1) {
+ print_event (&event);
+ event_ptr = g_memdup (&event, sizeof(event));
+ events = g_list_prepend (events, event_ptr);
+
+ status = g_io_channel_read_chars (source,
+ (char *) &event,
+ sizeof(event),
+ &read,
+ NULL);
+ }
+ events = g_list_reverse (events);
+ } else {
+ g_debug ("Something unexpected happened on rfkill fd");
+ return FALSE;
+ }
+
+ process_events (self, events);
+ return TRUE;
+}
+
+
+static gboolean
+setup_rfkill (PhoshHksManager *self)
+{
+ int fd, ret;
+ g_autolist (RfKillEvent) events = NULL;
+
+ fd = open ("/dev/rfkill", O_RDONLY);
+ if (fd < 0)
+ return FALSE;
+
+ ret = fcntl (fd, F_SETFL, O_NONBLOCK);
+ if (ret < 0) {
+ g_warning ("Can't set RFKILL control device to non-blocking: %s", strerror (errno));
+ close (fd);
+ return FALSE;
+ }
+
+ while (1) {
+ RfKillEvent event;
+ RfKillEvent *event_ptr;
+ ssize_t len;
+
+ len = read (fd, &event, sizeof(event));
+ if (len < 0) {
+ if (errno == EAGAIN)
+ break;
+ g_debug ("Reading of RFKILL events failed");
+ break;
+ }
+
+ if (len < RFKILL_EVENT_SIZE_V1) {
+ g_warning ("Wrong size of RFKILL event\n");
+ continue;
+ }
+
+ if (event.op != RFKILL_OP_ADD)
+ continue;
+
+ g_debug ("Read killswitch of type '%s' (idx=%d): soft %d hard %d",
+ type_to_string (event.type),
+ event.idx, event.soft, event.hard);
+
+ event_ptr = g_memdup (&event, sizeof(event));
+ events = g_list_prepend (events, event_ptr);
+ }
+
+ /* Setup monitoring */
+ self->channel = g_io_channel_unix_new (fd);
+ g_io_channel_set_encoding (self->channel, NULL, NULL);
+ self->watch_id = g_io_add_watch (self->channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
+ (GIOFunc) rfkill_event_cb,
+ self);
+
+ if (events) {
+ events = g_list_reverse (events);
+ process_events (self, events);
+ } else {
+ g_debug ("No rfkill device available on startup");
+ }
+
+ return TRUE;
+}
+
+
+static void
+phosh_hks_manager_constructed (GObject *object)
+{
+ PhoshHksManager *self = PHOSH_HKS_MANAGER (object);
+
+ self->mic.killswitches = g_hash_table_new (g_direct_hash, g_direct_equal);
+ self->mic.blocked_icon_name = "microphone-hardware-disabled-symbolic";
+ self->mic.unblocked_icon_name = "microphone-sensitivity-high-symbolic";
+
+ self->camera.killswitches = g_hash_table_new (g_direct_hash, g_direct_equal);
+ self->camera.blocked_icon_name = "camera-hardware-disabled-symbolic";
+ self->camera.unblocked_icon_name = "camera-photo-symbolic";
+
+ setup_rfkill (self);
+
+ G_OBJECT_CLASS (phosh_hks_manager_parent_class)->constructed (object);
+}
+
+
+static void
+phosh_hks_manager_dispose (GObject *object)
+{
+ PhoshHksManager *self = PHOSH_HKS_MANAGER (object);
+
+ if (self->watch_id > 0) {
+ g_source_remove (self->watch_id);
+ self->watch_id = 0;
+ g_io_channel_shutdown (self->channel, FALSE, NULL);
+ g_io_channel_unref (self->channel);
+ }
+
+ G_OBJECT_CLASS (phosh_hks_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_hks_manager_finalize (GObject *object)
+{
+ PhoshHksManager *self = PHOSH_HKS_MANAGER (object);
+
+ g_clear_pointer (&self->mic.killswitches, g_hash_table_destroy);
+ g_clear_pointer (&self->camera.killswitches, g_hash_table_destroy);
+
+ G_OBJECT_CLASS (phosh_hks_manager_parent_class)->finalize (object);
+}
+
+
+static void
+phosh_hks_manager_class_init (PhoshHksManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = phosh_hks_manager_constructed;
+ object_class->dispose = phosh_hks_manager_dispose;
+ object_class->finalize = phosh_hks_manager_finalize;
+ object_class->get_property = phosh_hks_manager_get_property;
+
+ props[PROP_MIC_PRESENT] =
+ g_param_spec_boolean ("mic-present",
+ "Mic present",
+ "HKS capable microphone present",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_MIC_BLOCKED] =
+ g_param_spec_boolean ("mic-blocked",
+ "Mic blocked",
+ "Microphone blocked via hks",
+ TRUE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_MIC_ICON_NAME] =
+ g_param_spec_string ("mic-icon-name",
+ "Mic Icon Name",
+ "Icon for microphone hks",
+ "",
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_CAMERA_PRESENT] =
+ g_param_spec_boolean ("camera-present",
+ "Camera present",
+ "HKS capable camera present",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_CAMERA_BLOCKED] =
+ g_param_spec_boolean ("camera-blocked",
+ "Camera blocked",
+ "Camera blocked via hks",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_CAMERA_ICON_NAME] =
+ g_param_spec_string ("camera-icon-name",
+ "Camera Icon Name",
+ "Icon for camera hks",
+ "",
+ G_PARAM_READABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+}
+
+
+static void
+phosh_hks_manager_init (PhoshHksManager *self)
+{
+}
+
+
+PhoshHksManager *
+phosh_hks_manager_new (void)
+{
+ return PHOSH_HKS_MANAGER (g_object_new (PHOSH_TYPE_HKS_MANAGER, NULL));
+}
diff -Nru phosh-0.8.0/src/hks-manager.h phosh-0.13.1/src/hks-manager.h
--- phosh-0.8.0/src/hks-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/hks-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+
+
+G_BEGIN_DECLS
+
+/**
+ * PhoshHksDeviceType:
+ * @PHOSH_HKS_TYPE_MIC: Microphone hardware kill switch
+ *
+ * Keep in sync with kernels rfkill types
+ */
+typedef enum {
+ PHOSH_HKS_TYPE_MIC = 10,
+} PhoshHksDeviceType;
+
+
+#define PHOSH_TYPE_HKS_MANAGER (phosh_hks_manager_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshHksManager, phosh_hks_manager, PHOSH, HKS_MANAGER, GObject)
+
+PhoshHksManager *phosh_hks_manager_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/home.c phosh-0.13.1/src/home.c
--- phosh-0.8.0/src/home.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/home.c 2021-08-31 09:15:52.000000000 +0000
@@ -14,7 +14,7 @@
#include "home.h"
#include "shell.h"
#include "phosh-enums.h"
-#include "osk/osk-button.h"
+#include "osk-button.h"
#include
@@ -67,7 +67,7 @@
PhoshHomeState state;
/* Keybinding */
- GArray *actions;
+ GStrv action_names;
GSettings *settings;
/* osk button */
@@ -202,22 +202,32 @@
static gboolean
-key_press_event_cb (PhoshHome *self, GdkEventKey *event, gpointer data)
+window_key_press_event_cb (PhoshHome *self, GdkEvent *event, gpointer data)
{
- gboolean handled = FALSE;
- g_return_val_if_fail (PHOSH_IS_HOME (self), FALSE);
+ gboolean ret = GDK_EVENT_PROPAGATE;
+ guint keyval;
+ g_return_val_if_fail (PHOSH_IS_HOME (self), GDK_EVENT_PROPAGATE);
- switch (event->keyval) {
+ if (self->state != PHOSH_HOME_STATE_UNFOLDED)
+ return GDK_EVENT_PROPAGATE;
+
+ if (!gdk_event_get_keyval (event, &keyval))
+ return GDK_EVENT_PROPAGATE;
+
+ switch (keyval) {
case GDK_KEY_Escape:
phosh_home_set_state (self, PHOSH_HOME_STATE_FOLDED);
- handled = TRUE;
+ ret = GDK_EVENT_STOP;
break;
- default:
- /* nothing to do */
+ case GDK_KEY_Return:
+ ret = GDK_EVENT_PROPAGATE;
break;
+ default:
+ /* Focus search when typing */
+ ret = phosh_overview_handle_search (PHOSH_OVERVIEW (self->overview), event);
}
- return handled;
+ return ret;
}
@@ -253,74 +263,66 @@
static void
add_keybindings (PhoshHome *self)
{
- g_auto (GStrv) bindings = NULL;
+ GStrv overview_bindings;
+ GStrv app_view_bindings;
+ GPtrArray *action_names = g_ptr_array_new ();
g_autoptr (GSettings) settings = g_settings_new (KEYBINDINGS_SCHEMA_ID);
+ g_autoptr (GArray) actions = g_array_new (FALSE, TRUE, sizeof (GActionEntry));
- bindings = g_settings_get_strv (settings, KEYBINDING_KEY_TOGGLE_OVERVIEW);
- for (int i = 0; i < g_strv_length (bindings); i++) {
- GActionEntry entry = { bindings[i],
+ overview_bindings = g_settings_get_strv (settings, KEYBINDING_KEY_TOGGLE_OVERVIEW);
+ for (int i = 0; i < g_strv_length (overview_bindings); i++) {
+ GActionEntry entry = { overview_bindings[i],
toggle_overview_action, };
- g_array_append_val (self->actions, entry);
+ g_array_append_val (actions, entry);
+ g_ptr_array_add (action_names, overview_bindings[i]);
}
+ /* Free GStrv container but keep individual strings for action_names */
+ g_free (overview_bindings);
- bindings = g_settings_get_strv (settings, KEYBINDING_KEY_TOGGLE_APPLICATION_VIEW);
- for (int i = 0; i < g_strv_length (bindings); i++) {
- GActionEntry entry = { bindings[i],
+ app_view_bindings = g_settings_get_strv (settings, KEYBINDING_KEY_TOGGLE_APPLICATION_VIEW);
+ for (int i = 0; i < g_strv_length (app_view_bindings); i++) {
+ GActionEntry entry = { app_view_bindings[i],
toggle_application_view_action, };
- g_array_append_val (self->actions, entry);
+ g_array_append_val (actions, entry);
+ g_ptr_array_add (action_names, app_view_bindings[i]);
}
+ /* Free GStrv container but keep individual strings for action_names */
+ g_free (app_view_bindings);
+ g_ptr_array_add (action_names, NULL);
phosh_shell_add_global_keyboard_action_entries (phosh_shell_get_default (),
- (GActionEntry*)self->actions->data,
- self->actions->len,
+ (GActionEntry*) actions->data,
+ actions->len,
self);
+ self->action_names = (GStrv) g_ptr_array_free (action_names, FALSE);
}
static void
-on_keybindings_changed (PhoshHome *self,
+on_keybindings_changed (PhoshHome *self,
gchar *key,
GSettings *settings)
{
/* For now just redo all keybindings */
g_debug ("Updating keybindings");
phosh_shell_remove_global_keyboard_action_entries (phosh_shell_get_default (),
- (GActionEntry*)self->actions->data,
- self->actions->len);
- g_array_set_size (self->actions, 0);
+ self->action_names);
+ g_clear_pointer (&self->action_names, g_strfreev);
add_keybindings (self);
}
-static gboolean
-on_idle (PhoshOskButton *self)
-{
- g_autoptr (GSettings) settings = NULL;
-
- settings = g_settings_new ("org.gnome.desktop.a11y.applications");
- g_settings_bind (settings, "screen-keyboard-enabled",
- self, "osk-enabled", G_SETTINGS_BIND_GET);
-
- return FALSE;
-}
-
-
static void
phosh_home_constructed (GObject *object)
{
PhoshHome *self = PHOSH_HOME (object);
+ g_autoptr (GSettings) settings = NULL;
g_signal_connect (self,
"configured",
G_CALLBACK (phosh_home_resize),
NULL);
- gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
- g_signal_connect (G_OBJECT (self),
- "key_press_event",
- G_CALLBACK (key_press_event_cb),
- NULL);
-
g_object_connect (self->settings,
"swapped-signal::changed::" KEYBINDING_KEY_TOGGLE_OVERVIEW,
on_keybindings_changed, self,
@@ -331,7 +333,9 @@
phosh_connect_feedback (self->btn_home);
- g_idle_add ((GSourceFunc) on_idle, self);
+ settings = g_settings_new ("org.gnome.desktop.a11y.applications");
+ g_settings_bind (settings, "screen-keyboard-enabled",
+ self, "osk-enabled", G_SETTINGS_BIND_GET);
G_OBJECT_CLASS (phosh_home_parent_class)->constructed (object);
}
@@ -344,11 +348,10 @@
g_clear_object (&self->settings);
- if (self->actions) {
+ if (self->action_names) {
phosh_shell_remove_global_keyboard_action_entries (phosh_shell_get_default (),
- (GActionEntry*)self->actions->data,
- self->actions->len);
- g_clear_pointer (&self->actions, g_array_unref);
+ self->action_names);
+ g_clear_pointer (&self->action_names, g_strfreev);
}
G_OBJECT_CLASS (phosh_home_parent_class)->dispose (object);
@@ -403,6 +406,7 @@
gtk_widget_class_bind_template_callback (widget_class, home_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_has_activities_changed);
gtk_widget_class_bind_template_callback (widget_class, osk_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, window_key_press_event_cb);
gtk_widget_class_set_css_name (widget_class, "phosh-home");
}
@@ -413,7 +417,6 @@
{
self->state = PHOSH_HOME_STATE_FOLDED;
self->animation.progress = 1.0;
- self->actions = g_array_new (FALSE, TRUE, sizeof (GActionEntry));
self->settings = g_settings_new (KEYBINDINGS_SCHEMA_ID);
gtk_widget_init_template (GTK_WIDGET (self));
@@ -462,7 +465,20 @@
phosh_home_resize (self);
- return finished ? G_SOURCE_REMOVE : G_SOURCE_CONTINUE;
+ if (finished) {
+ if (self->state == PHOSH_HOME_STATE_FOLDED)
+ gtk_widget_hide (GTK_WIDGET (self->overview));
+ return G_SOURCE_REMOVE;
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+
+static double
+reverse_ease_out_cubic (double t)
+{
+ return cbrt(t - 1) + 1;
}
@@ -493,12 +509,13 @@
g_debug ("Setting state to %s", state_name);
self->animation.last_frame = -1;
- self->animation.progress = enable_animations ? (1.0 - self->animation.progress) : 1.0;
+ self->animation.progress = enable_animations ? reverse_ease_out_cubic (1.0 - hdy_ease_out_cubic (self->animation.progress)) : 1.0;
gtk_widget_add_tick_callback (GTK_WIDGET (self), animate_cb, NULL, NULL);
if (state == PHOSH_HOME_STATE_UNFOLDED) {
kbd_interactivity = TRUE;
phosh_overview_reset (PHOSH_OVERVIEW (self->overview));
+ gtk_widget_show (GTK_WIDGET (self->overview));
} else {
kbd_interactivity = FALSE;
}
@@ -509,3 +526,12 @@
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HOME_STATE]);
}
+
+
+PhoshOverview*
+phosh_home_get_overview (PhoshHome *self)
+{
+ g_return_val_if_fail (PHOSH_IS_HOME (self), NULL);
+
+ return PHOSH_OVERVIEW (self->overview);
+}
diff -Nru phosh-0.8.0/src/home.h phosh-0.13.1/src/home.h
--- phosh-0.8.0/src/home.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/home.h 2021-08-31 09:15:52.000000000 +0000
@@ -5,8 +5,10 @@
*/
#pragma once
-#include
#include "layersurface.h"
+#include "overview.h"
+
+#include
#define PHOSH_TYPE_HOME (phosh_home_get_type())
@@ -29,3 +31,4 @@
GtkWidget * phosh_home_new (struct zwlr_layer_shell_v1 *layer_shell,
struct wl_output *wl_output);
void phosh_home_set_state (PhoshHome *self, PhoshHomeState state);
+PhoshOverview *phosh_home_get_overview (PhoshHome *self);
diff -Nru phosh-0.8.0/src/idle-manager.c phosh-0.13.1/src/idle-manager.c
--- phosh-0.8.0/src/idle-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/idle-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -367,7 +367,7 @@
const char *name,
gpointer user_data)
{
- PhoshIdleManager *self = user_data;
+ PhoshIdleManager *self = PHOSH_IDLE_MANAGER (user_data);
PhoshMonitor *monitor;
g_autofree char *path = NULL;
@@ -389,8 +389,10 @@
{
PhoshIdleManager *self = PHOSH_IDLE_MANAGER (object);
- g_hash_table_destroy (self->watches);
- g_object_unref (self->manager);
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
+
+ g_clear_pointer (&self->watches, g_hash_table_destroy);
+ g_clear_object (&self->manager);
G_OBJECT_CLASS (phosh_idle_manager_parent_class)->dispose (object);
}
@@ -431,7 +433,7 @@
static void
phosh_idle_manager_init (PhoshIdleManager *self)
{
- self->dbus_name_id = -1;
+ self->dbus_name_id = 0;
}
diff -Nru phosh-0.8.0/src/layersurface.c phosh-0.13.1/src/layersurface.c
--- phosh-0.8.0/src/layersurface.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/layersurface.c 2021-08-31 09:15:52.000000000 +0000
@@ -327,7 +327,6 @@
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
priv = phosh_layer_surface_get_instance_private (self);
- priv = phosh_layer_surface_get_instance_private (self);
if (priv->layer_surface) {
zwlr_layer_surface_v1_destroy (priv->layer_surface);
priv->layer_surface = NULL;
@@ -387,14 +386,14 @@
"layer-shell",
"Wayland Layer Shell Global",
"The layer shell wayland global",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
props[PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT] =
g_param_spec_pointer (
"wl-output",
"Wayland Output",
"The wl_output associated with this surface",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
props[PHOSH_LAYER_SURFACE_PROP_ANCHOR] =
g_param_spec_uint (
@@ -404,7 +403,7 @@
0,
G_MAXUINT,
0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
props[PHOSH_LAYER_SURFACE_PROP_LAYER] =
g_param_spec_uint (
@@ -414,7 +413,7 @@
0,
G_MAXUINT,
0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY] =
g_param_spec_boolean (
@@ -521,7 +520,7 @@
"Namespace",
"Namespace of the layer surface",
"",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, PHOSH_LAYER_SURFACE_PROP_LAST_PROP, props);
diff -Nru phosh-0.8.0/src/location-info.c phosh-0.13.1/src/location-info.c
--- phosh-0.8.0/src/location-info.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/location-info.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-location-info"
+
+#include "config.h"
+
+#include "location-info.h"
+#include "location-manager.h"
+
+#include "shell.h"
+
+/**
+ * SECTION:location-info
+ * @short_description: A widget to display the location service status
+ * @Title: PhoshLocationInfo
+ *
+ * #PhoshLocationInfo indicates if the location service is active.
+ * The widgets container should hide the widget if
+ * #PhoshLocationInfo:active is %FALSE.
+ */
+
+enum {
+ PROP_0,
+ PROP_ACTIVE,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+struct _PhoshLocationInfo {
+ PhoshStatusIcon parent;
+
+ gboolean active;
+ PhoshLocationManager *manager;
+};
+G_DEFINE_TYPE (PhoshLocationInfo, phosh_location_info, PHOSH_TYPE_STATUS_ICON);
+
+
+static void
+phosh_location_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshLocationInfo *self = PHOSH_LOCATION_INFO (object);
+
+ switch (property_id) {
+ case PROP_ACTIVE:
+ g_value_set_boolean (value, self->active);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_location_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshLocationInfo *self = PHOSH_LOCATION_INFO (object);
+
+ switch (property_id) {
+ case PROP_ACTIVE:
+ self->active = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static gboolean
+active_to_icon_name (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ gboolean active = g_value_get_boolean (from_value);
+
+ g_value_set_string (to_value, active ? "location-services-active-symbolic" :
+ "location-services-disabled-symbolic");
+ return TRUE;
+}
+
+
+static void
+phosh_location_info_constructed (GObject *object)
+{
+ PhoshLocationInfo *self = PHOSH_LOCATION_INFO (object);
+ PhoshShell *shell = phosh_shell_get_default ();;
+
+ self->manager = g_object_ref (phosh_shell_get_location_manager (shell));
+
+ g_object_bind_property (self->manager, "active",
+ self,"active",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property_full (self->manager, "active",
+ self,"icon-name",
+ G_BINDING_SYNC_CREATE,
+ active_to_icon_name,
+ NULL, NULL, NULL);
+
+ G_OBJECT_CLASS (phosh_location_info_parent_class)->constructed (object);
+}
+
+
+static void
+phosh_location_info_dispose (GObject *object)
+{
+ PhoshLocationInfo *self = PHOSH_LOCATION_INFO (object);
+
+ g_clear_object (&self->manager);
+
+ G_OBJECT_CLASS (phosh_location_info_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_location_info_class_init (PhoshLocationInfoClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = phosh_location_info_constructed;
+ object_class->dispose = phosh_location_info_dispose;
+ object_class->get_property = phosh_location_info_get_property;
+ object_class->set_property = phosh_location_info_set_property;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-location-info");
+
+ props[PROP_ACTIVE] =
+ g_param_spec_boolean ("active",
+ "Active",
+ "Whether the location service is active (in use)",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+}
+
+
+static void
+phosh_location_info_init (PhoshLocationInfo *self)
+{
+}
+
+
+GtkWidget *
+phosh_location_info_new (void)
+{
+ return g_object_new (PHOSH_TYPE_LOCATION_INFO, NULL);
+}
diff -Nru phosh-0.8.0/src/location-info.h phosh-0.13.1/src/location-info.h
--- phosh-0.8.0/src/location-info.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/location-info.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "status-icon.h"
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_LOCATION_INFO (phosh_location_info_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshLocationInfo, phosh_location_info, PHOSH, LOCATION_INFO, PhoshStatusIcon)
+
+GtkWidget * phosh_location_info_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/location-manager.c phosh-0.13.1/src/location-manager.c
--- phosh-0.8.0/src/location-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/location-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-location-manager"
+
+#include "config.h"
+
+#include "app-auth-prompt.h"
+#include "geoclue-manager-dbus.h"
+#include "location-manager.h"
+#include "shell.h"
+#include "util.h"
+
+#include
+#include
+
+/**
+ * SECTION:location-manager
+ * @short_description: Provides the org.freedesktop.GeoClue2.Agent DBus interface
+ * @Title: PhoshLocationManager
+ *
+ * The #PhoshLocationManager provides the agent interface and authorizes
+ * clients based on the org.gnome.system.location 'enabled' gsetting. Note
+ * the phosh needs to be enabled as agent in geoclue's config.
+ */
+#define LOCATION_AGENT_DBUS_NAME "org.freedesktop.GeoClue2.Agent"
+#define LOCATION_AGENT_DBUS_PATH "/org/freedesktop/GeoClue2/Agent"
+
+#define GEOCLUE_SERVICE "org.freedesktop.GeoClue2"
+#define GEOCLUE_MANAGER_PATH "/org/freedesktop/GeoClue2/Manager"
+
+/**
+ * AccuracyLevel:
+ * @LEVEL_NONE: Accuracy level unknown or unset.
+ * @LEVEL_COUNTRY: Country-level accuracy.
+ * @LEVEL_CITY: City-level accuracy.
+ * @LEVEL_NEIGHBORHOOD: neighborhood-level accuracy.
+ * @LEVEL_STREET: Street-level accuracy.
+ * @LEVEL_EXACT: Exact accuracy. Typically requires GPS receiver.
+ *
+ * Used to specify level of accuracy requested by, or allowed for a client.
+ **/
+typedef enum {
+ LEVEL_NONE = 0,
+ LEVEL_COUNTRY = 1,
+ LEVEL_CITY = 4,
+ LEVEL_NEIGHBORHOOD = 5,
+ LEVEL_STREET = 6,
+ LEVEL_EXACT = 8,
+} AccuracyLevel;
+
+
+enum {
+ PROP_0,
+ PROP_ENABLED,
+ PROP_ACTIVE,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+typedef struct _PhoshLocationManager {
+ PhoshGeoClueDBusOrgFreedesktopGeoClue2AgentSkeleton parent;
+
+ PhoshGeoClueDBusManager *manager_proxy;
+ guint dbus_name_id;
+ GSettings *location_settings;
+ gboolean enabled;
+ gboolean active;
+
+ /* Current Request */
+ GtkWidget *prompt;
+ GDBusMethodInvocation *invocation;
+ AccuracyLevel req_level;
+
+ GCancellable *cancel;
+} PhoshLocationManager;
+
+static void phosh_location_manager_geoclue2_agent_iface_init (
+ PhoshGeoClueDBusOrgFreedesktopGeoClue2AgentIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (PhoshLocationManager,
+ phosh_location_manager,
+ PHOSH_GEO_CLUE_DBUS_TYPE_ORG_FREEDESKTOP_GEO_CLUE2_AGENT_SKELETON,
+ G_IMPLEMENT_INTERFACE (
+ PHOSH_GEO_CLUE_DBUS_TYPE_ORG_FREEDESKTOP_GEO_CLUE2_AGENT,
+ phosh_location_manager_geoclue2_agent_iface_init));
+
+
+static guint
+get_max_level (PhoshLocationManager *self)
+{
+ gint level = LEVEL_NONE;
+
+ if (self->enabled) {
+ GDesktopLocationAccuracyLevel val = g_settings_get_enum (self->location_settings, "max-accuracy-level");
+
+ switch (val) {
+ case G_DESKTOP_LOCATION_ACCURACY_LEVEL_COUNTRY:
+ level = LEVEL_COUNTRY;
+ break;
+ case G_DESKTOP_LOCATION_ACCURACY_LEVEL_CITY:
+ level = LEVEL_CITY;
+ break;
+ case G_DESKTOP_LOCATION_ACCURACY_LEVEL_NEIGHBORHOOD:
+ level = LEVEL_NEIGHBORHOOD;
+ break;
+ case G_DESKTOP_LOCATION_ACCURACY_LEVEL_STREET:
+ level = LEVEL_STREET;
+ break;
+ case G_DESKTOP_LOCATION_ACCURACY_LEVEL_EXACT:
+ level = LEVEL_EXACT;
+ break;
+ default:
+ g_warn_if_reached ();
+ }
+ }
+
+ return level;
+}
+
+
+static void
+update_accuracy_level (PhoshLocationManager *self, gboolean enabled)
+{
+ int level;
+
+ self->enabled = enabled;
+ level = get_max_level (self);
+
+ g_debug ("Setting accuracy level to %d", level);
+ phosh_geo_clue_dbus_org_freedesktop_geo_clue2_agent_set_max_accuracy_level (
+ PHOSH_GEO_CLUE_DBUS_ORG_FREEDESKTOP_GEO_CLUE2_AGENT (self), level);
+}
+
+
+static void
+phosh_location_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshLocationManager *self = PHOSH_LOCATION_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_ENABLED:
+ g_value_set_boolean (value, self->enabled);
+ break;
+ case PROP_ACTIVE:
+ g_value_set_boolean (value, self->active);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_location_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshLocationManager *self = PHOSH_LOCATION_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_ENABLED:
+ update_accuracy_level (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+on_app_auth_prompt_closed (PhoshLocationManager *self, PhoshAppAuthPrompt *prompt)
+{
+ gboolean grant_access;
+
+ g_return_if_fail (PHOSH_IS_LOCATION_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_APP_AUTH_PROMPT (prompt));
+
+ grant_access = phosh_app_auth_prompt_get_grant_access (GTK_WIDGET (prompt));
+
+ g_debug ("Granting access for %p at level %d: %s",
+ self->invocation,
+ self->req_level,
+ grant_access ? "yes" : "no");
+
+ phosh_geo_clue_dbus_org_freedesktop_geo_clue2_agent_complete_authorize_app (
+ PHOSH_GEO_CLUE_DBUS_ORG_FREEDESKTOP_GEO_CLUE2_AGENT (self),
+ self->invocation,
+ grant_access,
+ self->req_level);
+
+ /* TODO: save in permission store */
+
+ self->req_level = LEVEL_NONE;
+ self->invocation = NULL;
+ self->prompt = NULL;
+
+ return;
+}
+
+
+static gboolean
+handle_authorize_app (PhoshGeoClueDBusOrgFreedesktopGeoClue2Agent *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *arg_desktop_id,
+ guint arg_req_accuracy_level)
+{
+ PhoshLocationManager *self = PHOSH_LOCATION_MANAGER (object);
+ g_autofree char *desktop_file = NULL;
+ g_autofree char *body = NULL;
+ g_autofree char *subtitle = NULL;
+
+ g_autoptr (GDesktopAppInfo) app_info = NULL;
+ gint level;
+
+ g_debug ("Authorizing %s: %d", arg_desktop_id, self->enabled);
+
+ level = get_max_level (self);
+ if (arg_req_accuracy_level > level) {
+ g_debug ("Req accuracy level %d > max allowed %d", arg_req_accuracy_level, level);
+ phosh_geo_clue_dbus_org_freedesktop_geo_clue2_agent_complete_authorize_app (
+ object,
+ invocation,
+ FALSE,
+ arg_req_accuracy_level);
+ return TRUE;
+ }
+
+ desktop_file = g_strjoin (".", arg_desktop_id, "desktop", NULL);
+ app_info = g_desktop_app_info_new (desktop_file);
+ if (app_info == NULL) {
+ g_debug ("Failed to find %s", desktop_file);
+ phosh_geo_clue_dbus_org_freedesktop_geo_clue2_agent_complete_authorize_app (
+ object,
+ invocation,
+ FALSE,
+ arg_req_accuracy_level);
+
+ return TRUE;
+ }
+
+ /* TODO: look at location permission store */
+
+ /* Cancel any ongoing prompt */
+ if (self->prompt)
+ gtk_widget_destroy (GTK_WIDGET (self->prompt));
+
+ if (self->invocation) {
+ phosh_geo_clue_dbus_org_freedesktop_geo_clue2_agent_complete_authorize_app (
+ object,
+ self->invocation,
+ FALSE,
+ arg_req_accuracy_level);
+ }
+
+ self->req_level = arg_req_accuracy_level;
+ self->invocation = invocation;
+ subtitle = g_strdup_printf (_("Allow '%s' to access your location information?"),
+ g_app_info_get_display_name (G_APP_INFO (app_info)));
+
+ body = g_desktop_app_info_get_string (app_info, "X-Geoclue-Reason");
+ self->prompt = phosh_app_auth_prompt_new (g_app_info_get_icon (G_APP_INFO (app_info)),
+ _("Geolocation"),
+ subtitle, body, _("Yes"), _("No"), FALSE);
+ g_signal_connect_object (self->prompt,
+ "closed",
+ G_CALLBACK (on_app_auth_prompt_closed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ /* Show widget when not locked and keep that in sync */
+ g_object_bind_property (phosh_shell_get_default (), "locked",
+ self->prompt, "visible",
+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
+
+
+ return TRUE;
+}
+
+
+static guint
+handle_get_max_accuracy_level (PhoshGeoClueDBusOrgFreedesktopGeoClue2Agent *object)
+{
+ PhoshLocationManager *self = PHOSH_LOCATION_MANAGER (object);
+ gint level = get_max_level (self);
+
+ g_debug ("Accuracy level %d", level);
+ return level;
+}
+
+
+static void
+phosh_location_manager_geoclue2_agent_iface_init (PhoshGeoClueDBusOrgFreedesktopGeoClue2AgentIface *iface)
+{
+ iface->handle_authorize_app = handle_authorize_app;
+ iface->get_max_accuracy_level = handle_get_max_accuracy_level;
+}
+
+
+static void
+on_bus_acquired (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ g_autoptr (GError) err = NULL;
+ PhoshLocationManager *self;
+ GDBusConnection *connection;
+
+ connection = g_bus_get_finish (res, &err);
+ if (!connection) {
+ phosh_async_error_warn (err, "Failed to connect to system bus");
+ return;
+ }
+
+ self = PHOSH_LOCATION_MANAGER (user_data);
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
+ connection,
+ LOCATION_AGENT_DBUS_PATH,
+ NULL);
+ update_accuracy_level (self, self->enabled);
+}
+
+
+static void
+on_add_agent_ready (PhoshGeoClueDBusManager *manager,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ g_autoptr (GError) err = NULL;
+
+ if (phosh_geo_clue_dbus_manager_call_add_agent_finish (manager, res, &err))
+ g_debug ("Added ourself as geoclue agent");
+ else
+ g_warning ("Failed to add agent: %s", err->message);
+}
+
+
+static void
+on_agent_in_use_changed (PhoshLocationManager *self)
+{
+ gboolean in_use;
+
+ g_return_if_fail (PHOSH_IS_LOCATION_MANAGER (self));
+ g_return_if_fail (PHOSH_GEO_CLUE_DBUS_IS_MANAGER (self->manager_proxy));
+
+ in_use = phosh_geo_clue_dbus_manager_get_in_use (self->manager_proxy);
+ g_debug ("In use: %d", in_use);
+
+ if (in_use == self->active)
+ return;
+
+ self->active = in_use;
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVE]);
+}
+
+
+static void
+on_manager_proxy_ready (GObject *source_object,
+ GAsyncResult *res,
+ PhoshLocationManager *self)
+{
+ g_autoptr (GError) err = NULL;
+
+ g_return_if_fail (PHOSH_IS_LOCATION_MANAGER (self));
+
+ self->manager_proxy = phosh_geo_clue_dbus_manager_proxy_new_for_bus_finish (res, &err);
+ if (self->manager_proxy == NULL) {
+ g_warning ("Failed to create proxy to %s: %s",
+ GEOCLUE_MANAGER_PATH,
+ err->message);
+ return;
+ }
+
+ phosh_geo_clue_dbus_manager_call_add_agent (self->manager_proxy,
+ PHOSH_APP_ID,
+ NULL,
+ (GAsyncReadyCallback)on_add_agent_ready,
+ NULL);
+ g_signal_connect_swapped (self->manager_proxy,
+ "notify::in-use",
+ G_CALLBACK (on_agent_in_use_changed),
+ self);
+ on_agent_in_use_changed (self);
+}
+
+
+static void
+on_manager_name_appeared (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ PhoshLocationManager *self)
+{
+ g_return_if_fail (PHOSH_IS_LOCATION_MANAGER (self));
+ g_debug ("%s appeared", name);
+
+ phosh_geo_clue_dbus_manager_proxy_new_for_bus (
+ G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ GEOCLUE_SERVICE,
+ GEOCLUE_MANAGER_PATH,
+ NULL,
+ (GAsyncReadyCallback)on_manager_proxy_ready,
+ self);
+}
+
+static void
+on_manager_name_vanished (GDBusConnection *connection,
+ const gchar *name,
+ PhoshLocationManager *self)
+{
+ g_return_if_fail (PHOSH_IS_LOCATION_MANAGER (self));
+
+ g_debug ("%s vanished", name);
+ g_clear_object (&self->manager_proxy);
+}
+
+
+static void
+phosh_location_manager_dispose (GObject *object)
+{
+ PhoshLocationManager *self = PHOSH_LOCATION_MANAGER (object);
+
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
+ /* Close dialog and cancel pending request if ongoing */
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+
+ if (self->invocation) {
+ phosh_geo_clue_dbus_org_freedesktop_geo_clue2_agent_complete_authorize_app (
+ PHOSH_GEO_CLUE_DBUS_ORG_FREEDESKTOP_GEO_CLUE2_AGENT (self),
+ self->invocation,
+ FALSE,
+ LEVEL_NONE);
+ self->invocation = NULL;
+ }
+
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unwatch_name);
+
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_object (&self->location_settings);
+ g_clear_object (&self->manager_proxy);
+
+ G_OBJECT_CLASS (phosh_location_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_location_manager_constructed (GObject *object)
+{
+ PhoshLocationManager *self = PHOSH_LOCATION_MANAGER (object);
+
+ G_OBJECT_CLASS (phosh_location_manager_parent_class)->constructed (object);
+
+ self->location_settings = g_settings_new ("org.gnome.system.location");
+ g_settings_bind (self->location_settings,
+ "enabled",
+ self,
+ "enabled",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_bus_get (G_BUS_TYPE_SYSTEM,
+ self->cancel,
+ on_bus_acquired,
+ self);
+
+ self->dbus_name_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
+ GEOCLUE_SERVICE,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback) on_manager_name_appeared,
+ (GBusNameVanishedCallback) on_manager_name_vanished,
+ self,
+ NULL);
+}
+
+
+static void
+phosh_location_manager_class_init (PhoshLocationManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = phosh_location_manager_constructed;
+ object_class->dispose = phosh_location_manager_dispose;
+
+ object_class->set_property = phosh_location_manager_set_property;
+ object_class->get_property = phosh_location_manager_get_property;
+
+ props[PROP_ENABLED] =
+ g_param_spec_boolean ("enabled",
+ "enabled",
+ "Whether location services are enabled",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_ACTIVE] =
+ g_param_spec_boolean ("active",
+ "Active",
+ "Whether location services are currently active",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+}
+
+
+static void
+phosh_location_manager_init (PhoshLocationManager *self)
+{
+ self->cancel = g_cancellable_new ();
+}
+
+
+PhoshLocationManager *
+phosh_location_manager_new (void)
+{
+ return g_object_new (PHOSH_TYPE_LOCATION_MANAGER, NULL);
+}
diff -Nru phosh-0.8.0/src/location-manager.h phosh-0.13.1/src/location-manager.h
--- phosh-0.8.0/src/location-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/location-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Author: Guido Günther
+ */
+#pragma once
+
+#include "dbus/geoclue-agent-dbus.h"
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_LOCATION_MANAGER (phosh_location_manager_get_type ())
+G_DECLARE_FINAL_TYPE (PhoshLocationManager, phosh_location_manager, PHOSH, LOCATION_MANAGER,
+ PhoshGeoClueDBusOrgFreedesktopGeoClue2AgentSkeleton)
+
+PhoshLocationManager * phosh_location_manager_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/lockscreen.c phosh-0.13.1/src/lockscreen.c
--- phosh-0.8.0/src/lockscreen.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/lockscreen.c 2021-08-31 09:15:52.000000000 +0000
@@ -12,8 +12,11 @@
#include "auth.h"
#include "bt-info.h"
+#include "calls-manager.h"
#include "lockscreen.h"
-#include "media-player.h"
+#include "notifications/notify-manager.h"
+#include "notifications/notification-frame.h"
+#include "util.h"
#include
#include
@@ -21,8 +24,9 @@
#include
#include
-#define HANDY_USE_UNSTABLE_API
#include
+#include
+
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include
@@ -36,8 +40,25 @@
*
* The lock screen featuring the clock
* and unlock keypad.
+ *
+ * # CSS nodes
+ *
+ * #PhoshLockscreen has a CSS name with the name phosh-lockscreen.
*/
+
+typedef enum {
+ POS_OVERVIEW = 0,
+ POS_UNLOCK = 1,
+} PhoshLocksreenPos;
+
+enum {
+ PROP_0,
+ PROP_CALLS_MANAGER,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
enum {
LOCKSCREEN_UNLOCK,
WAKEUP_OUTPUT,
@@ -45,7 +66,6 @@
};
static guint signals[N_SIGNALS] = { 0 };
-
typedef struct _PhoshLockscreen
{
PhoshLayerSurface parent;
@@ -53,33 +73,84 @@
typedef struct {
- GtkWidget *carousel;
+ GtkWidget *carousel;
/* info page */
- GtkWidget *box_info;
- GtkWidget *lbl_clock;
- GtkWidget *lbl_date;
+ GtkWidget *box_info;
+ GtkWidget *lbl_clock;
+ GtkWidget *lbl_date;
+ GtkWidget *list_notifications;
+ GtkWidget *sw_notifications;
+ GSettings *settings;
/* unlock page */
- GtkWidget *box_unlock;
- GtkWidget *keypad;
- GtkWidget *entry_pin;
- GtkGesture *long_press_del_gesture;
- GtkWidget *lbl_unlock_status;
- GtkWidget *btn_submit;
- GtkWidget *btn_emergency;
- guint idle_timer;
- gint64 last_input;
- PhoshAuth *auth;
-
- GnomeWallClock *wall_clock;
+ GtkWidget *box_unlock;
+ GtkWidget *keypad;
+ GtkWidget *entry_pin;
+ GtkGesture *long_press_del_gesture;
+ GtkWidget *lbl_unlock_status;
+ GtkWidget *btn_submit;
+ GtkWidget *btn_emergency;
+ guint idle_timer;
+ gint64 last_input;
+ PhoshAuth *auth;
+
+ /* Call page */
+ HdyDeck *deck;
+ GtkBox *box_call_display;
+ CuiCallDisplay *call_display;
+
+ GnomeWallClock *wall_clock;
+ PhoshCallsManager *calls_manager;
+ char *active; /* opaque handle to the active call */
} PhoshLockscreenPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (PhoshLockscreen, phosh_lockscreen, PHOSH_TYPE_LAYER_SURFACE)
static void
-clear_input (PhoshLockscreen *self, gboolean clear_all) {
+phosh_lockscreen_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshLockscreen *self = PHOSH_LOCKSCREEN (object);
+ PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+
+ switch (property_id) {
+ case PROP_CALLS_MANAGER:
+ priv->calls_manager = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_lockscreen_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshLockscreen *self = PHOSH_LOCKSCREEN (object);
+ PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+
+ switch (property_id) {
+ case PROP_CALLS_MANAGER:
+ g_value_set_object (value, priv->calls_manager);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+clear_input (PhoshLockscreen *self, gboolean clear_all)
+{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
if (clear_all) {
@@ -95,6 +166,7 @@
show_info_page (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+
if (hdy_carousel_get_position (HDY_CAROUSEL (priv->carousel)) <= 0)
return;
@@ -122,6 +194,7 @@
show_unlock_page (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+
if (hdy_carousel_get_position (HDY_CAROUSEL (priv->carousel)) > 0)
return;
@@ -134,7 +207,8 @@
static gboolean
-finish_shake_label (PhoshLockscreen *self) {
+finish_shake_label (PhoshLockscreen *self)
+{
clear_input (self, TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
return FALSE;
@@ -142,9 +216,10 @@
static gboolean
-shake_label (GtkWidget *widget,
- GdkFrameClock *frame_clock,
- gpointer data) {
+shake_label (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer data)
+{
PhoshLockscreen *self = PHOSH_LOCKSCREEN (widget);
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
gint64 start_time = g_variant_get_int64 (data);
@@ -185,7 +260,7 @@
g_object_ref (self);
if (authenticated) {
- g_signal_emit(self, signals[LOCKSCREEN_UNLOCK], 0);
+ g_signal_emit (self, signals[LOCKSCREEN_UNLOCK], 0);
g_clear_object (&priv->auth);
} else {
GdkFrameClock *clock;
@@ -207,7 +282,7 @@
static void
delete_button_clicked_cb (PhoshLockscreen *self,
- GtkWidget *widget)
+ GtkWidget *widget)
{
g_return_if_fail (PHOSH_IS_LOCKSCREEN (self));
@@ -382,14 +457,14 @@
static void
wall_clock_notify_cb (PhoshLockscreen *self,
- GParamSpec *pspec,
- GnomeWallClock *wall_clock)
+ GParamSpec *pspec,
+ GnomeWallClock *wall_clock)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
const char *time;
g_autofree char *date = NULL;
- time = gnome_wall_clock_get_clock(wall_clock);
+ time = gnome_wall_clock_get_clock (wall_clock);
gtk_label_set_text (GTK_LABEL (priv->lbl_clock), time);
date = local_date ();
@@ -407,12 +482,12 @@
position = hdy_carousel_get_position (HDY_CAROUSEL (priv->carousel));
- if (position <= 0) {
+ if (position <= POS_OVERVIEW) {
clear_input (self, TRUE);
return;
}
- if (position >= 1) {
+ if (position >= POS_UNLOCK) {
if (!priv->idle_timer) {
priv->last_input = g_get_monotonic_time ();
priv->idle_timer = g_timeout_add_seconds (LOCKSCREEN_IDLE_SECONDS,
@@ -431,21 +506,109 @@
static void
+on_calls_call_inbound (PhoshLockscreen *self, const gchar *path)
+{
+ PhoshLockscreenPrivate *priv;
+ PhoshCall *call;
+
+ g_return_if_fail (PHOSH_IS_LOCKSCREEN (self));
+ priv = phosh_lockscreen_get_instance_private (self);
+ g_return_if_fail (PHOSH_IS_CALLS_MANAGER (priv->calls_manager));
+
+ g_debug ("New inbound call %s", path);
+ g_signal_emit (self, signals[WAKEUP_OUTPUT], 0);
+
+ g_free (priv->active);
+ priv->active = g_strdup (path);
+
+ call = phosh_calls_manager_get_call (priv->calls_manager, path);
+ g_return_if_fail (PHOSH_IS_CALL (call));
+
+ hdy_deck_set_visible_child (priv->deck, GTK_WIDGET (priv->box_call_display));
+
+ cui_call_display_set_call (priv->call_display, CUI_CALL (call));
+}
+
+
+static void
+on_calls_call_removed (PhoshLockscreen *self, const gchar *path)
+{
+ PhoshLockscreenPrivate *priv;
+
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (PHOSH_IS_LOCKSCREEN (self));
+ priv = phosh_lockscreen_get_instance_private (self);
+
+ g_debug ("Call %s removed, active: %s", path, priv->active);
+
+ if (g_strcmp0 (path, priv->active))
+ return;
+
+ g_clear_pointer (&priv->active, g_free);
+ hdy_deck_navigate (priv->deck, HDY_NAVIGATION_DIRECTION_BACK);
+}
+
+
+static GtkWidget *
+create_notification_row (gpointer item, gpointer data)
+{
+ GtkWidget *row = NULL;
+ GtkWidget *frame = NULL;
+
+ row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
+ "activatable", FALSE,
+ "visible", TRUE,
+ NULL);
+
+ frame = phosh_notification_frame_new (FALSE);
+ phosh_notification_frame_bind_model (PHOSH_NOTIFICATION_FRAME (frame), item);
+
+ gtk_widget_show (frame);
+ gtk_container_add (GTK_CONTAINER (row), frame);
+
+ return row;
+}
+
+
+static void
+on_notifcation_items_changed (PhoshLockscreen *self,
+ guint position,
+ guint removed,
+ guint added,
+ GListModel *list)
+{
+ PhoshLockscreenPrivate *priv;
+ gboolean is_empty;
+
+ g_return_if_fail (G_IS_LIST_MODEL (list));
+ g_return_if_fail (PHOSH_IS_LOCKSCREEN (self));
+ priv = phosh_lockscreen_get_instance_private (self);
+
+ is_empty = !g_list_model_get_n_items (list);
+ g_debug("Notification list empty: %d", is_empty);
+
+ /* Don't unhide when we don't want notification on the lock screen */
+ if (!is_empty && !g_settings_get_boolean (priv->settings, "show-in-lock-screen"))
+ return;
+
+ gtk_widget_set_visible (GTK_WIDGET (priv->sw_notifications), !is_empty);
+}
+
+
+static void
phosh_lockscreen_constructed (GObject *object)
{
PhoshLockscreen *self = PHOSH_LOCKSCREEN (object);
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+ const char *active;
+ PhoshNotifyManager *manager;
G_OBJECT_CLASS (phosh_lockscreen_parent_class)->constructed (object);
/* window properties */
gtk_window_set_title (GTK_WINDOW (self), "phosh lockscreen");
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
- gtk_widget_realize(GTK_WIDGET (self));
-
- gtk_style_context_add_class (
- gtk_widget_get_style_context (GTK_WIDGET (self)),
- "phosh-lockscreen");
+ gtk_widget_realize (GTK_WIDGET (self));
gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
g_signal_connect (G_OBJECT (self),
@@ -461,6 +624,50 @@
G_CALLBACK (wall_clock_notify_cb),
self);
wall_clock_notify_cb (self, NULL, priv->wall_clock);
+
+ g_signal_connect_object (priv->calls_manager,
+ "call-inbound",
+ G_CALLBACK (on_calls_call_inbound),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (priv->calls_manager,
+ "call-removed",
+ G_CALLBACK (on_calls_call_removed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ /* If a call is ongoing show it when locking until we show a notification */
+ active = phosh_calls_manager_get_active_call_handle (priv->calls_manager);
+ if (active)
+ on_calls_call_inbound (self, active);
+
+ manager = phosh_notify_manager_get_default ();
+ /* TODO: deduplicate after !862 */
+ priv->settings = g_settings_new("org.gnome.desktop.notifications");
+ g_settings_bind (priv->settings, "show-in-lock-screen",
+ priv->list_notifications, "visible",
+ G_SETTINGS_BIND_GET);
+ gtk_list_box_bind_model (GTK_LIST_BOX (priv->list_notifications),
+ G_LIST_MODEL (phosh_notify_manager_get_list (manager)),
+ create_notification_row,
+ NULL,
+ NULL);
+ g_signal_connect_object (phosh_notify_manager_get_list (manager),
+ "items-changed",
+ G_CALLBACK (on_notifcation_items_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ on_notifcation_items_changed (self, -1, -1, -1,
+ G_LIST_MODEL (phosh_notify_manager_get_list (manager)));
+}
+
+static void
+deck_back_clicked_cb (GtkWidget *sender,
+ PhoshLockscreen *self)
+{
+ PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+
+ hdy_deck_navigate (priv->deck, HDY_NAVIGATION_DIRECTION_BACK);
}
@@ -470,11 +677,11 @@
PhoshLockscreen *self = PHOSH_LOCKSCREEN (object);
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
+ g_clear_object (&priv->settings);
g_clear_object (&priv->wall_clock);
- if (priv->idle_timer) {
- g_source_remove (priv->idle_timer);
- priv->idle_timer = 0;
- }
+ g_clear_handle_id (&priv->idle_timer, g_source_remove);
+ g_clear_object (&priv->calls_manager);
+ g_clear_pointer (&priv->active, g_free);
G_OBJECT_CLASS (phosh_lockscreen_parent_class)->dispose (object);
}
@@ -486,25 +693,34 @@
GObjectClass *object_class = (GObjectClass *)klass;
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- g_type_ensure (PHOSH_TYPE_BT_INFO);
- g_type_ensure (PHOSH_TYPE_MEDIA_PLAYER);
-
object_class->constructed = phosh_lockscreen_constructed;
object_class->dispose = phosh_lockscreen_dispose;
+ object_class->set_property = phosh_lockscreen_set_property;
+ object_class->get_property = phosh_lockscreen_get_property;
+
+ props[PROP_CALLS_MANAGER] =
+ g_param_spec_object ("calls-manager",
+ "",
+ "",
+ PHOSH_TYPE_CALLS_MANAGER,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
signals[LOCKSCREEN_UNLOCK] = g_signal_new ("lockscreen-unlock",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- NULL, G_TYPE_NONE, 0);
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
/**
- * PhoshLockscreen::wakeup-screen
+ * PhoshLockscreen::wakeup-output
* @self: The #PhoshLockscreen emitting this signal
*
* Emitted when the output showing the lock screen should be woken
* up.
*/
signals[WAKEUP_OUTPUT] = g_signal_new ("wakeup-output",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- NULL, G_TYPE_NONE, 0);
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
gtk_widget_class_set_css_name (widget_class, "phosh-lockscreen");
gtk_widget_class_set_template_from_resource (widget_class,
@@ -512,7 +728,7 @@
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, carousel);
gtk_widget_class_bind_template_callback_full (widget_class,
"carousel_position_notified_cb",
- G_CALLBACK(carousel_position_notified_cb));
+ G_CALLBACK (carousel_position_notified_cb));
/* unlock page */
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, box_unlock);
@@ -532,7 +748,15 @@
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, box_info);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, lbl_clock);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, lbl_date);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, list_notifications);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, sw_notifications);
gtk_widget_class_bind_template_callback (widget_class, show_unlock_page);
+
+ /* Call UI */
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, deck);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, box_call_display);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, call_display);
+ gtk_widget_class_bind_template_callback (widget_class, deck_back_clicked_cb);
}
@@ -545,7 +769,8 @@
GtkWidget *
phosh_lockscreen_new (gpointer layer_shell,
- gpointer wl_output)
+ gpointer wl_output,
+ PhoshCallsManager *calls_manager)
{
return g_object_new (PHOSH_TYPE_LOCKSCREEN,
"layer-shell", layer_shell,
@@ -558,5 +783,49 @@
"kbd-interactivity", TRUE,
"exclusive-zone", -1,
"namespace", "phosh lockscreen",
+ "calls-manager", calls_manager,
NULL);
}
+
+/**
+ * phosh_lockscreen_get_page
+ * @self: The #PhoshLockscreen
+ *
+ * Returns: The #PhoshLockscreenPage that is currently shown
+ */
+PhoshLockscreenPage
+phosh_lockscreen_get_page (PhoshLockscreen *self)
+{
+ PhoshLockscreenPrivate *priv;
+ gdouble position;
+
+ g_return_val_if_fail (PHOSH_IS_LOCKSCREEN (self), PHOSH_LOCKSCREEN_PAGE_DEFAULT);
+ priv = phosh_lockscreen_get_instance_private (self);
+ position = hdy_carousel_get_position (HDY_CAROUSEL (priv->carousel));
+
+ if (position <= 0)
+ return PHOSH_LOCKSCREEN_PAGE_DEFAULT;
+ else
+ return PHOSH_LOCKSCREEN_PAGE_UNLOCK;
+}
+
+/*
+ * phosh_lockscreen_set_page
+ * @self: The #PhoshLockscreen
+ * PhoshLockscreenPage: the page to scroll to
+ *
+ * Scrolls to a specific page in the carousel. The state of the deck isn't changed.
+ */
+void
+phosh_lockscreen_set_page (PhoshLockscreen *self, PhoshLockscreenPage page)
+{
+ GtkWidget *scroll_to;
+ PhoshLockscreenPrivate *priv;
+
+ g_return_if_fail (PHOSH_IS_LOCKSCREEN (self));
+ priv = phosh_lockscreen_get_instance_private (self);
+
+ scroll_to = (page == PHOSH_LOCKSCREEN_PAGE_UNLOCK) ? priv->box_unlock : priv->box_info;
+
+ hdy_carousel_scroll_to (HDY_CAROUSEL (priv->carousel), scroll_to);
+}
diff -Nru phosh-0.8.0/src/lockscreen.h phosh-0.13.1/src/lockscreen.h
--- phosh-0.8.0/src/lockscreen.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/lockscreen.h 2021-08-31 09:15:52.000000000 +0000
@@ -5,15 +5,32 @@
*/
#pragma once
+#include "calls-manager.h"
#include "layersurface.h"
G_BEGIN_DECLS
+/**
+ * PhoshLockscreenPage:
+ * @PHOSH_LOCKSCREEN_PAGE_DEFAULT: The default locked page
+ * @PHOSH_LOCKSCREEN_PAGE_UNLOCK: The unlock page (where PIN is entered)
+ *
+ * This enum indicates which page is shown on the lockscreen.
+ * This helps #PhoshGnomeShellManager to decide when to emit
+ * AcceleratorActivated events over DBus
+ */
+typedef enum {
+ PHOSH_LOCKSCREEN_PAGE_DEFAULT,
+ PHOSH_LOCKSCREEN_PAGE_UNLOCK,
+} PhoshLockscreenPage;
+
#define PHOSH_TYPE_LOCKSCREEN (phosh_lockscreen_get_type ())
G_DECLARE_FINAL_TYPE (PhoshLockscreen, phosh_lockscreen, PHOSH, LOCKSCREEN,
PhoshLayerSurface)
-GtkWidget * phosh_lockscreen_new (gpointer layer_shell, gpointer wl_output);
+GtkWidget * phosh_lockscreen_new (gpointer layer_shell, gpointer wl_output, PhoshCallsManager *calls_manager);
+void phosh_lockscreen_set_page (PhoshLockscreen *self, PhoshLockscreenPage page);
+PhoshLockscreenPage phosh_lockscreen_get_page (PhoshLockscreen *self);
G_END_DECLS
diff -Nru phosh-0.8.0/src/lockscreen-manager.c phosh-0.13.1/src/lockscreen-manager.c
--- phosh-0.8.0/src/lockscreen-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/lockscreen-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -42,26 +42,26 @@
static guint signals[N_SIGNALS] = { 0 };
enum {
- PHOSH_LOCKSCREEN_MANAGER_PROP_0,
- PHOSH_LOCKSCREEN_MANAGER_PROP_LOCKED,
- PHOSH_LOCKSCREEN_MANAGER_PROP_TIMEOUT,
- PHOSH_LOCKSCREEN_MANAGER_PROP_LAST_PROP
+ PROP_0,
+ PROP_LOCKED,
+ PROP_CALLS_MANAGER,
+ PROP_LAST_PROP
};
-static GParamSpec *props[PHOSH_LOCKSCREEN_MANAGER_PROP_LAST_PROP];
+static GParamSpec *props[PROP_LAST_PROP];
struct _PhoshLockscreenManager {
GObject parent;
- PhoshLockscreen *lockscreen; /* phone display lock screen */
- PhoshSessionPresence *presence; /* gnome-session's presence interface */
- GPtrArray *shields; /* other outputs */
- GSettings *settings;
+ PhoshLockscreen *lockscreen; /* phone display lock screen */
+ PhoshSessionPresence *presence; /* gnome-session's presence interface */
+ GPtrArray *shields; /* other outputs */
- int timeout; /* timeout in seconds before screen locks */
gboolean locked;
- gint64 active_time; /* when lock was activated (in us) */
- int transform; /* the shell transform before locking */
+ gint64 active_time; /* when lock was activated (in us) */
+ int transform; /* the shell transform before locking */
+
+ PhoshCallsManager *calls_manager; /* Calls DBus Interface */
};
G_DEFINE_TYPE (PhoshLockscreenManager, phosh_lockscreen_manager, G_TYPE_OBJECT)
@@ -77,10 +77,6 @@
g_return_if_fail (PHOSH_IS_LOCKSCREEN (lockscreen));
g_return_if_fail (lockscreen == PHOSH_LOCKSCREEN (self->lockscreen));
- /* Fixup transform in case the lockscreen needed to rotate to unlock */
- g_debug ("Restoring transform %d", self->transform);
- phosh_shell_set_transform (shell, self->transform);
-
g_signal_handlers_disconnect_by_data (monitor_manager, self);
g_signal_handlers_disconnect_by_data (primary_monitor, self);
g_signal_handlers_disconnect_by_data (shell, self);
@@ -91,7 +87,7 @@
self->locked = FALSE;
self->active_time = 0;
- g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LOCKSCREEN_MANAGER_PROP_LOCKED]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_LOCKED]);
}
@@ -171,35 +167,6 @@
lock_monitor (self, monitor);
}
-static void
-on_primary_monitor_power_mode_changed (PhoshLockscreenManager *self,
- GParamSpec *pspec,
- PhoshMonitor *monitor)
-{
- PhoshShell *shell = phosh_shell_get_default ();
- PhoshModeManager *mode_manager = phosh_shell_get_mode_manager(shell);
-
- /*
- * Only phones need to switch orientation so that the lock screen fits
- * https://source.puri.sm/Librem5/phosh/-/issues/388
- */
- if (phosh_mode_manager_get_device_type(mode_manager) != PHOSH_MODE_DEVICE_TYPE_PHONE)
- return;
-
- /* Don't mess with transforms on external screens either */
- if (!phosh_monitor_is_builtin (monitor))
- return;
-
- switch (phosh_monitor_get_power_save_mode (monitor)) {
- case PHOSH_MONITOR_POWER_SAVE_MODE_ON:
- phosh_shell_set_transform (shell, PHOSH_MONITOR_TRANSFORM_NORMAL);
- break;
- case PHOSH_MONITOR_POWER_SAVE_MODE_OFF:
- break;
- default:
- g_warn_if_reached ();
- }
-}
static void
lock_primary_monitor (PhoshLockscreenManager *self)
@@ -209,23 +176,18 @@
PhoshShell *shell = phosh_shell_get_default ();
primary_monitor = phosh_shell_get_primary_monitor (shell);
- self->transform = phosh_shell_get_transform (shell);
/* The primary output gets the clock, keypad, ... */
self->lockscreen = PHOSH_LOCKSCREEN (phosh_lockscreen_new (
phosh_wayland_get_zwlr_layer_shell_v1 (wl),
- primary_monitor->wl_output));
-
+ primary_monitor->wl_output,
+ self->calls_manager));
g_object_connect (
self->lockscreen,
"swapped-object-signal::lockscreen-unlock", G_CALLBACK (lockscreen_unlock_cb), self,
"swapped-object-signal::wakeup-output", G_CALLBACK (lockscreen_wakeup_output_cb), self,
NULL);
- g_signal_connect_swapped (primary_monitor, "notify::power-mode",
- G_CALLBACK(on_primary_monitor_power_mode_changed),
- self);
-
gtk_widget_show (GTK_WIDGET (self->lockscreen));
/* Old lockscreen gets remove due to `layer_surface_closed` */
}
@@ -289,7 +251,7 @@
self->locked = TRUE;
self->active_time = g_get_monotonic_time ();
- g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LOCKSCREEN_MANAGER_PROP_LOCKED]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_LOCKED]);
}
@@ -313,11 +275,11 @@
PhoshLockscreenManager *self = PHOSH_LOCKSCREEN_MANAGER (object);
switch (property_id) {
- case PHOSH_LOCKSCREEN_MANAGER_PROP_LOCKED:
+ case PROP_LOCKED:
phosh_lockscreen_manager_set_locked (self, g_value_get_boolean (value));
break;
- case PHOSH_LOCKSCREEN_MANAGER_PROP_TIMEOUT:
- phosh_lockscreen_manager_set_timeout (self, g_value_get_int (value));
+ case PROP_CALLS_MANAGER:
+ self->calls_manager = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -335,11 +297,11 @@
PhoshLockscreenManager *self = PHOSH_LOCKSCREEN_MANAGER (object);
switch (property_id) {
- case PHOSH_LOCKSCREEN_MANAGER_PROP_LOCKED:
+ case PROP_LOCKED:
g_value_set_boolean (value, self->locked);
break;
- case PHOSH_LOCKSCREEN_MANAGER_PROP_TIMEOUT:
- g_value_set_uint (value, self->timeout);
+ case PROP_CALLS_MANAGER:
+ g_value_set_object (value, self->calls_manager);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -349,13 +311,23 @@
static void
+on_calls_call_inbound (PhoshLockscreen *self)
+{
+ g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self));
+
+ g_signal_emit (self, signals[WAKEUP_OUTPUTS], 0);
+}
+
+
+static void
phosh_lockscreen_manager_dispose (GObject *object)
{
PhoshLockscreenManager *self = PHOSH_LOCKSCREEN_MANAGER (object);
g_clear_pointer (&self->shields, g_ptr_array_unref);
g_clear_pointer (&self->lockscreen, phosh_cp_widget_destroy);
- g_clear_object (&self->settings);
+ g_clear_object (&self->calls_manager);
+ g_clear_object (&self->presence);
G_OBJECT_CLASS (phosh_lockscreen_manager_parent_class)->dispose (object);
}
@@ -368,9 +340,6 @@
G_OBJECT_CLASS (phosh_lockscreen_manager_parent_class)->constructed (object);
- self->settings = g_settings_new ("org.gnome.desktop.session");
- g_settings_bind (self->settings, "idle-delay", self, "timeout", G_SETTINGS_BIND_GET);
-
self->presence = phosh_session_presence_get_default_failable ();
if (self->presence) {
g_signal_connect_swapped (self->presence,
@@ -378,6 +347,12 @@
(GCallback) presence_status_changed_cb,
self);
}
+
+ g_signal_connect_object (self->calls_manager,
+ "call-inbound",
+ G_CALLBACK (on_calls_call_inbound),
+ self,
+ G_CONNECT_SWAPPED);
}
@@ -392,21 +367,21 @@
object_class->set_property = phosh_lockscreen_manager_set_property;
object_class->get_property = phosh_lockscreen_manager_get_property;
- props[PHOSH_LOCKSCREEN_MANAGER_PROP_LOCKED] =
+ props[PROP_LOCKED] =
g_param_spec_boolean ("locked",
"Locked",
"Whether the screen is locked",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
- props[PHOSH_LOCKSCREEN_MANAGER_PROP_TIMEOUT] =
- g_param_spec_int ("timeout",
- "Timeout",
- "Idle timeout in seconds until screen locks",
- 0,
- G_MAXINT,
- 300,
- G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, PHOSH_LOCKSCREEN_MANAGER_PROP_LAST_PROP, props);
+
+ props[PROP_CALLS_MANAGER] =
+ g_param_spec_object ("calls-manager",
+ "",
+ "",
+ PHOSH_TYPE_CALLS_MANAGER,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
/**
* PhoshLockscreenManager::wakeup-outputs
@@ -428,20 +403,28 @@
PhoshLockscreenManager *
-phosh_lockscreen_manager_new (void)
+phosh_lockscreen_manager_new (PhoshCallsManager *calls_manager)
{
- return g_object_new (PHOSH_TYPE_LOCKSCREEN_MANAGER, NULL);
+ return g_object_new (PHOSH_TYPE_LOCKSCREEN_MANAGER,
+ "calls-manager", calls_manager,
+ NULL);
}
-
+/**
+ * phosh_lockscreen_set_locked:
+ * @self: The #PhoshLockscreenManager
+ * @lock: %TRUE to lock %FALSE to unlock
+ *
+ * Lock or unlock the screen.
+ */
void
-phosh_lockscreen_manager_set_locked (PhoshLockscreenManager *self, gboolean state)
+phosh_lockscreen_manager_set_locked (PhoshLockscreenManager *self, gboolean lock)
{
g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self));
- if (state == self->locked)
+ if (lock == self->locked)
return;
- if (state)
+ if (lock)
lockscreen_lock (self);
else
lockscreen_unlock_cb (self, PHOSH_LOCKSCREEN (self->lockscreen));
@@ -456,35 +439,41 @@
return self->locked;
}
-
-void
-phosh_lockscreen_manager_set_timeout (PhoshLockscreenManager *self, int timeout)
+/**
+ * phosh_lockscreen_manager_get_page
+ * @self: The #PhoshLockscreenManager
+ *
+ * Returns: The currently shown #PhoshLockscreenPage in the #PhoshLockscreen
+ */
+PhoshLockscreenPage
+phosh_lockscreen_manager_get_page (PhoshLockscreenManager *self)
{
- g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self));
-
- if (timeout == self->timeout)
- return;
-
- g_debug ("Setting lock screen idle timeout to %d seconds", timeout);
- self->timeout = timeout;
+ g_return_val_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self), FALSE);
- g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LOCKSCREEN_MANAGER_PROP_TIMEOUT]);
+ return phosh_lockscreen_get_page (self->lockscreen);
}
-int
-phosh_lockscreen_manager_get_timeout (PhoshLockscreenManager *self)
+gint64
+phosh_lockscreen_manager_get_active_time (PhoshLockscreenManager *self)
{
g_return_val_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self), 0);
- return self->timeout;
+ return self->active_time;
}
-gint64
-phosh_lockscreen_manager_get_active_time (PhoshLockscreenManager *self)
+gboolean
+phosh_lockscreen_manager_set_page (PhoshLockscreenManager *self,
+ PhoshLockscreenPage page)
{
- g_return_val_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self), 0);
+ g_return_val_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self), FALSE);
- return self->active_time;
+ if (!self->lockscreen)
+ return FALSE;
+
+ g_return_val_if_fail (PHOSH_IS_LOCKSCREEN (self->lockscreen), FALSE);
+
+ phosh_lockscreen_set_page (self->lockscreen, page);
+ return TRUE;
}
diff -Nru phosh-0.8.0/src/lockscreen-manager.h phosh-0.13.1/src/lockscreen-manager.h
--- phosh-0.8.0/src/lockscreen-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/lockscreen-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,6 +6,8 @@
#pragma once
+#include "calls-manager.h"
+#include "lockscreen.h"
#include
#define PHOSH_TYPE_LOCKSCREEN_MANAGER (phosh_lockscreen_manager_get_type())
@@ -16,10 +18,13 @@
LOCKSCREEN_MANAGER,
GObject)
-PhoshLockscreenManager *phosh_lockscreen_manager_new (void);
+PhoshLockscreenManager *phosh_lockscreen_manager_new (PhoshCallsManager *calls_manager);
void phosh_lockscreen_manager_set_locked (PhoshLockscreenManager *self,
gboolean state);
gboolean phosh_lockscreen_manager_get_locked (PhoshLockscreenManager *self);
+gboolean phosh_lockscreen_manager_set_page (PhoshLockscreenManager *self,
+ PhoshLockscreenPage page);
+PhoshLockscreenPage phosh_lockscreen_manager_get_page (PhoshLockscreenManager *self);
void phosh_lockscreen_manager_set_timeout (PhoshLockscreenManager *self,
int timeout);
int phosh_lockscreen_manager_get_timeout (PhoshLockscreenManager *self);
diff -Nru phosh-0.8.0/src/main.c phosh-0.13.1/src/main.c
--- phosh-0.8.0/src/main.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/main.c 2021-08-31 09:15:52.000000000 +0000
@@ -15,10 +15,12 @@
#include "phosh-wayland.h"
#include
+#include
#include
#include
+#include
static gboolean
quit (gpointer unused)
@@ -70,6 +72,19 @@
}
+static void
+on_shell_ready (PhoshShell *shell, GTimer *timer)
+{
+ g_timer_stop (timer);
+ g_debug ("Phosh ready after %.2fs", g_timer_elapsed (timer, NULL));
+
+ /* Inform systemd we're up */
+ sd_notify (0, "READY=1");
+
+ g_signal_handlers_disconnect_by_data (shell, timer);
+}
+
+
int main(int argc, char *argv[])
{
g_autoptr(GSource) sigterm = NULL;
@@ -78,6 +93,7 @@
gboolean unlocked = FALSE, locked = FALSE, version = FALSE;
g_autoptr(PhoshWayland) wl = NULL;
g_autoptr(PhoshShell) shell = NULL;
+ g_autoptr (GTimer) timer = g_timer_new ();
const GOptionEntry options [] = {
{"unlocked", 'U', 0, G_OPTION_ARG_NONE, &unlocked,
@@ -109,6 +125,7 @@
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
gtk_init (&argc, &argv);
hdy_init ();
+ cui_init (TRUE);
g_unix_signal_add (SIGTERM, on_shutdown_signal, NULL);
g_unix_signal_add (SIGINT, on_shutdown_signal, NULL);
@@ -116,10 +133,15 @@
wl = phosh_wayland_get_default ();
shell = phosh_shell_get_default ();
+
+ g_signal_connect (shell, "ready", G_CALLBACK (on_shell_ready), timer);
+
if (!(unlocked || phosh_shell_started_by_display_manager(shell)) || locked)
phosh_shell_lock (shell);
gtk_main ();
+ cui_uninit ();
+
return EXIT_SUCCESS;
}
diff -Nru phosh-0.8.0/src/manager.c phosh-0.13.1/src/manager.c
--- phosh-0.8.0/src/manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-manager"
+
+#include "config.h"
+
+#include "manager.h"
+
+/**
+ * SECTION:manager
+ * @short_description: Base class for manager objects
+ * @Title: PhoshManager
+ *
+ * Common functionality for manager objects.
+ */
+
+typedef struct
+{
+ guint idle_id;
+} PhoshManagerPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (PhoshManager, phosh_manager, G_TYPE_OBJECT);
+
+
+static gboolean
+on_idle (PhoshManager *self)
+{
+ PhoshManagerClass *klass = PHOSH_MANAGER_GET_CLASS (self);
+ PhoshManagerPrivate *priv = phosh_manager_get_instance_private (self);
+
+ if (klass->idle_init)
+ (*klass->idle_init) (self);
+
+ priv->idle_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+
+static void
+phosh_manager_dispose (GObject *object)
+{
+ PhoshManager *self = PHOSH_MANAGER (object);
+ PhoshManagerPrivate *priv = phosh_manager_get_instance_private (self);
+
+ g_clear_handle_id (&priv->idle_id, g_source_remove);
+
+ G_OBJECT_CLASS (phosh_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_manager_constructed (GObject *object)
+{
+ PhoshManager *self = PHOSH_MANAGER (object);
+ PhoshManagerClass *klass = PHOSH_MANAGER_GET_CLASS (object);
+ PhoshManagerPrivate *priv = phosh_manager_get_instance_private (self);
+
+ G_OBJECT_CLASS (phosh_manager_parent_class)->constructed (object);
+
+ if (klass->idle_init)
+ priv->idle_id = g_idle_add ((GSourceFunc) on_idle, self);
+}
+
+
+static void
+phosh_manager_class_init (PhoshManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = phosh_manager_constructed;
+ object_class->dispose = phosh_manager_dispose;
+}
+
+static void
+phosh_manager_init (PhoshManager *self)
+{
+}
diff -Nru phosh-0.8.0/src/manager.h phosh-0.13.1/src/manager.h
--- phosh-0.8.0/src/manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_MANAGER (phosh_manager_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (PhoshManager, phosh_manager, PHOSH, MANAGER, GObject)
+
+/**
+ * PhoshManagerClass:
+ * @parent_class: The parent class
+ * @idle_init: a callback to be invoked once on idle
+ */
+struct _PhoshManagerClass
+{
+ GObjectClass parent_class;
+
+ void (*idle_init) (PhoshManager *self);
+};
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/media-player.c phosh-0.13.1/src/media-player.c
--- phosh-0.8.0/src/media-player.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/media-player.c 2021-08-31 09:15:52.000000000 +0000
@@ -68,6 +68,7 @@
GtkWidget *btn_prev;
GtkWidget *btn_details;
GtkWidget *img_art;
+ GtkWidget *img_play;
GtkWidget *lbl_title;
GtkWidget *lbl_artist;
@@ -80,6 +81,8 @@
PhoshMediaPlayerStatus status;
gboolean attached;
gboolean playable;
+
+ guint idle_id;
} PhoshMediaPlayer;
G_DEFINE_TYPE (PhoshMediaPlayer, phosh_media_player, GTK_TYPE_GRID);
@@ -292,11 +295,9 @@
g_autoptr (GFile) file = g_file_new_for_uri (url);
icon = g_file_icon_new (file);
- gtk_image_set_from_gicon (GTK_IMAGE (self->img_art), icon, GTK_ICON_SIZE_DIALOG);
+ gtk_image_set_from_gicon (GTK_IMAGE (self->img_art), icon, -1);
} else {
- gtk_image_set_from_icon_name (GTK_IMAGE (self->img_art),
- "audio-x-generic-symbolic",
- GTK_ICON_SIZE_DIALOG);
+ gtk_image_set_from_icon_name (GTK_IMAGE (self->img_art), "audio-x-generic-symbolic", -1);
}
}
@@ -337,8 +338,8 @@
}
if (self->status != current) {
- GtkWidget *image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_button_set_image (GTK_BUTTON (self->btn_play), image);
+ gtk_image_set_from_icon_name (GTK_IMAGE (self->img_play), icon, -1);
+ gtk_widget_set_valign (self->img_play, GTK_ALIGN_START);
}
}
@@ -390,11 +391,13 @@
{
PhoshMediaPlayer *self = PHOSH_MEDIA_PLAYER (object);
+ g_clear_handle_id (&self->idle_id, g_source_remove);
+
if (self->dbus_id) {
g_dbus_connection_signal_unsubscribe (self->session_bus, self->dbus_id);
self->dbus_id = 0;
- g_clear_object (&self->session_bus);
}
+ g_clear_object (&self->session_bus);
g_clear_object (&self->mpris);
g_clear_object (&self->player);
@@ -461,6 +464,7 @@
gtk_widget_class_bind_template_child (widget_class, PhoshMediaPlayer, btn_prev);
gtk_widget_class_bind_template_child (widget_class, PhoshMediaPlayer, btn_details);
gtk_widget_class_bind_template_child (widget_class, PhoshMediaPlayer, img_art);
+ gtk_widget_class_bind_template_child (widget_class, PhoshMediaPlayer, img_play);
gtk_widget_class_bind_template_child (widget_class, PhoshMediaPlayer, lbl_artist);
gtk_widget_class_bind_template_child (widget_class, PhoshMediaPlayer, lbl_title);
gtk_widget_class_bind_template_callback (widget_class, btn_play_clicked_cb);
@@ -724,6 +728,8 @@
NULL,
(GAsyncReadyCallback)on_bus_get_finished,
g_object_ref (self));
+
+ self->idle_id = 0;
return G_SOURCE_REMOVE;
}
@@ -734,7 +740,7 @@
gtk_widget_init_template (GTK_WIDGET (self));
/* Perform DBus setup when idle */
- g_idle_add ((GSourceFunc)on_idle, self);
+ self->idle_id = g_idle_add ((GSourceFunc)on_idle, self);
}
diff -Nru phosh-0.8.0/src/meson.build phosh-0.13.1/src/meson.build
--- phosh-0.8.0/src/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -1,7 +1,6 @@
subdir('dbus')
subdir('monitor')
subdir('notifications')
-subdir('osk')
subdir('wwan')
subdir('settings')
subdir('gtk-list-models')
@@ -13,15 +12,19 @@
c_name: 'phosh',
)
-phosh_enum_headers = [
+phosh_enum_headers = files(
'app-grid-button.h',
+ 'gnome-shell-manager.h',
'home.h',
+ 'lockscreen.h',
'mode-manager.h',
'monitor/monitor.h',
'notifications/notification.h',
'notifications/notify-manager.h',
'phosh-wayland.h',
-] + schema_enum_headers
+ 'rotation-manager.h',
+ 'shell.h',
+) + schema_enum_headers
phosh_enums = gnome.mkenums('phosh-enums',
h_template: 'phosh-enums.h.in',
@@ -29,8 +32,8 @@
sources: phosh_enum_headers,
)
-phosh_settings_sources = [
- 'settings.c',
+phosh_settings_sources = files(
+ 'settings.c') + [
phosh_settings_widgets_sources,
]
@@ -41,7 +44,7 @@
generated_dbus_sources,
]
-libphosh_tool_sources = [
+libphosh_tool_sources = files(
'activity.c',
'activity.h',
'animation.c',
@@ -54,8 +57,18 @@
'app-list-model.h',
'background.c',
'background.h',
+ 'call.c',
+ 'call.h',
+ 'calls-manager.c',
+ 'calls-manager.h',
'connectivity-info.c',
'connectivity-info.h',
+ 'end-session-dialog.c',
+ 'end-session-dialog.h',
+ 'hks-info.c',
+ 'hks-info.h',
+ 'hks-manager.c',
+ 'hks-manager.h',
'docked-info.c',
'docked-info.h',
'docked-manager.c',
@@ -66,22 +79,36 @@
'feedback-manager.h',
'gnome-shell-manager.c',
'gnome-shell-manager.h',
+ 'gtk-mount-manager.c',
+ 'gtk-mount-manager.h',
+ 'gtk-mount-prompt.c',
+ 'gtk-mount-prompt.h',
'layersurface.c',
'layersurface.h',
'lockshield.c',
'lockshield.h',
'log.h',
'log.c',
+ 'manager.h',
+ 'manager.c',
'media-player.c',
'media-player.h',
'mode-manager.c',
'mode-manager.h',
'mount-manager.c',
'mount-manager.h',
+ 'mount-operation.c',
+ 'mount-operation.h',
'overview.c',
'overview.h',
+ 'osd-window.c',
+ 'osd-window.h',
'status-icon.c',
'status-icon.h',
+ 'system-modal.c',
+ 'system-modal.h',
+ 'system-modal-dialog.c',
+ 'system-modal-dialog.h',
'thumbnail.c',
'thumbnail.h',
'quick-setting.c',
@@ -92,12 +119,18 @@
'swipe-away-bin.h',
'util.c',
'util.h',
+ 'wl-buffer.c',
+ 'wl-buffer.h',
+) + [
+ libphosh_generated_sources,
phosh_gtk_list_models_sources,
+ phosh_monitor_sources,
phosh_notifications_sources,
- libphosh_generated_sources,
]
-libphosh_sources = [
+libphosh_sources = files(
+ 'app-auth-prompt.c',
+ 'app-auth-prompt.h',
'arrow.c',
'arrow.h',
'auth.c',
@@ -122,6 +155,10 @@
'keyboard-events.h',
'idle-manager.c',
'idle-manager.h',
+ 'location-info.c',
+ 'location-info.h',
+ 'location-manager.c',
+ 'location-manager.h',
'lockscreen-manager.c',
'lockscreen-manager.h',
'lockscreen.c',
@@ -130,22 +167,28 @@
'monitor-manager.h',
'network-auth-prompt.c',
'network-auth-prompt.h',
+ 'osk-button.c',
+ 'osk-button.h',
'osk-manager.c',
'osk-manager.h',
- 'panel.c',
- 'panel.h',
+ 'top-panel.c',
+ 'top-panel.h',
'polkit-auth-agent.c',
'polkit-auth-agent.h',
'polkit-auth-prompt.c',
'polkit-auth-prompt.h',
'proximity.h',
'proximity.c',
+ 'rotation-manager.h',
+ 'rotation-manager.c',
'sensor-proxy-manager.c',
'sensor-proxy-manager.h',
'rotateinfo.c',
'rotateinfo.h',
'screen-saver-manager.c',
'screen-saver-manager.h',
+ 'screenshot-manager.c',
+ 'screenshot-manager.h',
'session-presence.c',
'session-presence.h',
'session-manager.c',
@@ -172,10 +215,9 @@
'wifimanager.h',
'wwaninfo.c',
'wwaninfo.h',
+) + [
phosh_settings_sources,
phosh_wwan_sources,
- phosh_monitor_sources,
- phosh_osk_sources,
]
phosh_deps = [
@@ -185,8 +227,11 @@
glib_dep,
gnome_desktop_dep,
gobject_dep,
+ gsettings_desktop_schemas_dep,
gtk_dep,
gtk_wayland_dep,
+ libcall_ui_dep,
+ gudev_dep,
libfeedback_dep,
libgvc_dep,
libhandy_dep,
@@ -208,23 +253,33 @@
phosh_inc = include_directories('.')
# A static library used by tests and tools
-phosh_tool_lib = static_library('phosh-tool', libphosh_tool_sources, dependencies: phosh_deps)
+phosh_tool_lib = static_library('phosh-tool',
+ libphosh_tool_sources,
+ include_directories: [root_inc, phosh_inc],
+ dependencies: phosh_deps)
phosh_tool_dep = declare_dependency(sources: libphosh_generated_sources,
include_directories: [root_inc, phosh_inc],
link_with: phosh_tool_lib,
dependencies: phosh_deps)
-if get_option('gtk_doc')
-# We only build the shared lib for gtk-doc:
-phosh_doc_lib = library('phosh-doc', [libphosh_sources, libphosh_tool_sources], dependencies: phosh_deps)
+phosh_lib = both_libraries('phosh',
+ libphosh_sources,
+ include_directories: [root_inc, phosh_inc],
+ dependencies: [phosh_tool_dep, phosh_deps])
+
+# Shared lib used by docs
phosh_doc_dep = declare_dependency(sources: libphosh_generated_sources,
include_directories: [root_inc, phosh_inc],
- link_with: phosh_doc_lib,
+ link_with: phosh_lib,
dependencies: phosh_deps)
-endif
-phosh = executable('phosh', ['main.c', libphosh_sources],
- dependencies: phosh_tool_dep,
+# Static library used by shell and integration tests
+phosh_dep = declare_dependency(
+ include_directories: [root_inc, phosh_inc],
+ link_with: phosh_lib.get_static_lib(),
+ dependencies: [phosh_deps, phosh_tool_dep])
+
+phosh = executable('phosh', 'main.c',
+ dependencies: phosh_dep,
install: true,
install_dir: libexecdir)
-
diff -Nru phosh-0.8.0/src/mode-manager.c phosh-0.13.1/src/mode-manager.c
--- phosh-0.8.0/src/mode-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/mode-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -12,6 +12,7 @@
#include "mode-manager.h"
#include "shell.h"
+#include "util.h"
#include "dbus/hostname1-dbus.h"
#define BUS_NAME "org.freedesktop.hostname1"
@@ -40,7 +41,7 @@
static GParamSpec *props[PROP_LAST_PROP];
struct _PhoshModeManager {
- GObject parent;
+ PhoshManager parent;
PhoshModeDeviceType device_type;
PhoshModeDeviceType mimicry;
@@ -49,10 +50,11 @@
PhoshMonitorManager *monitor_manager;
PhoshHostname1DBusHostname1 *proxy;
+ GCancellable *cancel;
gchar *chassis;
PhoshWaylandSeatCapabilities wl_caps;
};
-G_DEFINE_TYPE (PhoshModeManager, phosh_mode_manager, G_TYPE_OBJECT);
+G_DEFINE_TYPE (PhoshModeManager, phosh_mode_manager, PHOSH_TYPE_MANAGER);
static void
@@ -206,15 +208,16 @@
PhoshModeManager *self)
{
g_autoptr (GError) err = NULL;
- PhoshWayland *wl = phosh_wayland_get_default ();
-
- g_return_if_fail (PHOSH_IS_MODE_MANAGER (self));
+ PhoshWayland *wl;
+ PhoshHostname1DBusHostname1 *proxy;
- self->proxy = phosh_hostname1_dbus_hostname1_proxy_new_for_bus_finish (res, &err);
- if (!self->proxy) {
- g_warning ("Failed to get hostname1 proxy: %s", err->message);
- goto out;
+ proxy = phosh_hostname1_dbus_hostname1_proxy_new_for_bus_finish (res, &err);
+ if (proxy == NULL) {
+ phosh_async_error_warn (err, "Failed to get hostname1 proxy");
+ return;
}
+ g_return_if_fail (PHOSH_IS_MODE_MANAGER (self));
+ self->proxy = proxy;
g_debug ("Hostname1 interface initialized");
g_signal_connect_object (self->proxy,
@@ -224,6 +227,7 @@
G_CONNECT_SWAPPED);
on_chassis_changed (self, NULL, self->proxy);
+ wl = phosh_wayland_get_default ();
g_signal_connect_object (wl,
"notify::seat-capabilities",
G_CALLBACK (on_seat_capabilities_changed),
@@ -237,24 +241,21 @@
self,
G_CONNECT_SWAPPED);
/* n_monitors is always updated in update_props () */
-
-out:
- g_object_unref (self);
}
-static gboolean
-on_idle (PhoshTorchManager *self)
+static void
+phosh_mode_manager_idle_init (PhoshManager *manager)
{
+ PhoshModeManager *self = PHOSH_MODE_MANAGER (manager);
+
phosh_hostname1_dbus_hostname1_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
BUS_NAME,
OBJECT_PATH,
- NULL,
+ self->cancel,
(GAsyncReadyCallback) on_proxy_new_for_bus_finish,
- g_object_ref (self));
-
- return G_SOURCE_REMOVE;
+ self);
}
static void
@@ -265,9 +266,6 @@
G_OBJECT_CLASS (phosh_mode_manager_parent_class)->constructed (object);
self->monitor_manager = phosh_shell_get_monitor_manager (phosh_shell_get_default ());
-
- /* Perform DBus setup when idle */
- g_idle_add ((GSourceFunc)on_idle, self);
}
@@ -276,6 +274,9 @@
{
PhoshModeManager *self = PHOSH_MODE_MANAGER (object);
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
g_clear_object (&self->proxy);
G_OBJECT_CLASS (phosh_mode_manager_parent_class)->dispose (object);
@@ -297,12 +298,15 @@
phosh_mode_manager_class_init (PhoshModeManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshManagerClass *manager_class = PHOSH_MANAGER_CLASS (klass);
object_class->constructed = phosh_mode_manager_constructed;
object_class->dispose = phosh_mode_manager_dispose;
object_class->finalize = phosh_mode_manager_finalize;
object_class->get_property = phosh_mode_manager_get_property;
+ manager_class->idle_init = phosh_mode_manager_idle_init;
+
props[PROP_DEVICE_TYPE] =
g_param_spec_enum ("device-type",
"Device Type",
@@ -351,6 +355,7 @@
self->hw_flags = PHOSH_MODE_HW_NONE;
self->device_type = PHOSH_MODE_DEVICE_TYPE_UNKNOWN;
self->mimicry = PHOSH_MODE_DEVICE_TYPE_UNKNOWN;
+ self->cancel = g_cancellable_new ();
}
diff -Nru phosh-0.8.0/src/mode-manager.h phosh-0.13.1/src/mode-manager.h
--- phosh-0.8.0/src/mode-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/mode-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,6 +6,8 @@
#pragma once
+#include
+
#include
@@ -54,7 +56,7 @@
#define PHOSH_TYPE_MODE_MANAGER (phosh_mode_manager_get_type ())
-G_DECLARE_FINAL_TYPE (PhoshModeManager, phosh_mode_manager, PHOSH, MODE_MANAGER, GObject)
+G_DECLARE_FINAL_TYPE (PhoshModeManager, phosh_mode_manager, PHOSH, MODE_MANAGER, PhoshManager)
PhoshModeManager *phosh_mode_manager_new (void);
PhoshModeDeviceType phosh_mode_manager_get_device_type (PhoshModeManager *self);
diff -Nru phosh-0.8.0/src/monitor/head.c phosh-0.13.1/src/monitor/head.c
--- phosh-0.8.0/src/monitor/head.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor/head.c 2021-08-31 09:15:52.000000000 +0000
@@ -38,8 +38,10 @@
#define MINIMUM_LOGICAL_AREA_LANDSCAPE (800 * 480)
#define MINIMUM_LOGICAL_AREA_PORTRAIT (360 * 720)
-#define MINIMUM_SCALE_FACTOR 1
-#define MAXIMUM_SCALE_FACTOR 4
+#define MINIMUM_SCALE_FACTOR 1.0f
+#define MAXIMUM_SCALE_FACTOR 4.0f
+#define SCALE_FACTORS_PER_INTEGER 4
+#define SCALE_FACTORS_STEPS (1.0 / (float) SCALE_FACTORS_PER_INTEGER)
G_DEFINE_TYPE (PhoshHead, phosh_head, G_TYPE_OBJECT);
@@ -71,29 +73,24 @@
static gboolean
-is_logical_size_large_enough (int width, int height)
+is_logical_size_large_enough (float width, float height)
{
- if (width > height)
- return width * height >= MINIMUM_LOGICAL_AREA_LANDSCAPE;
- else
- return width * height >= MINIMUM_LOGICAL_AREA_PORTRAIT;
+ int area = (width > height) ? MINIMUM_LOGICAL_AREA_LANDSCAPE : MINIMUM_LOGICAL_AREA_PORTRAIT;
+
+ return width * height >= area;
}
static gboolean
-is_valid_scale (int width, int height, int scale)
+is_valid_scale (float width, float height, float scale)
{
- int scaled_h = height / scale;
- int scaled_w = width / scale;
+ float scaled_h = height / scale;
+ float scaled_w = width / scale;
- if (scale < MINIMUM_SCALE_FACTOR || scale > MAXIMUM_SCALE_FACTOR ||
- !is_logical_size_large_enough (scaled_w, scaled_h))
+ if (scale < MINIMUM_SCALE_FACTOR || scale > MAXIMUM_SCALE_FACTOR)
return FALSE;
- if (width % scale == 0 && height % scale == 0)
- return TRUE;
-
- return FALSE;
+ return is_logical_size_large_enough (floorf (scaled_w), floorf(scaled_h));
}
@@ -353,8 +350,8 @@
g_return_if_fail (PHOSH_IS_HEAD (self));
g_free (self->serial);
- self->product = g_strdup (serial_number);
- g_debug ("Head %p has serial %s", self, self->product);
+ self->serial = g_strdup (serial_number);
+ g_debug ("Head %p has serial %s", self, self->serial);
}
@@ -586,28 +583,108 @@
}
-int *
+static float
+get_closest_scale_factor_for_resolution (float width, float height, float scale, float threshold)
+{
+ unsigned int i;
+ float scaled_h;
+ float scaled_w;
+ float best_scale;
+ int base_scaled_w;
+ gboolean found_one;
+
+ best_scale = 0;
+
+ if (!is_valid_scale (width, height, scale))
+ return 0.0;
+
+ if ((int)fmodf (width, scale) == 0 && (int)fmodf (height, scale) == 0)
+ return scale;
+
+ i = 0;
+ found_one = FALSE;
+ base_scaled_w = floorf (width / scale);
+
+ do {
+ for (int j = 0; j < 2; j++) {
+ float current_scale;
+ int offset = i * (j ? 1 : -1);
+
+ scaled_w = base_scaled_w + offset;
+ current_scale = width / scaled_w;
+ scaled_h = height / current_scale;
+
+ if (current_scale >= scale + threshold ||
+ current_scale <= scale - threshold ||
+ current_scale < MINIMUM_SCALE_FACTOR ||
+ current_scale > MAXIMUM_SCALE_FACTOR) {
+ return best_scale;
+ }
+
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+ if (floorf (scaled_h) == scaled_h) {
+#pragma GCC diagnostic error "-Wfloat-equal"
+ found_one = TRUE;
+
+ if (fabsf (current_scale - scale) < fabsf (best_scale - scale))
+ best_scale = current_scale;
+ }
+ }
+ i++;
+ } while (!found_one);
+
+ return best_scale;
+}
+
+
+float *
phosh_head_calculate_supported_mode_scales (PhoshHead *head,
PhoshHeadMode *mode,
- int *n_supported_scales)
+ int *n_supported_scales,
+ gboolean fractional)
{
- unsigned int i;
GArray *supported_scales;
- supported_scales = g_array_new (FALSE, FALSE, sizeof (int));
+ supported_scales = g_array_new (FALSE, FALSE, sizeof (float));
- for (i = MINIMUM_SCALE_FACTOR; i <= MAXIMUM_SCALE_FACTOR; i++) {
- if (is_valid_scale (mode->width, mode->height, i))
- g_array_append_val (supported_scales, i);
+ if (fractional) {
+ for (int i = floorf (MINIMUM_SCALE_FACTOR); i <= ceilf (MAXIMUM_SCALE_FACTOR); i++) {
+ float max_bound;
+
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+ if (i == floorf (MINIMUM_SCALE_FACTOR) || i == ceilf (MAXIMUM_SCALE_FACTOR)) {
+#pragma GCC diagnostic error "-Wfloat-equal"
+ max_bound = SCALE_FACTORS_STEPS;
+ } else {
+ max_bound = SCALE_FACTORS_STEPS / 2.0;
+ }
+
+ for (int j = 0; j < SCALE_FACTORS_PER_INTEGER; j++) {
+ float scale;
+ float scale_value = i + j * SCALE_FACTORS_STEPS;
+
+ scale = get_closest_scale_factor_for_resolution (mode->width, mode->height,
+ scale_value,
+ max_bound);
+ if (scale > 0.0)
+ g_array_append_val (supported_scales, scale);
+ }
+ }
+ } else {
+ for (float f = floorf (MINIMUM_SCALE_FACTOR); f <= ceilf (MAXIMUM_SCALE_FACTOR); f++) {
+ if (is_valid_scale (mode->width, mode->height, f)) {
+ g_array_append_val (supported_scales, f);
+ }
+ }
}
if (supported_scales->len == 0) {
- int fallback_scale = 1;
+ float fallback_scale = 1.0;
g_array_append_val (supported_scales, fallback_scale);
}
*n_supported_scales = supported_scales->len;
- return (int *) g_array_free (supported_scales, FALSE);
+ return (float *) g_array_free (supported_scales, FALSE);
}
/**
diff -Nru phosh-0.8.0/src/monitor/head.h phosh-0.13.1/src/monitor/head.h
--- phosh-0.8.0/src/monitor/head.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor/head.h 2021-08-31 09:15:52.000000000 +0000
@@ -71,9 +71,10 @@
PhoshHeadMode *phosh_head_get_preferred_mode (PhoshHead *self);
gboolean phosh_head_is_builtin (PhoshHead *self);
PhoshHeadMode *phosh_head_find_mode_by_name (PhoshHead *self, const char *name);
-int * phosh_head_calculate_supported_mode_scales (PhoshHead *head,
+float * phosh_head_calculate_supported_mode_scales (PhoshHead *head,
PhoshHeadMode *mode,
- int *n);
+ int *n,
+ gboolean fractional);
void phosh_head_clear_pending (PhoshHead *self);
G_END_DECLS
diff -Nru phosh-0.8.0/src/monitor/meson.build phosh-0.13.1/src/monitor/meson.build
--- phosh-0.8.0/src/monitor/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -1,14 +1,6 @@
-generated_monitor_sources = gnome.gdbus_codegen(
- 'phosh-display-dbus',
- 'org.gnome.Mutter.DisplayConfig.xml',
- interface_prefix: 'org.gnome.Mutter',
- namespace: 'PhoshDisplayDbus',
-)
-
phosh_monitor_sources = [
'monitor/head.c',
'monitor/head.h',
'monitor/monitor.c',
'monitor/monitor.h',
- generated_monitor_sources,
]
diff -Nru phosh-0.8.0/src/monitor/monitor.c phosh-0.13.1/src/monitor/monitor.c
--- phosh-0.8.0/src/monitor/monitor.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor/monitor.c 2021-08-31 09:15:52.000000000 +0000
@@ -89,8 +89,8 @@
{
PhoshMonitor *self = PHOSH_MONITOR (data);
+ /* nothing to do */
self->wl_output_done = FALSE;
- self->scale = scale;
}
@@ -168,7 +168,6 @@
g_debug ("Monitor %p: Logical size: %dx%d", self, width, height);
self->logical.width = width;
self->logical.height = height;
-
}
@@ -259,7 +258,7 @@
wlr_output_power_handle_failed(void *data,
struct zwlr_output_power_v1 *output_power)
{
- PhoshMonitor *self = data;
+ PhoshMonitor *self = PHOSH_MONITOR (data);
g_return_if_fail (PHOSH_IS_MONITOR (self));
g_warning("Failed to set output power mode for %s\n", self->name);
@@ -405,7 +404,6 @@
static void
phosh_monitor_init (PhoshMonitor *self)
{
- self->scale = 1.0;
self->modes = g_array_new (FALSE, FALSE, sizeof(PhoshMonitorMode));
self->power_mode = PHOSH_MONITOR_POWER_SAVE_MODE_OFF;
}
@@ -601,3 +599,40 @@
return FALSE;
}
}
+
+struct wl_output*
+phosh_monitor_get_wl_output (PhoshMonitor *self)
+{
+ g_return_val_if_fail (PHOSH_IS_MONITOR (self), NULL);
+
+ return self->wl_output;
+}
+
+/**
+ * phosh_monitor_get_fractional_scale:
+ * @self: The monitor
+ *
+ * Get the fractinoal scale determined from the output width and the
+ * current logical width.
+ * Returns: the fractional scale
+*/
+float
+phosh_monitor_get_fractional_scale (PhoshMonitor *self)
+{
+ float width;
+
+ g_return_val_if_fail (PHOSH_IS_MONITOR (self), 1.0);
+ g_return_val_if_fail (phosh_monitor_is_configured (self), 1.0);
+
+ switch (self->transform) {
+ case PHOSH_MONITOR_TRANSFORM_NORMAL:
+ case PHOSH_MONITOR_TRANSFORM_180:
+ case PHOSH_MONITOR_TRANSFORM_FLIPPED:
+ case PHOSH_MONITOR_TRANSFORM_FLIPPED_180:
+ width = self->logical.width;
+ break;
+ default:
+ width = self->logical.height;
+ }
+ return self->width / width;
+}
diff -Nru phosh-0.8.0/src/monitor/monitor.h phosh-0.13.1/src/monitor/monitor.h
--- phosh-0.8.0/src/monitor/monitor.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor/monitor.h 2021-08-31 09:15:52.000000000 +0000
@@ -117,7 +117,7 @@
int x, y, width, height;
int subpixel;
- gint32 transform, scale;
+ gint32 transform;
struct {
gint32 x, y, width, height;
@@ -154,5 +154,7 @@
PhoshMonitorPowerSaveMode phosh_monitor_get_power_save_mode (PhoshMonitor *self);
PhoshMonitorConnectorType phosh_monitor_connector_type_from_name (const char *name);
gboolean phosh_monitor_connector_is_builtin (PhoshMonitorConnectorType type);
+struct wl_output * phosh_monitor_get_wl_output (PhoshMonitor *self);
+float phosh_monitor_get_fractional_scale (PhoshMonitor *self);
G_END_DECLS
diff -Nru phosh-0.8.0/src/monitor/org.gnome.Mutter.DisplayConfig.xml phosh-0.13.1/src/monitor/org.gnome.Mutter.DisplayConfig.xml
--- phosh-0.8.0/src/monitor/org.gnome.Mutter.DisplayConfig.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor/org.gnome.Mutter.DisplayConfig.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,453 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -Nru phosh-0.8.0/src/monitor-manager.c phosh-0.13.1/src/monitor-manager.c
--- phosh-0.8.0/src/monitor-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -25,8 +25,10 @@
* @short_description: The singleton that manages available monitors
* @Title: PhoshMonitorManager
*
- * #PhoshMonitorManager keeps tracks of and configure available monitors
- * and handles the "org.gnome.Mutter.DisplayConfig" DBus protocol.
+ * This keeps track of all monitors and handles the
+ * org.gnome.Mutter.DisplayConfig DBus interface via
+ * #PhoshDBusDisplayConfig. This includes individual monitor
+ * configuration as well as blanking/power saving.
*/
/* Equivalent to the 'layout-mode' enum in org.gnome.Mutter.DisplayConfig */
@@ -37,6 +39,7 @@
enum {
PROP_0,
+ PROP_SENSOR_PROXY_MANAGER,
PROP_N_MONITORS,
PROP_LAST_PROP
};
@@ -50,11 +53,14 @@
static guint signals[N_SIGNALS] = { 0 };
static void phosh_monitor_manager_display_config_init (
- PhoshDisplayDbusDisplayConfigIface *iface);
+ PhoshDBusDisplayConfigIface *iface);
typedef struct _PhoshMonitorManager
{
- PhoshDisplayDbusDisplayConfigSkeleton parent;
+ PhoshDBusDisplayConfigSkeleton parent;
+
+ PhoshSensorProxyManager *sensor_proxy_manager;
+ GBinding *sensor_proxy_binding;
GPtrArray *monitors; /* Currently known monitors */
GPtrArray *heads; /* Currently known heads */
@@ -67,9 +73,9 @@
G_DEFINE_TYPE_WITH_CODE (PhoshMonitorManager,
phosh_monitor_manager,
- PHOSH_DISPLAY_DBUS_TYPE_DISPLAY_CONFIG_SKELETON,
+ PHOSH_DBUS_TYPE_DISPLAY_CONFIG_SKELETON,
G_IMPLEMENT_INTERFACE (
- PHOSH_DISPLAY_DBUS_TYPE_DISPLAY_CONFIG,
+ PHOSH_DBUS_TYPE_DISPLAY_CONFIG,
phosh_monitor_manager_display_config_init));
@@ -130,7 +136,7 @@
return g_strdup_printf (C_("This is a monitor vendor name followed by "
"product/model name where size in inches "
"could not be calculated, e.g. Dell U2414H",
- "%s %sn"),
+ "%s %s"),
vendor_name, product_name);
}
}
@@ -156,42 +162,13 @@
return NULL;
}
-
-static gint32
-phosh_monitor_manager_flip_transform (PhoshMonitorTransform transform)
-{
- /* Wayland rotation is opposite from DBus */
- switch (transform) {
- case PHOSH_MONITOR_TRANSFORM_90:
- return WL_OUTPUT_TRANSFORM_270;
- break;
- case PHOSH_MONITOR_TRANSFORM_270:
- return WL_OUTPUT_TRANSFORM_90;
- break;
- case PHOSH_MONITOR_TRANSFORM_FLIPPED_90:
- return WL_OUTPUT_TRANSFORM_FLIPPED_270;
- break;
- case PHOSH_MONITOR_TRANSFORM_FLIPPED_270:
- return WL_OUTPUT_TRANSFORM_FLIPPED_90;
- break;
- case PHOSH_MONITOR_TRANSFORM_NORMAL:
- case PHOSH_MONITOR_TRANSFORM_180:
- case PHOSH_MONITOR_TRANSFORM_FLIPPED:
- case PHOSH_MONITOR_TRANSFORM_FLIPPED_180:
- default:
- /* Nothing to be done */
- return transform;
- }
-}
-
/*
* DBus Interface
*/
static gboolean
-phosh_monitor_manager_handle_get_resources (
- PhoshDisplayDbusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation)
+phosh_monitor_manager_handle_get_resources (PhoshDBusDisplayConfig *skeleton,
+ GDBusMethodInvocation *invocation)
{
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
GVariantBuilder crtc_builder, output_builder, mode_builder;
@@ -285,7 +262,7 @@
/* Don't bother setting up modes, they're ignored */
- phosh_display_dbus_display_config_complete_get_resources (
+ phosh_dbus_display_config_complete_get_resources (
skeleton,
invocation,
self->serial,
@@ -301,12 +278,11 @@
static gboolean
-phosh_monitor_manager_handle_change_backlight (
- PhoshDisplayDbusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation,
- guint serial,
- guint output_index,
- int value)
+phosh_monitor_manager_handle_change_backlight (PhoshDBusDisplayConfig *skeleton,
+ GDBusMethodInvocation *invocation,
+ guint serial,
+ guint output_index,
+ int value)
{
g_debug ("Unimplemented DBus call %s", __func__);
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@@ -317,7 +293,7 @@
struct get_wl_gamma_callback_data {
- PhoshDisplayDbusDisplayConfig *skeleton;
+ PhoshDBusDisplayConfig *skeleton;
GDBusMethodInvocation *invocation;
};
@@ -342,7 +318,7 @@
green_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), green_bytes, TRUE);
blue_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), blue_bytes, TRUE);
- phosh_display_dbus_display_config_complete_get_crtc_gamma (
+ phosh_dbus_display_config_complete_get_crtc_gamma (
gamma_callback_data->skeleton,
gamma_callback_data->invocation,
red_v, green_v, blue_v);
@@ -363,11 +339,10 @@
static gboolean
-phosh_monitor_manager_handle_get_crtc_gamma (
- PhoshDisplayDbusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation,
- guint serial,
- guint crtc_id)
+phosh_monitor_manager_handle_get_crtc_gamma (PhoshDBusDisplayConfig *skeleton,
+ GDBusMethodInvocation *invocation,
+ guint serial,
+ guint crtc_id)
{
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
PhoshMonitor *monitor;
@@ -415,14 +390,13 @@
static gboolean
-phosh_monitor_manager_handle_set_crtc_gamma (
- PhoshDisplayDbusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation,
- guint serial,
- guint crtc_id,
- GVariant *red_v,
- GVariant *green_v,
- GVariant *blue_v)
+phosh_monitor_manager_handle_set_crtc_gamma (PhoshDBusDisplayConfig *skeleton,
+ GDBusMethodInvocation *invocation,
+ guint serial,
+ guint crtc_id,
+ GVariant *red_v,
+ GVariant *green_v,
+ GVariant *blue_v)
{
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
PhoshMonitor *monitor;
@@ -493,7 +467,7 @@
gamma_control_set_gamma(gamma_control, &wl_red, &wl_green, &wl_blue);
gamma_control_destroy (gamma_control);
- phosh_display_dbus_display_config_complete_set_crtc_gamma (
+ phosh_dbus_display_config_complete_set_crtc_gamma (
skeleton,
invocation);
@@ -521,9 +495,8 @@
static gboolean
-phosh_monitor_manager_handle_get_current_state (
- PhoshDisplayDbusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation)
+phosh_monitor_manager_handle_get_current_state (PhoshDBusDisplayConfig *skeleton,
+ GDBusMethodInvocation *invocation)
{
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
GVariantBuilder monitors_builder, logical_monitors_builder, properties_builder;
@@ -567,7 +540,7 @@
for (int k = 0; k < head->modes->len; k++) {
PhoshHeadMode *mode = g_ptr_array_index (head->modes, k);
- g_autofree int *scales = NULL;
+ g_autofree float *scales = NULL;
if (!mode->name) {
g_warning ("Skipping unnamend mode %p", mode);
continue;
@@ -575,7 +548,7 @@
g_variant_builder_init (&supported_scales_builder,
G_VARIANT_TYPE ("ad"));
- scales = phosh_head_calculate_supported_mode_scales (head, mode, &n);
+ scales = phosh_head_calculate_supported_mode_scales (head, mode, &n, TRUE);
for (int l = 0; l < n; l++) {
g_variant_builder_add (&supported_scales_builder, "d",
(double)scales[l]);
@@ -657,9 +630,6 @@
}
g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}"));
- g_variant_builder_add (&properties_builder, "{sv}",
- "supports-mirroring",
- g_variant_new_boolean (FALSE));
g_variant_builder_add (&properties_builder, "{sv}",
"layout-mode",
@@ -669,7 +639,7 @@
"supports-changing-layout-mode",
g_variant_new_boolean (TRUE));
- phosh_display_dbus_display_config_complete_get_current_state (
+ phosh_dbus_display_config_complete_get_current_state (
skeleton,
invocation,
self->serial,
@@ -803,7 +773,7 @@
head->pending.scale = scale;
head->pending.x = x;
head->pending.y = y;
- head->pending.transform = phosh_monitor_manager_flip_transform (transform);
+ head->pending.transform = transform;
head->pending.enabled = TRUE;
head->pending.seen = TRUE;
}
@@ -818,13 +788,12 @@
static gboolean
-phosh_monitor_manager_handle_apply_monitors_config (
- PhoshDisplayDbusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation,
- guint serial,
- guint method,
- GVariant *logical_monitor_configs_variant,
- GVariant *properties_variant)
+phosh_monitor_manager_handle_apply_monitors_config (PhoshDBusDisplayConfig *skeleton,
+ GDBusMethodInvocation *invocation,
+ guint serial,
+ guint method,
+ GVariant *logical_monitor_configs_variant,
+ GVariant *properties_variant)
{
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
GVariantIter logical_monitor_configs_iter;
@@ -940,7 +909,7 @@
phosh_monitor_manager_apply_monitor_config (self);
}
- phosh_display_dbus_display_config_complete_apply_monitors_config (
+ phosh_dbus_display_config_complete_apply_monitors_config (
skeleton,
invocation);
@@ -949,7 +918,7 @@
static void
-phosh_monitor_manager_display_config_init (PhoshDisplayDbusDisplayConfigIface *iface)
+phosh_monitor_manager_display_config_init (PhoshDBusDisplayConfigIface *iface)
{
iface->handle_get_resources = phosh_monitor_manager_handle_get_resources;
iface->handle_change_backlight = phosh_monitor_manager_handle_change_backlight;
@@ -967,8 +936,8 @@
{
int mode, ps_mode;
- mode = phosh_display_dbus_display_config_get_power_save_mode (
- PHOSH_DISPLAY_DBUS_DISPLAY_CONFIG (self));
+ mode = phosh_dbus_display_config_get_power_save_mode (
+ PHOSH_DBUS_DISPLAY_CONFIG (self));
g_debug ("Power save mode %d requested", mode);
switch (mode) {
@@ -1011,7 +980,7 @@
const char *name,
gpointer user_data)
{
- PhoshMonitorManager *self = user_data;
+ PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (user_data);
/* We need to use Mutter's object path here to make gnome-settings happy */
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
@@ -1037,6 +1006,19 @@
static void
+on_monitor_configured (PhoshMonitorManager *self, PhoshMonitor *monitor)
+{
+ g_return_if_fail (PHOSH_IS_MONITOR_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_MONITOR (monitor));
+
+ g_signal_emit (self, signals[SIGNAL_MONITOR_ADDED], 0, monitor);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_N_MONITORS]);
+
+ g_signal_handlers_disconnect_by_data (monitor, self);
+}
+
+
+static void
on_monitor_removed (PhoshMonitorManager *self,
PhoshMonitor *monitor,
gpointer *data)
@@ -1051,6 +1033,18 @@
static void
+phosh_monitor_manager_add_monitor (PhoshMonitorManager *self, PhoshMonitor *monitor)
+{
+ g_ptr_array_add (self->monitors, monitor);
+ /* Delay emmission of 'monitor-added' until it's configured */
+ g_signal_connect_swapped (monitor,
+ "configured",
+ G_CALLBACK (on_monitor_configured),
+ self);
+}
+
+
+static void
on_wl_outputs_changed (PhoshMonitorManager *self, GParamSpec *pspec, PhoshWayland *wl)
{
GHashTable *wl_outputs = phosh_wayland_get_wl_outputs (wl);
@@ -1098,7 +1092,7 @@
else
g_warning ("Tried to remove inexistend head %p", head);
- phosh_display_dbus_display_config_emit_monitors_changed (PHOSH_DISPLAY_DBUS_DISPLAY_CONFIG (self));
+ phosh_dbus_display_config_emit_monitors_changed (PHOSH_DBUS_DISPLAY_CONFIG (self));
}
@@ -1117,7 +1111,7 @@
g_ptr_array_add (self->heads, head);
g_signal_connect_swapped (head, "head-finished", G_CALLBACK (on_head_finished), self);
- phosh_display_dbus_display_config_emit_monitors_changed (PHOSH_DISPLAY_DBUS_DISPLAY_CONFIG (self));
+ phosh_dbus_display_config_emit_monitors_changed (PHOSH_DBUS_DISPLAY_CONFIG (self));
}
@@ -1133,7 +1127,7 @@
self->zwlr_output_serial = serial;
self->serial++;
- phosh_display_dbus_display_config_emit_monitors_changed (PHOSH_DISPLAY_DBUS_DISPLAY_CONFIG (self));
+ phosh_dbus_display_config_emit_monitors_changed (PHOSH_DBUS_DISPLAY_CONFIG (self));
}
@@ -1179,6 +1173,23 @@
static void
+phosh_monitor_manager_dispose (GObject *object)
+{
+ PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (object);
+
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
+
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_object (&self->sensor_proxy_manager);
+ g_clear_pointer (&self->sensor_proxy_binding, g_binding_unbind);
+
+ G_OBJECT_CLASS (phosh_monitor_manager_parent_class)->dispose (object);
+}
+
+
+static void
phosh_monitor_manager_finalize (GObject *object)
{
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (object);
@@ -1194,6 +1205,25 @@
*/
static void
+phosh_monitor_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_SENSOR_PROXY_MANAGER:
+ phosh_monitor_manager_set_sensor_proxy_manager (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
phosh_monitor_manager_get_property (GObject *object,
guint property_id,
GValue *value,
@@ -1202,6 +1232,9 @@
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (object);
switch (property_id) {
+ case PROP_SENSOR_PROXY_MANAGER:
+ g_value_set_object (value, self->sensor_proxy_manager);
+ break;
case PROP_N_MONITORS:
g_value_set_int (value, self->monitors->len);
break;
@@ -1222,8 +1255,8 @@
on_bus_acquired,
on_name_acquired,
on_name_lost,
- g_object_ref (self),
- g_object_unref);
+ self,
+ NULL);
return FALSE;
}
@@ -1268,8 +1301,18 @@
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = phosh_monitor_manager_constructed;
+ object_class->dispose = phosh_monitor_manager_dispose;
object_class->finalize = phosh_monitor_manager_finalize;
object_class->get_property = phosh_monitor_manager_get_property;
+ object_class->set_property = phosh_monitor_manager_set_property;
+
+ props[PROP_SENSOR_PROXY_MANAGER] =
+ g_param_spec_object ("sensor-proxy-manager",
+ "Sensor Proxy Manager",
+ "Sensor Proxy Manager",
+ PHOSH_TYPE_SENSOR_PROXY_MANAGER,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
props[PROP_N_MONITORS] =
g_param_spec_int ("n-monitors",
@@ -1289,10 +1332,7 @@
* @manager: The #PhoshMonitorManager emitting the signal.
* @monitor: The #PhoshMonitor being added.
*
- * Emitted whenever a monitor is about to be added. Note
- * that the monitor might not yet be fully initialized. Use
- * phosh_monitor_is_configured() to check or listen for
- * the #PhoshMonitor::configured signal.
+ * Emitted whenever a monitor was added.
*/
signals[SIGNAL_MONITOR_ADDED] = g_signal_new (
"monitor-added",
@@ -1325,18 +1365,11 @@
PhoshMonitorManager *
-phosh_monitor_manager_new (void)
+phosh_monitor_manager_new (PhoshSensorProxyManager *proxy)
{
- return g_object_new (PHOSH_TYPE_MONITOR_MANAGER, NULL);
-}
-
-
-void
-phosh_monitor_manager_add_monitor (PhoshMonitorManager *self, PhoshMonitor *monitor)
-{
- g_ptr_array_add (self->monitors, monitor);
- g_signal_emit (self, signals[SIGNAL_MONITOR_ADDED], 0, monitor);
- g_object_notify_by_pspec (G_OBJECT (self), props[PROP_N_MONITORS]);
+ return g_object_new (PHOSH_TYPE_MONITOR_MANAGER,
+ "sensor-proxy-manager", proxy,
+ NULL);
}
@@ -1369,9 +1402,10 @@
}
/**
- * phosh_monitor_set_transform:
+ * phosh_monitor_manager_set_monitor_transform:
* @self: A #PhoshMonitor
- * @mode: The #PhoshMonitorPowerSaveMode
+ * @monitor: The #PhoshMonitor to set the tansform on
+ * @transform: The #PhoshMonitorTransform to set
*
* Sets monitor's transform. This will become active after the next
* call to #phosh_monitor_manager_apply_monitor_config().
@@ -1446,3 +1480,24 @@
zwlr_output_configuration_v1_apply (config);
}
+
+void
+phosh_monitor_manager_set_sensor_proxy_manager (PhoshMonitorManager *self,
+ PhoshSensorProxyManager *manager)
+{
+ g_return_if_fail (PHOSH_IS_MONITOR_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_SENSOR_PROXY_MANAGER (manager) || manager == NULL);
+
+ g_clear_object (&self->sensor_proxy_manager);
+ g_clear_pointer (&self->sensor_proxy_binding, g_binding_unbind);
+
+ if (manager == NULL)
+ return;
+
+ self->sensor_proxy_manager = g_object_ref (manager);
+ self->sensor_proxy_binding = g_object_bind_property (manager, "has-accelerometer",
+ self, "panel-orientation-managed",
+ G_BINDING_SYNC_CREATE);
+
+
+}
diff -Nru phosh-0.8.0/src/monitor-manager.h phosh-0.13.1/src/monitor-manager.h
--- phosh-0.8.0/src/monitor-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/monitor-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -7,8 +7,11 @@
*/
#pragma once
-#include "monitor/phosh-display-dbus.h"
+#include "phosh-display-dbus.h"
#include "monitor/monitor.h"
+
+#include "sensor-proxy-manager.h"
+
#include
G_BEGIN_DECLS
@@ -30,11 +33,9 @@
#define PHOSH_TYPE_MONITOR_MANAGER (phosh_monitor_manager_get_type ())
G_DECLARE_FINAL_TYPE (PhoshMonitorManager, phosh_monitor_manager, PHOSH, MONITOR_MANAGER,
- PhoshDisplayDbusDisplayConfigSkeleton)
+ PhoshDBusDisplayConfigSkeleton)
-PhoshMonitorManager * phosh_monitor_manager_new (void);
-void phosh_monitor_manager_add_monitor (PhoshMonitorManager *self,
- PhoshMonitor *monitor);
+PhoshMonitorManager * phosh_monitor_manager_new (PhoshSensorProxyManager *proxy);
PhoshMonitor * phosh_monitor_manager_get_monitor (PhoshMonitorManager *self,
guint num);
guint phosh_monitor_manager_get_num_monitors (PhoshMonitorManager *self);
@@ -44,5 +45,6 @@
PhoshMonitor *monitor,
PhoshMonitorTransform transform);
void phosh_monitor_manager_apply_monitor_config (PhoshMonitorManager *self);
-
+void phosh_monitor_manager_set_sensor_proxy_manager (PhoshMonitorManager *self,
+ PhoshSensorProxyManager *manager);
G_END_DECLS
diff -Nru phosh-0.8.0/src/mount-manager.c phosh-0.13.1/src/mount-manager.c
--- phosh-0.8.0/src/mount-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/mount-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -11,6 +11,7 @@
#include "config.h"
#include "feedback-manager.h"
#include "mount-manager.h"
+#include "mount-operation.h"
#include "notifications/mount-notification.h"
#include "notifications/notify-manager.h"
#include "shell.h"
@@ -101,8 +102,9 @@
on_volume_added (PhoshMountManager *self, GVolume *vol, GVolumeMonitor *monitor)
{
gboolean automount;
- gpointer ignore_lock;
+ gboolean mount_all;
GCancellable *cancellable;
+ g_autoptr (PhoshMountOperation) op = NULL;
g_autoptr (GMount) mount = NULL;
g_autofree gchar *name = NULL;
@@ -116,8 +118,9 @@
if (!phosh_shell_is_session_active (phosh_shell_get_default ()))
return;
- ignore_lock = g_object_get_data (G_OBJECT (vol), "phosh-ignore-lock");
- if (phosh_shell_get_locked (phosh_shell_get_default ()) && !ignore_lock)
+ mount_all = !!g_object_get_data (G_OBJECT (vol), "phosh-mount-all");
+ /* Initial mount-all is o.k. even when locked */
+ if (phosh_shell_get_locked (phosh_shell_get_default ()) && !mount_all)
return;
mount = g_volume_get_mount (vol);
@@ -133,12 +136,16 @@
return;
}
+ /* If this is not the intial 'mount-all' run allow UI interaction */
+ if (!mount_all)
+ op = phosh_mount_operation_new ();
+
cancellable = g_cancellable_new ();
g_object_set_data (G_OBJECT (vol), "phosh-cancel", cancellable);
g_ptr_array_add (self->cancellables, cancellable);
g_ptr_array_ref (self->cancellables);
g_debug ("Mounting '%s'", name);
- g_volume_mount (g_object_ref (vol), G_MOUNT_MOUNT_NONE, NULL, cancellable,
+ g_volume_mount (g_object_ref (vol), G_MOUNT_MOUNT_NONE, G_MOUNT_OPERATION (op), cancellable,
(GAsyncReadyCallback)on_mount_finished, g_object_ref (self));
}
@@ -243,7 +250,7 @@
for (GList *elem = volumes; elem != NULL; elem = elem->next) {
GVolume *vol = G_VOLUME (elem->data);
/* Ignore screen lock on initial startup */
- g_object_set_data (G_OBJECT (vol), "phosh-ignore-lock", GINT_TO_POINTER (TRUE));
+ g_object_set_data (G_OBJECT (vol), "phosh-mount-all", GINT_TO_POINTER (TRUE));
on_volume_added (self, vol, self->monitor);
}
diff -Nru phosh-0.8.0/src/mount-operation.c phosh-0.13.1/src/mount-operation.c
--- phosh-0.8.0/src/mount-operation.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/mount-operation.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-mount-operation"
+
+#include "config.h"
+
+#include "gtk-mount-prompt.h"
+#include "mount-operation.h"
+#include "util.h"
+
+/**
+ * SECTION:mount-operation
+ * @short_description: #GMountOperation using UI
+ * @Title: PhoshMountOperation
+ *
+ * A #GMountOperation that uses system modal dialogs for input.
+ */
+
+struct _PhoshMountOperation {
+ GMountOperation parent;
+
+ PhoshGtkMountPrompt *prompt;
+};
+G_DEFINE_TYPE (PhoshMountOperation, phosh_mount_operation, G_TYPE_MOUNT_OPERATION)
+
+
+static void
+on_prompt_done (PhoshMountOperation *self, PhoshGtkMountPrompt *prompt)
+{
+ gboolean cancelled;
+ GMountOperationResult result = G_MOUNT_OPERATION_ABORTED;
+
+ g_return_if_fail (PHOSH_IS_MOUNT_OPERATION (self));
+ g_return_if_fail (PHOSH_IS_GTK_MOUNT_PROMPT (prompt));
+
+ cancelled = phosh_gtk_mount_prompt_get_cancelled (prompt);
+ g_debug ("Prompt done, cancelled: %d", cancelled);
+
+ if (!cancelled) {
+ GAskPasswordFlags flags = phosh_gtk_mount_prompt_get_ask_flags (prompt);
+
+ if (flags & G_ASK_PASSWORD_NEED_PASSWORD) {
+ const char *password;
+
+ password = phosh_gtk_mount_prompt_get_password (prompt);
+ g_mount_operation_set_password (G_MOUNT_OPERATION (self), password);
+ result = G_MOUNT_OPERATION_HANDLED;
+ }
+ }
+
+ g_mount_operation_reply (G_MOUNT_OPERATION (self), result);
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+}
+
+
+static void
+new_prompt (PhoshMountOperation *self,
+ const char *message,
+ const char *icon_name,
+ const char *default_user,
+ const char *default_domain,
+ GVariant *pids,
+ const char *const *choices,
+ GAskPasswordFlags ask_flags)
+{
+ g_debug ("New prompt for '%s'", message);
+
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+
+ self->prompt = PHOSH_GTK_MOUNT_PROMPT (phosh_gtk_mount_prompt_new (
+ message,
+ icon_name,
+ default_user,
+ default_domain,
+ pids,
+ choices,
+ ask_flags));
+ g_signal_connect_swapped (self->prompt,
+ "closed",
+ G_CALLBACK (on_prompt_done),
+ self);
+
+ gtk_widget_show (GTK_WIDGET (self->prompt));
+}
+
+
+static void
+phosh_mount_operation_ask_password (GMountOperation *op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
+ GAskPasswordFlags flags)
+{
+ PhoshMountOperation *self = PHOSH_MOUNT_OPERATION (op);
+
+ new_prompt (self, message,
+ NULL, /* icon */
+ default_user,
+ default_domain,
+ NULL, /* default_user */
+ NULL, /* choices */
+ flags);
+}
+
+
+static void
+phosh_mount_operation_dispose (GObject *object)
+{
+ PhoshMountOperation *self = PHOSH_MOUNT_OPERATION (object);
+
+ g_clear_pointer (&self->prompt, phosh_cp_widget_destroy);
+
+ G_OBJECT_CLASS (phosh_mount_operation_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_mount_operation_class_init (PhoshMountOperationClass *klass)
+{
+ GMountOperationClass *mount_op_class = G_MOUNT_OPERATION_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = phosh_mount_operation_dispose;
+
+ mount_op_class->ask_password = phosh_mount_operation_ask_password;
+}
+
+
+static void
+phosh_mount_operation_init (PhoshMountOperation *self)
+{
+}
+
+
+PhoshMountOperation *
+phosh_mount_operation_new (void)
+{
+ return PHOSH_MOUNT_OPERATION (g_object_new (PHOSH_TYPE_MOUNT_OPERATION, NULL));
+}
diff -Nru phosh-0.8.0/src/mount-operation.h phosh-0.13.1/src/mount-operation.h
--- phosh-0.8.0/src/mount-operation.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/mount-operation.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_MOUNT_OPERATION (phosh_mount_operation_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshMountOperation, phosh_mount_operation, PHOSH, MOUNT_OPERATION, GMountOperation)
+
+PhoshMountOperation *phosh_mount_operation_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/network-auth-prompt.c phosh-0.13.1/src/network-auth-prompt.c
--- phosh-0.8.0/src/network-auth-prompt.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/network-auth-prompt.c 2021-08-31 09:15:52.000000000 +0000
@@ -37,7 +37,7 @@
struct _PhoshNetworkAuthPrompt
{
- PhoshLayerSurface parent;
+ PhoshSystemModalDialog parent;
GtkWidget *cancel_button;
GtkWidget *connect_button;
@@ -62,7 +62,7 @@
gboolean visible; /* is input visible */
};
-G_DEFINE_TYPE(PhoshNetworkAuthPrompt, phosh_network_auth_prompt, PHOSH_TYPE_LAYER_SURFACE);
+G_DEFINE_TYPE(PhoshNetworkAuthPrompt, phosh_network_auth_prompt, PHOSH_TYPE_SYSTEM_MODAL_DIALOG);
static void
@@ -216,11 +216,12 @@
gtk_entry_buffer_set_text (GTK_ENTRY_BUFFER (self->password_buffer), password, -1);
}
+ gtk_widget_grab_focus (self->wpa_password_entry);
}
static void
-network_prompt_cancel_clicked_cb (PhoshNetworkAuthPrompt *self)
+on_dialog_canceled (PhoshNetworkAuthPrompt *self)
{
g_return_if_fail (PHOSH_IS_NETWORK_AUTH_PROMPT (self));
@@ -353,7 +354,7 @@
gtk_widget_class_bind_template_child (widget_class, PhoshNetworkAuthPrompt, wpa_password_entry);
gtk_widget_class_bind_template_child (widget_class, PhoshNetworkAuthPrompt, password_buffer);
- gtk_widget_class_bind_template_callback (widget_class, network_prompt_cancel_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_dialog_canceled);
gtk_widget_class_bind_template_callback (widget_class, network_prompt_connect_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, network_prompt_key_press_event_cb);
gtk_widget_class_bind_template_callback (widget_class, network_prompt_wpa_password_changed_cb);
@@ -370,28 +371,14 @@
GtkWidget *
phosh_network_auth_prompt_new (ShellNetworkAgent *agent,
- NMClient *nm_client,
- gpointer layer_shell,
- gpointer wl_output)
+ NMClient *nm_client)
{
PhoshNetworkAuthPrompt *self;
g_return_val_if_fail (SHELL_IS_NETWORK_AGENT (agent), NULL);
g_return_val_if_fail (NM_CLIENT (nm_client), NULL);
- self = g_object_new (PHOSH_TYPE_NETWORK_AUTH_PROMPT,
- /* layer shell */
- "layer-shell", layer_shell,
- "wl-output", wl_output,
- "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
- "layer", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
- "kbd-interactivity", TRUE,
- "exclusive-zone", -1,
- "namespace", "phosh prompter",
- NULL);
+ self = g_object_new (PHOSH_TYPE_NETWORK_AUTH_PROMPT, NULL);
self->nm_client = g_object_ref (nm_client);
self->agent = g_object_ref (agent);
diff -Nru phosh-0.8.0/src/network-auth-prompt.h phosh-0.13.1/src/network-auth-prompt.h
--- phosh-0.8.0/src/network-auth-prompt.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/network-auth-prompt.h 2021-08-31 09:15:52.000000000 +0000
@@ -7,18 +7,16 @@
#include
#include
-#include "layersurface.h"
+#include "system-modal-dialog.h"
G_BEGIN_DECLS
#define PHOSH_TYPE_NETWORK_AUTH_PROMPT (phosh_network_auth_prompt_get_type())
-G_DECLARE_FINAL_TYPE (PhoshNetworkAuthPrompt, phosh_network_auth_prompt, PHOSH, NETWORK_AUTH_PROMPT, PhoshLayerSurface);
+G_DECLARE_FINAL_TYPE (PhoshNetworkAuthPrompt, phosh_network_auth_prompt, PHOSH, NETWORK_AUTH_PROMPT, PhoshSystemModalDialog);
GtkWidget *phosh_network_auth_prompt_new (ShellNetworkAgent *agent,
- NMClient *nm_client,
- gpointer layer_shell,
- gpointer wl_output);
+ NMClient *nm_client);
void phosh_network_auth_prompt_set_request (PhoshNetworkAuthPrompt *self,
char *request_id,
NMConnection *connection,
diff -Nru phosh-0.8.0/src/notifications/meson.build phosh-0.13.1/src/notifications/meson.build
--- phosh-0.8.0/src/notifications/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -17,6 +17,8 @@
'notifications/notification-source.h',
'notifications/notify-manager.c',
'notifications/notify-manager.h',
+ 'notifications/notify-feedback.c',
+ 'notifications/notify-feedback.h',
'notifications/timestamp-label.c',
'notifications/timestamp-label.h',
]
diff -Nru phosh-0.8.0/src/notifications/mount-notification.c phosh-0.13.1/src/notifications/mount-notification.c
--- phosh-0.8.0/src/notifications/mount-notification.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/mount-notification.c 2021-08-31 09:15:52.000000000 +0000
@@ -35,7 +35,6 @@
G_DEFINE_TYPE (PhoshMountNotification, phosh_mount_notification, PHOSH_TYPE_NOTIFICATION)
-#if GLIB_CHECK_VERSION(2,60,0)
static void
on_launch_finished (GAppInfo *source,
GAsyncResult *result,
@@ -51,7 +50,7 @@
g_object_unref (self);
}
-#endif
+
static void
phosh_mount_notification_do_action (PhoshNotification *notification, guint id, const char *action)
@@ -70,7 +69,6 @@
l = g_list_append (l, (gpointer)action);
context = phosh_shell_get_app_launch_context (phosh_shell_get_default ());
-#if GLIB_CHECK_VERSION(2,60,0)
self->cancellable = g_cancellable_new ();
g_app_info_launch_uris_async (info,
l,
@@ -78,19 +76,6 @@
self->cancellable,
(GAsyncReadyCallback)on_launch_finished,
g_object_ref (self));
-#else
- {
- g_autoptr (GError) err = NULL;
- if (!g_app_info_launch_uris (info,
- l,
- G_APP_LAUNCH_CONTEXT (context),
- &err)) {
- g_warning ("Failed to open %s: %s",
- phosh_notification_get_summary (PHOSH_NOTIFICATION (self)),
- err->message);
- }
- }
-#endif
}
diff -Nru phosh-0.8.0/src/notifications/notification-banner.c phosh-0.13.1/src/notifications/notification-banner.c
--- phosh-0.8.0/src/notifications/notification-banner.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-banner.c 2021-08-31 09:15:52.000000000 +0000
@@ -14,7 +14,6 @@
#include "shell.h"
#include "util.h"
-#define HANDY_USE_UNSTABLE_API
#include
/**
@@ -52,8 +51,8 @@
static void
clear_handler (PhoshNotificationBanner *self)
{
- phosh_clear_handler (&self->handler_expired, self->notification);
- phosh_clear_handler (&self->handler_closed, self->notification);
+ g_clear_signal_handler (&self->handler_expired, self->notification);
+ g_clear_signal_handler (&self->handler_closed, self->notification);
}
@@ -94,7 +93,7 @@
g_set_object (&self->notification, notification);
- content = phosh_notification_frame_new ();
+ content = phosh_notification_frame_new (TRUE);
phosh_notification_frame_bind_notification (PHOSH_NOTIFICATION_FRAME (content),
self->notification);
gtk_container_add (GTK_CONTAINER (self), content);
@@ -265,7 +264,9 @@
phosh_notification_banner_new (PhoshNotification *notification)
{
PhoshWayland *wl = phosh_wayland_get_default ();
+ PhoshMonitor *monitor = phosh_shell_get_primary_monitor (phosh_shell_get_default ());
int width = 360;
+
phosh_shell_get_usable_area (phosh_shell_get_default (),
NULL, NULL, &width, NULL);
@@ -274,6 +275,7 @@
/* layer surface */
"margin-top", -300,
"layer-shell", phosh_wayland_get_zwlr_layer_shell_v1 (wl),
+ "wl-output", monitor ? monitor->wl_output : NULL,
"anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP,
"height", 50,
"width", MIN (width, 450),
diff -Nru phosh-0.8.0/src/notifications/notification.c phosh-0.13.1/src/notifications/notification.c
--- phosh-0.8.0/src/notifications/notification.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification.c 2021-08-31 09:15:52.000000000 +0000
@@ -19,6 +19,8 @@
* SECTION:notification
* @short_description: A notification
* @Title: PhoshNotification
+ *
+ * A #PhoshNotification with summary, body, icon, actions, etc.
*/
enum {
diff -Nru phosh-0.8.0/src/notifications/notification-content.c phosh-0.13.1/src/notifications/notification-content.c
--- phosh-0.8.0/src/notifications/notification-content.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-content.c 2021-08-31 09:15:52.000000000 +0000
@@ -21,6 +21,7 @@
enum {
PROP_0,
PROP_NOTIFICATION,
+ PROP_SHOW_BODY,
LAST_PROP
};
static GParamSpec *props[LAST_PROP];
@@ -35,6 +36,8 @@
GtkWidget *lbl_body;
GtkWidget *img_image;
GtkWidget *box_actions;
+
+ gboolean show_body;
};
typedef struct _PhoshNotificationContent PhoshNotificationContent;
@@ -90,7 +93,7 @@
const char* body = g_value_get_string (from_value);
gboolean visible;
- visible = body != NULL && g_strcmp0 (body, "");
+ visible = body != NULL && g_strcmp0 (body, "") && self->show_body;
gtk_widget_set_visible (self->lbl_body, visible);
g_value_set_string (to_value, body);
@@ -180,8 +183,8 @@
self,
NULL);
- g_signal_connect (self->notification, "notify::actions",
- G_CALLBACK (set_actions), self);
+ g_signal_connect_object (self->notification, "notify::actions",
+ G_CALLBACK (set_actions), self, 0);
set_actions (self->notification, NULL, self);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_NOTIFICATION]);
@@ -201,6 +204,10 @@
phosh_notification_content_set_notification (self,
g_value_get_object (value));
break;
+ case PROP_SHOW_BODY:
+ self->show_body = g_value_get_boolean (value);
+ break;
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -220,6 +227,9 @@
case PROP_NOTIFICATION:
g_value_set_object (value, self->notification);
break;
+ case PROP_SHOW_BODY:
+ g_value_set_boolean (value, self->show_body);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -262,6 +272,19 @@
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * PhoshNotificationContent:show-body:
+ *
+ * Whether the body of the notification is shown
+ */
+ props[PROP_SHOW_BODY] =
+ g_param_spec_boolean ("show-body",
+ "",
+ "",
+ TRUE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, LAST_PROP, props);
gtk_widget_class_set_template_from_resource (widget_class,
@@ -302,6 +325,8 @@
{
g_autoptr (GActionMap) map = NULL;
+ self->show_body = TRUE;
+
map = G_ACTION_MAP (g_simple_action_group_new ());
g_action_map_add_action_entries (map,
entries,
@@ -312,14 +337,28 @@
G_ACTION_GROUP (map));
gtk_widget_init_template (GTK_WIDGET (self));
+
+
+ g_object_bind_property (self,
+ "show-body",
+ self->lbl_body,
+ "visible",
+ G_BINDING_DEFAULT);
+
+ g_object_bind_property (self,
+ "show-body",
+ self->box_actions,
+ "visible",
+ G_BINDING_DEFAULT);
}
GtkWidget *
-phosh_notification_content_new (PhoshNotification *notification)
+phosh_notification_content_new (PhoshNotification *notification, gboolean show_body)
{
return g_object_new (PHOSH_TYPE_NOTIFICATION_CONTENT,
"notification", notification,
+ "show-body", show_body,
NULL);
}
diff -Nru phosh-0.8.0/src/notifications/notification-content.h phosh-0.13.1/src/notifications/notification-content.h
--- phosh-0.8.0/src/notifications/notification-content.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-content.h 2021-08-31 09:15:52.000000000 +0000
@@ -21,7 +21,8 @@
G_DECLARE_FINAL_TYPE (PhoshNotificationContent, phosh_notification_content, PHOSH, NOTIFICATION_CONTENT, GtkListBoxRow)
-GtkWidget *phosh_notification_content_new (PhoshNotification *notification);
+GtkWidget *phosh_notification_content_new (PhoshNotification *notification,
+ gboolean show_body);
PhoshNotification *phosh_notification_content_get_notification (PhoshNotificationContent *self);
diff -Nru phosh-0.8.0/src/notifications/notification-frame.c phosh-0.13.1/src/notifications/notification-frame.c
--- phosh-0.8.0/src/notifications/notification-frame.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-frame.c 2021-08-31 09:15:52.000000000 +0000
@@ -22,6 +22,14 @@
*/
+enum {
+ PROP_0,
+ PROP_SHOW_BODY,
+ LAST_PROP
+};
+static GParamSpec *props[LAST_PROP];
+
+
struct _PhoshNotificationFrame {
GtkBox parent;
@@ -36,6 +44,8 @@
GtkWidget *img_icon;
GtkWidget *list_notifs;
GtkWidget *updated;
+
+ gboolean show_body;
};
typedef struct _PhoshNotificationFrame PhoshNotificationFrame;
@@ -51,13 +61,51 @@
static void
+phosh_notification_frame_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshNotificationFrame *self = PHOSH_NOTIFICATION_FRAME (object);
+
+ switch (property_id) {
+ case PROP_SHOW_BODY:
+ self->show_body = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_notification_frame_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshNotificationFrame *self = PHOSH_NOTIFICATION_FRAME (object);
+
+ switch (property_id) {
+ case PROP_SHOW_BODY:
+ g_value_set_boolean (value, self->show_body);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
phosh_notification_frame_finalize (GObject *object)
{
PhoshNotificationFrame *self = PHOSH_NOTIFICATION_FRAME (object);
/* Don't clear bindings, they're already unref'd before here */
- phosh_clear_handler (&self->model_watch, self->model);
+ g_clear_signal_handler (&self->model_watch, self->model);
g_clear_object (&self->model);
@@ -109,6 +157,23 @@
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = phosh_notification_frame_finalize;
+ object_class->set_property = phosh_notification_frame_set_property;
+ object_class->get_property = phosh_notification_frame_get_property;
+
+ /**
+ * PhoshNotificationFrame:show-body:
+ *
+ * Whether notificaions in this frame should show the notification body
+ */
+ props[PROP_SHOW_BODY] =
+ g_param_spec_boolean ("show-body",
+ "",
+ "",
+ TRUE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, props);
signals[SIGNAL_EMPTY] = g_signal_new ("empty",
G_TYPE_FROM_CLASS (klass),
@@ -138,14 +203,15 @@
static void
phosh_notification_frame_init (PhoshNotificationFrame *self)
{
+ self->show_body = TRUE;
gtk_widget_init_template (GTK_WIDGET (self));
}
GtkWidget *
-phosh_notification_frame_new (void)
+phosh_notification_frame_new (gboolean show_body)
{
- return g_object_new (PHOSH_TYPE_NOTIFICATION_FRAME, NULL);
+ return g_object_new (PHOSH_TYPE_NOTIFICATION_FRAME, "show-body", show_body, NULL);
}
@@ -153,8 +219,11 @@
create_row (gpointer item, gpointer data)
{
PhoshNotification *notification = item;
+ PhoshNotificationFrame *self = PHOSH_NOTIFICATION_FRAME (data);
+
+ g_return_val_if_fail (PHOSH_IS_NOTIFICATION_FRAME (self), NULL);
- return phosh_notification_content_new (notification);
+ return phosh_notification_content_new (notification, self->show_body);
}
diff -Nru phosh-0.8.0/src/notifications/notification-frame.h phosh-0.13.1/src/notifications/notification-frame.h
--- phosh-0.8.0/src/notifications/notification-frame.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-frame.h 2021-08-31 09:15:52.000000000 +0000
@@ -21,7 +21,7 @@
G_DECLARE_FINAL_TYPE (PhoshNotificationFrame, phosh_notification_frame, PHOSH, NOTIFICATION_FRAME, GtkBox)
-GtkWidget *phosh_notification_frame_new (void);
+GtkWidget *phosh_notification_frame_new (gboolean show_body);
void phosh_notification_frame_bind_notification (PhoshNotificationFrame *self,
PhoshNotification *notification);
void phosh_notification_frame_bind_model (PhoshNotificationFrame *self,
diff -Nru phosh-0.8.0/src/notifications/notification-list.c phosh-0.13.1/src/notifications/notification-list.c
--- phosh-0.8.0/src/notifications/notification-list.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-list.c 2021-08-31 09:15:52.000000000 +0000
@@ -16,6 +16,9 @@
* SECTION:notification-list
* @short_description: A list containing one or more #PhoshNotificationSource
* @Title: PhoshNotificationList
+ *
+ * #PhoshNotificationList maps between #PhoshNotificationSource objects and their
+ * notifications creating and removing sources on the fly.
*/
diff -Nru phosh-0.8.0/src/notifications/notification-source.c phosh-0.13.1/src/notifications/notification-source.c
--- phosh-0.8.0/src/notifications/notification-source.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notification-source.c 2021-08-31 09:15:52.000000000 +0000
@@ -15,6 +15,9 @@
* SECTION:notification-source
* @short_description: A #GListModel containing one or more notifications
* @Title: PhoshNotificationSource
+ *
+ * A #PhoshNotificationSource groups notifications. A source has a name
+ * which is usually the app_id of the sending application.
*/
diff -Nru phosh-0.8.0/src/notifications/notify-feedback.c phosh-0.13.1/src/notifications/notify-feedback.c
--- phosh-0.8.0/src/notifications/notify-feedback.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/notifications/notify-feedback.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-notify-feedback"
+
+#include "config.h"
+
+#include "shell.h"
+#include "notify-feedback.h"
+#include "notification-source.h"
+
+#define LIBFEEDBACK_USE_UNSTABLE_API
+#include
+
+/**
+ * SECTION:notify-feedback
+ * @short_description: Provider feedback on notifications
+ * @Title: PhoshNotifyFeedback
+ *
+ * #PhoshNotifyFeedback is responsible to provider proper feedback
+ * on new notifications or when notifcations are being closed.
+ */
+
+enum {
+ PROP_0,
+ PROP_NOTIFICATION_LIST,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+struct _PhoshNotifyFeedback {
+ GObject parent;
+
+ LfbEvent *event;
+ PhoshNotificationList *list;
+};
+G_DEFINE_TYPE (PhoshNotifyFeedback, phosh_notify_feedback, G_TYPE_OBJECT)
+
+static void
+end_notify_feedback (PhoshNotifyFeedback *self)
+{
+ if (self->event == NULL)
+ return;
+
+ if (lfb_event_get_state (self->event) == LFB_EVENT_STATE_RUNNING)
+ lfb_event_end_feedback_async (self->event, NULL, NULL, NULL);
+}
+
+
+static const char *
+find_event (const char *category)
+{
+ gboolean locked = phosh_shell_get_locked (phosh_shell_get_default ());
+ /* If shell is unlocked and we don't have a specific category don't
+ trigger any event to not distract the user*/
+ const char *ret = NULL;
+
+ if (locked) {
+ if (g_strcmp0 (category, "email.arrived") == 0)
+ ret = "message-missed-email";
+ else if (g_strcmp0 (category, "im.received") == 0)
+ ret = "message-missed-instant";
+ else if (g_strcmp0 (category, "x-gnome.call.unanswered") == 0)
+ ret = "phone-missed-call";
+ else
+ ret = "message-missed-notification";
+ } else {
+ if (g_strcmp0 (category, "email.arrived") == 0)
+ ret = "message-new-email";
+ else if (g_strcmp0 (category, "im.received") == 0)
+ ret = "message-new-instant";
+ else if (g_strcmp0 (category, "x-gnome.call.unanswered") == 0)
+ ret = "phone-missed-call";
+ /* no additional feedback when not locked */
+ }
+
+ return ret;
+}
+
+
+static void
+on_notifcation_source_items_changed (PhoshNotifyFeedback *self,
+ guint position,
+ guint removed,
+ guint added,
+ GListModel *list)
+{
+ if (!added)
+ return;
+
+ /* TODO: add pending events to queue instead of just skipping them. */
+ if (self->event && lfb_event_get_state (self->event) == LFB_EVENT_STATE_RUNNING)
+ return;
+
+ for (int i = 0; i < added; i++) {
+ g_autoptr (PhoshNotification) new = g_list_model_get_item (list, position);
+ g_autoptr (LfbEvent) event = NULL;
+ const char *category, *event_name;
+
+ g_return_if_fail (PHOSH_IS_NOTIFICATION (new));
+
+ category = phosh_notification_get_category (new);
+ event_name = find_event (category);
+ if (event_name == NULL)
+ continue;
+
+ g_debug ("Emitting event %s", event_name);
+ event = lfb_event_new (event_name);
+ g_set_object (&self->event, event);
+ lfb_event_trigger_feedback_async (self->event, NULL, NULL, NULL);
+ /* TODO: add additional events to queue instead of just skipping them */
+ break;
+ }
+}
+
+
+static void
+on_notifcation_list_items_changed (PhoshNotifyFeedback *self,
+ guint position,
+ guint removed,
+ guint added,
+ GListModel *list)
+{
+ g_autoptr (PhoshNotificationSource) first = g_list_model_get_item (list, 0);
+
+ if (!first) {
+ g_debug ("Notification list empty, ending feedback");
+ end_notify_feedback (self);
+ }
+
+ /* No need to worry about removed sources, signals get detached due
+ * to g_signal_connect_object () */
+ for (int i = position; i < position + added; i++) {
+ g_autoptr (PhoshNotificationSource) source = g_list_model_get_item (list, position);
+ /* Listen to new notification on the store for feedback triggering */
+ g_signal_connect_object (source,
+ "items-changed",
+ G_CALLBACK (on_notifcation_source_items_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ on_notifcation_source_items_changed (self, 0, 0,
+ g_list_model_get_n_items (G_LIST_MODEL (source)),
+ G_LIST_MODEL (source));
+ }
+}
+
+
+static void
+phosh_notify_feedback_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshNotifyFeedback *self = PHOSH_NOTIFY_FEEDBACK (object);
+
+ switch (property_id) {
+ case PROP_NOTIFICATION_LIST:
+ self->list = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_notify_feedback_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshNotifyFeedback *self = PHOSH_NOTIFY_FEEDBACK (object);
+
+ switch (property_id) {
+ case PROP_NOTIFICATION_LIST:
+ g_value_set_object (value, self->list);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_notify_feedback_constructed (GObject *object)
+{
+ PhoshNotifyFeedback *self = PHOSH_NOTIFY_FEEDBACK (object);
+
+ G_OBJECT_CLASS (phosh_notify_feedback_parent_class)->constructed (object);
+
+ g_signal_connect_swapped (self->list,
+ "items-changed",
+ G_CALLBACK (on_notifcation_list_items_changed),
+ self);
+}
+
+
+static void
+phosh_notify_feedback_dispose (GObject *object)
+{
+ PhoshNotifyFeedback *self = PHOSH_NOTIFY_FEEDBACK (object);
+
+ if (self->event) {
+ end_notify_feedback (self);
+ g_clear_object (&self->event);
+ }
+
+ g_signal_handlers_disconnect_by_data (self->list, self);
+ g_clear_object (&self->list);
+
+ G_OBJECT_CLASS (phosh_notify_feedback_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_notify_feedback_class_init (PhoshNotifyFeedbackClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = phosh_notify_feedback_get_property;
+ object_class->set_property = phosh_notify_feedback_set_property;
+ object_class->constructed = phosh_notify_feedback_constructed;
+ object_class->dispose = phosh_notify_feedback_dispose;
+
+ /**
+ * PhoshNotifyFeedback:notification-list
+ *
+ * The list of notifications that drives the feedback emission
+ */
+ props[PROP_NOTIFICATION_LIST] =
+ g_param_spec_object ("notification-list",
+ "",
+ "",
+ PHOSH_TYPE_NOTIFICATION_LIST,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+}
+
+
+static void
+phosh_notify_feedback_init (PhoshNotifyFeedback *self)
+{
+}
+
+
+PhoshNotifyFeedback *
+phosh_notify_feedback_new (PhoshNotificationList *list)
+{
+ return PHOSH_NOTIFY_FEEDBACK (g_object_new (PHOSH_TYPE_NOTIFY_FEEDBACK,
+ "notification-list", list,
+ NULL));
+}
diff -Nru phosh-0.8.0/src/notifications/notify-feedback.h phosh-0.13.1/src/notifications/notify-feedback.h
--- phosh-0.8.0/src/notifications/notify-feedback.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/notifications/notify-feedback.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "notification-list.h"
+
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_NOTIFY_FEEDBACK (phosh_notify_feedback_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshNotifyFeedback, phosh_notify_feedback, PHOSH, NOTIFY_FEEDBACK, GObject)
+
+PhoshNotifyFeedback *phosh_notify_feedback_new (PhoshNotificationList *list);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/notifications/notify-manager.c phosh-0.13.1/src/notifications/notify-manager.c
--- phosh-0.8.0/src/notifications/notify-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notify-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -16,6 +16,7 @@
#include "notification-banner.h"
#include "notification-list.h"
#include "notify-manager.h"
+#include "notify-feedback.h"
#include "shell.h"
#include "phosh-enums.h"
#include "util.h"
@@ -40,6 +41,8 @@
* #PhoshNotifyManager manages notifications sent from the shell
* iself and via the org.freedesktop.Notification DBus interface.
* See https://developer.gnome.org/notification-spec/
+ *
+ * It maintains a list of notifications via a #PhoshNotificationList.
*/
#define NOTIFY_DBUS_NAME "org.freedesktop.Notifications"
@@ -59,7 +62,14 @@
GSettings *settings;
+ /* Notification to be handled on unlock */
+ struct {
+ PhoshNotification *notification;
+ char *action;
+ } unlock_notify;
+
PhoshNotificationList *list;
+ PhoshNotifyFeedback *feedback;
} PhoshNotifyManager;
G_DEFINE_TYPE_WITH_CODE (PhoshNotifyManager,
@@ -158,19 +168,39 @@
static void
-on_notification_actioned (PhoshNotifyManager *self,
- const char *action,
- PhoshNotification *notification)
+on_unlock_notify_ref_gone (gpointer data, GObject *gone)
{
- guint id;
+ PhoshNotifyManager *self = PHOSH_NOTIFY_MANAGER (data);
g_return_if_fail (PHOSH_IS_NOTIFY_MANAGER (self));
- g_return_if_fail (PHOSH_IS_NOTIFICATION (notification));
+
+ self->unlock_notify.notification = NULL;
+ g_clear_pointer (&self->unlock_notify.action, g_free);
+}
+
+
+static void
+forget_unlock_notify (PhoshNotifyManager *self)
+{
+ if (!self->unlock_notify.notification)
+ return;
+
+ g_object_weak_unref (G_OBJECT (self->unlock_notify.notification),
+ on_unlock_notify_ref_gone,
+ self);
+ self->unlock_notify.notification = NULL;
+ g_clear_pointer (&self->unlock_notify.action, g_free);
+}
+
+
+static void
+invoke_action (PhoshNotification *notification, const gchar *action)
+{
+ guint id;
id = phosh_notification_get_id (notification);
g_return_if_fail (id);
-
g_debug ("Emitting ActionInvoked: %d, %s", id, action);
phosh_notification_do_action (notification, id, action);
@@ -183,6 +213,55 @@
}
+
+static void
+on_shell_lock_changed (PhoshNotifyManager* self, GParamSpec *pspec, PhoshShell *shell)
+{
+ gboolean locked;
+
+ g_return_if_fail (PHOSH_IS_NOTIFY_MANAGER (self));
+
+ locked = phosh_shell_get_locked (shell);
+ if (!locked && self->unlock_notify.notification) {
+ invoke_action (self->unlock_notify.notification, self->unlock_notify.action);
+ forget_unlock_notify (self);
+ }
+}
+
+
+static void
+on_notification_actioned (PhoshNotifyManager *self,
+ const char *action,
+ PhoshNotification *notification)
+{
+ PhoshShell *shell = phosh_shell_get_default();
+
+ g_return_if_fail (PHOSH_IS_NOTIFY_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_NOTIFICATION (notification));
+
+ /* Postpone action when shell is locked */
+ if (phosh_shell_get_locked (shell)) {
+ PhoshLockscreenManager *lm;
+
+ /* Forget any pending actions */
+ forget_unlock_notify (self);
+
+ /* Clear out notification if it goes away in the meantime */
+ g_object_weak_ref (G_OBJECT (notification),
+ on_unlock_notify_ref_gone,
+ self);
+ self->unlock_notify.notification = notification;
+ self->unlock_notify.action = g_strdup (action);
+
+ /* Scroll to unlock page */
+ lm = phosh_shell_get_lockscreen_manager (shell);
+ phosh_lockscreen_manager_set_page (lm, PHOSH_LOCKSCREEN_PAGE_UNLOCK);
+ } else {
+ invoke_action (notification, action);
+ }
+}
+
+
static void
on_notification_closed (PhoshNotifyManager *self,
PhoshNotificationReason reason,
@@ -548,8 +627,13 @@
{
PhoshNotifyManager *self = PHOSH_NOTIFY_MANAGER (object);
- g_clear_object (&self->settings);
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_object (&self->settings);
+ g_clear_object (&self->feedback);
g_clear_object (&self->list);
G_OBJECT_CLASS (phosh_notify_manager_parent_class)->dispose (object);
@@ -572,6 +656,7 @@
phosh_notify_manager_constructed (GObject *object)
{
PhoshNotifyManager *self = PHOSH_NOTIFY_MANAGER (object);
+ PhoshShell *shell = phosh_shell_get_default();
G_OBJECT_CLASS (phosh_notify_manager_parent_class)->constructed (object);
self->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
@@ -581,8 +666,8 @@
on_bus_acquired,
on_name_acquired,
on_name_lost,
- g_object_ref (self),
- g_object_unref);
+ self,
+ NULL);
self->settings = g_settings_new (NOTIFICATIONS_SCHEMA_ID);
g_signal_connect_swapped (self->settings, "changed::" NOTIFICATIONS_KEY_SHOW_BANNERS,
@@ -592,6 +677,10 @@
g_signal_connect_swapped (self->settings, "changed::" NOTIFICATIONS_KEY_APP_CHILDREN,
G_CALLBACK (on_notification_apps_setting_changed), self);
on_notification_apps_setting_changed (self, NULL, self->settings);
+
+ g_signal_connect_swapped (shell, "notify::locked", G_CALLBACK (on_shell_lock_changed), self);
+
+ self->feedback = phosh_notify_feedback_new (self->list);
}
@@ -705,8 +794,7 @@
* @expire_timeout: When the notification should expire
* @notification: The notification
*
- * Returns: Adds a notification
- * notifications.
+ * Adds @notification to the current list of notifications.
*/
void
phosh_notify_manager_add_notification (PhoshNotifyManager *self,
@@ -803,3 +891,28 @@
g_debug ("Show banners for %s: %d", munged_id, show);
return show;
}
+
+/**
+ * phosh_notify_manager_close_all:
+ * @self: the #PhoshNotifyManager
+ * @rease: the #PhoshNotificationReason
+ *
+ * Closes all notifications using #PhoshNotificationReason as reason.
+ */
+void
+phosh_notify_manager_close_all_notifications (PhoshNotifyManager *self,
+ PhoshNotificationReason reason)
+{
+ GListModel *source_list;
+
+ source_list = G_LIST_MODEL (phosh_notify_manager_get_list (self));
+
+ for (int i = g_list_model_get_n_items(G_LIST_MODEL (source_list)); i > 0; i--) {
+ g_autoptr (GListModel) notif_list = G_LIST_MODEL (g_list_model_get_object (source_list, i-1));
+
+ for (int j = g_list_model_get_n_items(G_LIST_MODEL (notif_list)); j > 0; j--) {
+ g_autoptr (PhoshNotification) notification = PHOSH_NOTIFICATION (g_list_model_get_object (notif_list, j-1));
+ phosh_notification_close (notification, PHOSH_NOTIFICATION_REASON_DISMISSED);
+ }
+ }
+}
diff -Nru phosh-0.8.0/src/notifications/notify-manager.h phosh-0.13.1/src/notifications/notify-manager.h
--- phosh-0.8.0/src/notifications/notify-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/notifications/notify-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -27,11 +27,11 @@
const gchar *source_id,
int expire_timeout,
PhoshNotification *notification);
-gboolean phosh_notify_manager_close_notification_by_id (PhoshNotifyManager *self,
- int id,
- PhoshNotificationReason reason);
-gboolean
- phosh_notify_manager_get_show_notification_banner (
- PhoshNotifyManager *self,
+gboolean phosh_notify_manager_close_notification_by_id (PhoshNotifyManager *self,
+ int id,
+ PhoshNotificationReason reason);
+void phosh_notify_manager_close_all_notifications (PhoshNotifyManager *self,
+ PhoshNotificationReason reaseon);
+gboolean phosh_notify_manager_get_show_notification_banner (PhoshNotifyManager *self,
PhoshNotification *notification);
G_END_DECLS
diff -Nru phosh-0.8.0/src/osd-window.c phosh-0.13.1/src/osd-window.c
--- phosh-0.8.0/src/osd-window.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/osd-window.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-osd-window"
+
+#include "config.h"
+
+#include "osd-window.h"
+
+/**
+ * SECTION:osd-window
+ * @short_description: A OSD Window
+ * @Title: PhoshOsdWindow
+ *
+ * The #PhoshOsdWindow displays contents fed via the
+ * OSD (on screen display) DBus interface.
+ */
+
+enum {
+ PROP_0,
+ PROP_CONNECTOR,
+ PROP_LABEL,
+ PROP_ICON_NAME,
+ PROP_LEVEL,
+ PROP_MAX_LEVEL,
+ PROP_LAST_PROP,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+typedef struct _PhoshOsdWindow {
+ PhoshSystemModal parent;
+
+ char *connector;
+ char *label;
+ char *icon_name;
+ gdouble level;
+ gdouble max_level;
+
+ GtkWidget *lbl;
+ GtkWidget *icon;
+ GtkWidget *bar;
+ GtkGesture *click_gesture;
+} PhoshOsdWindow;
+
+
+G_DEFINE_TYPE (PhoshOsdWindow, phosh_osd_window, PHOSH_TYPE_SYSTEM_MODAL)
+
+static void
+phosh_osd_window_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshOsdWindow *self = PHOSH_OSD_WINDOW (obj);
+
+ switch (prop_id) {
+ case PROP_CONNECTOR:
+ g_free (self->connector);
+ self->connector = g_value_dup_string (value);
+ break;
+ case PROP_LABEL:
+ g_free (self->label);
+ self->label = g_value_dup_string (value);
+ gtk_label_set_label (GTK_LABEL (self->lbl), self->label);
+ break;
+ case PROP_ICON_NAME:
+ g_free (self->icon_name);
+ self->icon_name = g_value_dup_string (value);
+ gtk_image_set_from_icon_name (GTK_IMAGE (self->icon), self->icon_name, GTK_ICON_SIZE_INVALID);
+ break;
+ case PROP_LEVEL:
+ self->level = g_value_get_double (value);
+ gtk_level_bar_set_value (GTK_LEVEL_BAR (self->bar), self->level);
+ break;
+ case PROP_MAX_LEVEL:
+ self->max_level = g_value_get_double (value);
+ gtk_level_bar_set_max_value (GTK_LEVEL_BAR (self->bar), self->max_level);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_osd_window_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshOsdWindow *self = PHOSH_OSD_WINDOW (obj);
+
+ switch (prop_id) {
+ case PROP_CONNECTOR:
+ g_value_set_string (value, self->connector ? self->connector : "");
+ break;
+ case PROP_LABEL:
+ g_value_set_string (value, self->label ? self->label : "");
+ break;
+ case PROP_ICON_NAME:
+ g_value_set_string (value, self->icon_name ? self->icon_name : "");
+ break;
+ case PROP_LEVEL:
+ g_value_set_double (value, self->level);
+ break;
+ case PROP_MAX_LEVEL:
+ g_value_set_double (value, self->max_level);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+on_button_released (PhoshOsdWindow *self)
+{
+ gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+
+static void
+phosh_osd_window_finalize (GObject *obj)
+{
+ PhoshOsdWindow *self = PHOSH_OSD_WINDOW (obj);
+
+ g_free (self->connector);
+ g_free (self->label);
+ g_free (self->icon_name);
+
+ G_OBJECT_CLASS (phosh_osd_window_parent_class)->finalize (obj);
+}
+
+
+static void
+phosh_osd_window_class_init (PhoshOsdWindowClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *)klass;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = phosh_osd_window_get_property;
+ object_class->set_property = phosh_osd_window_set_property;
+ object_class->finalize = phosh_osd_window_finalize;
+
+ /* TODO: currently unused */
+ props[PROP_CONNECTOR] =
+ g_param_spec_string ("connector",
+ "Connector",
+ "Connector to use for osd display",
+ NULL,
+ G_PARAM_READWRITE);
+
+ props[PROP_LABEL] =
+ g_param_spec_string ("label",
+ "Label",
+ "Label to show on osd",
+ NULL,
+ G_PARAM_READWRITE);
+
+ props[PROP_ICON_NAME] =
+ g_param_spec_string ("icon-name",
+ "Icon Name",
+ "Name of icon to use on osd",
+ NULL,
+ G_PARAM_READWRITE);
+
+ props[PROP_LEVEL] =
+ g_param_spec_double ("level",
+ "Level",
+ "Level of bar to display on osd",
+ 0.0,
+ G_MAXDOUBLE,
+ 0.0,
+ G_PARAM_READWRITE);
+
+ props[PROP_MAX_LEVEL] =
+ g_param_spec_double ("max-level",
+ "Maximum Level",
+ "Maximum level of bar to display on osd",
+ 0.0,
+ G_MAXDOUBLE,
+ 0.0,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/sm/puri/phosh/ui/osd-window.ui");
+ gtk_widget_class_bind_template_child (widget_class, PhoshOsdWindow, lbl);
+ gtk_widget_class_bind_template_child (widget_class, PhoshOsdWindow, icon);
+ gtk_widget_class_bind_template_child (widget_class, PhoshOsdWindow, bar);
+ gtk_widget_class_bind_template_child (widget_class, PhoshOsdWindow, click_gesture);
+ gtk_widget_class_bind_template_callback (widget_class, on_button_released);
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-osd-window");
+}
+
+
+static void
+phosh_osd_window_init (PhoshOsdWindow *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ gtk_widget_add_events (GTK_WIDGET (self), GDK_BUTTON_RELEASE_MASK);
+}
+
+
+GtkWidget *
+phosh_osd_window_new (char *connector,
+ char *label,
+ char *icon_name,
+ double level,
+ double max_level)
+{
+ return g_object_new (PHOSH_TYPE_OSD_WINDOW,
+ "connector", connector,
+ "label",label,
+ "icon-name", icon_name,
+ "level", level,
+ "max-level", max_level,
+ NULL);
+}
diff -Nru phosh-0.8.0/src/osd-window.h phosh-0.13.1/src/osd-window.h
--- phosh-0.8.0/src/osd-window.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/osd-window.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "system-modal.h"
+
+#define PHOSH_TYPE_OSD_WINDOW (phosh_osd_window_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshOsdWindow, phosh_osd_window, PHOSH, OSD_WINDOW, PhoshSystemModal)
+
+GtkWidget *phosh_osd_window_new (char *connector,
+ char *label,
+ char *icon_name,
+ double level,
+ double max_level);
diff -Nru phosh-0.8.0/src/osk/meson.build phosh-0.13.1/src/osk/meson.build
--- phosh-0.8.0/src/osk/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/osk/meson.build 1970-01-01 00:00:00.000000000 +0000
@@ -1,10 +0,0 @@
-iface = 'phosh-osk0-dbus'
-generated_osk_sources = gnome.gdbus_codegen(iface,
- iface + '.xml',
- namespace: 'PhoshOsk0',
- object_manager: true)
-
-phosh_osk_sources = [
- 'osk/osk-button.c',
- generated_osk_sources,
-]
diff -Nru phosh-0.8.0/src/osk/osk-button.c phosh-0.13.1/src/osk/osk-button.c
--- phosh-0.8.0/src/osk/osk-button.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/osk/osk-button.c 1970-01-01 00:00:00.000000000 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2018 Purism SPC
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- * Author: Guido Günther
- */
-
-#define G_LOG_DOMAIN "phosh-osk-button"
-
-#include "osk-button.h"
-#include "osk-manager.h"
-#include "shell.h"
-
-#include
-#include
-
-/**
- * SECTION:osk-button
- * @short_description: A button that toggles the OSK
- * @Title: PhoshOsk
- *
- * The #PhoshOskButton is responsible for toggling the on screen keyboard
- */
-struct _PhoshOskButton
-{
- GtkToggleButton parent;
-
- PhoshOskManager *osk;
- gboolean setting_visibility;
-};
-
-G_DEFINE_TYPE (PhoshOskButton, phosh_osk_button, GTK_TYPE_TOGGLE_BUTTON)
-
-
-static void
-toggled_cb (PhoshOskButton *self, gpointer data)
-{
- gboolean visible, active;
-
- self->setting_visibility = TRUE;
- visible = phosh_osk_manager_get_visible (self->osk);
-
- active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self));
- if (visible != active)
- phosh_osk_manager_set_visible (self->osk, active);
-
- self->setting_visibility = FALSE;
-}
-
-
-static void
-on_osk_availability_changed (PhoshOskButton *self, GParamSpec *pspec, PhoshOskManager *osk)
-{
- gboolean available;
-
- g_return_if_fail (PHOSH_IS_OSK_BUTTON (self));
- g_return_if_fail (PHOSH_IS_OSK_MANAGER (osk));
- g_return_if_fail (self->osk == osk);
-
- available = phosh_osk_manager_get_available (osk);
- gtk_widget_set_sensitive (GTK_WIDGET (self), available);
-}
-
-
-static void
-on_osk_visibility_changed (PhoshOskButton *self, GParamSpec *pspec, PhoshOskManager *osk)
-{
- gboolean visible;
-
- g_return_if_fail (PHOSH_IS_OSK_BUTTON (self));
- g_return_if_fail (PHOSH_IS_OSK_MANAGER (osk));
- g_return_if_fail (self->osk == osk);
-
- visible = phosh_osk_manager_get_visible (osk);
- if (!self->setting_visibility)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), visible);
-}
-
-
-static void
-phosh_osk_button_constructed (GObject *object)
-{
- PhoshOskButton *self = PHOSH_OSK_BUTTON (object);
- PhoshShell *shell;
- GtkWidget *image;
-
- G_OBJECT_CLASS (phosh_osk_button_parent_class)->constructed (object);
-
- shell = phosh_shell_get_default ();
- self->osk = g_object_ref(phosh_shell_get_osk_manager (shell));
-
- g_signal_connect_swapped (
- self->osk,
- "notify::visible",
- G_CALLBACK (on_osk_visibility_changed),
- self);
-
- g_signal_connect_swapped (
- self->osk,
- "notify::available",
- G_CALLBACK (on_osk_availability_changed),
- self);
-
- g_signal_connect (self,
- "toggled",
- G_CALLBACK (toggled_cb),
- NULL);
-
- image = gtk_image_new_from_icon_name ("input-keyboard-symbolic", GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON (self), image);
- gtk_button_set_always_show_image (GTK_BUTTON (self), TRUE);
-
- on_osk_availability_changed (self, NULL, self->osk);
- on_osk_visibility_changed (self, NULL, self->osk);
-}
-
-
-static void
-phosh_osk_button_dispose (GObject *object)
-{
- PhoshOskButton *self = PHOSH_OSK_BUTTON (object);
-
- g_clear_object (&self->osk);
- G_OBJECT_CLASS (phosh_osk_button_parent_class)->dispose (object);
-}
-
-
-static void
-phosh_osk_button_class_init (PhoshOskButtonClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->constructed = phosh_osk_button_constructed;
- object_class->dispose = phosh_osk_button_dispose;
-}
-
-
-static void
-phosh_osk_button_init (PhoshOskButton *self)
-{
-}
-
-
-GtkWidget *
-phosh_osk_button_new (void)
-{
- return g_object_new (PHOSH_TYPE_OSK_BUTTON, NULL);
-}
diff -Nru phosh-0.8.0/src/osk/osk-button.h phosh-0.13.1/src/osk/osk-button.h
--- phosh-0.8.0/src/osk/osk-button.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/osk/osk-button.h 1970-01-01 00:00:00.000000000 +0000
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 Purism SPC
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- * Author: Guido Günther
- */
-
-#pragma once
-
-#include
-
-G_BEGIN_DECLS
-
-#define PHOSH_TYPE_OSK_BUTTON (phosh_osk_button_get_type())
-
-G_DECLARE_FINAL_TYPE (PhoshOskButton, phosh_osk_button, PHOSH, OSK_BUTTON, GtkToggleButton)
-
-GtkWidget * phosh_osk_button_new (void);
-
-G_END_DECLS
diff -Nru phosh-0.8.0/src/osk/phosh-osk0-dbus.xml phosh-0.13.1/src/osk/phosh-osk0-dbus.xml
--- phosh-0.8.0/src/osk/phosh-osk0-dbus.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/osk/phosh-osk0-dbus.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-
-
-
-
-
-
- Switch keyboard visibility
-
-
-
-
-
-
diff -Nru phosh-0.8.0/src/osk-button.c phosh-0.13.1/src/osk-button.c
--- phosh-0.8.0/src/osk-button.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/osk-button.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-osk-button"
+
+#include "osk-button.h"
+#include "osk-manager.h"
+#include "shell.h"
+
+#include
+#include
+
+/**
+ * SECTION:osk-button
+ * @short_description: A button that toggles the OSK
+ * @Title: PhoshOsk
+ *
+ * The #PhoshOskButton is responsible for toggling the on screen keyboard
+ */
+struct _PhoshOskButton
+{
+ GtkToggleButton parent;
+
+ PhoshOskManager *osk;
+ gboolean setting_visibility;
+};
+
+G_DEFINE_TYPE (PhoshOskButton, phosh_osk_button, GTK_TYPE_TOGGLE_BUTTON)
+
+
+static void
+toggled_cb (PhoshOskButton *self, gpointer data)
+{
+ gboolean visible, active;
+
+ self->setting_visibility = TRUE;
+ visible = phosh_osk_manager_get_visible (self->osk);
+
+ active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self));
+ if (visible != active)
+ phosh_osk_manager_set_visible (self->osk, active);
+
+ self->setting_visibility = FALSE;
+}
+
+
+static void
+on_osk_availability_changed (PhoshOskButton *self, GParamSpec *pspec, PhoshOskManager *osk)
+{
+ gboolean available;
+
+ g_return_if_fail (PHOSH_IS_OSK_BUTTON (self));
+ g_return_if_fail (PHOSH_IS_OSK_MANAGER (osk));
+ g_return_if_fail (self->osk == osk);
+
+ available = phosh_osk_manager_get_available (osk);
+ gtk_widget_set_sensitive (GTK_WIDGET (self), available);
+}
+
+
+static void
+on_osk_visibility_changed (PhoshOskButton *self, GParamSpec *pspec, PhoshOskManager *osk)
+{
+ gboolean visible;
+
+ g_return_if_fail (PHOSH_IS_OSK_BUTTON (self));
+ g_return_if_fail (PHOSH_IS_OSK_MANAGER (osk));
+ g_return_if_fail (self->osk == osk);
+
+ visible = phosh_osk_manager_get_visible (osk);
+ if (!self->setting_visibility)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), visible);
+}
+
+
+static void
+phosh_osk_button_constructed (GObject *object)
+{
+ PhoshOskButton *self = PHOSH_OSK_BUTTON (object);
+ PhoshShell *shell;
+ GtkWidget *image;
+
+ G_OBJECT_CLASS (phosh_osk_button_parent_class)->constructed (object);
+
+ shell = phosh_shell_get_default ();
+ self->osk = g_object_ref(phosh_shell_get_osk_manager (shell));
+
+ g_signal_connect_swapped (
+ self->osk,
+ "notify::visible",
+ G_CALLBACK (on_osk_visibility_changed),
+ self);
+
+ g_signal_connect_swapped (
+ self->osk,
+ "notify::available",
+ G_CALLBACK (on_osk_availability_changed),
+ self);
+
+ g_signal_connect (self,
+ "toggled",
+ G_CALLBACK (toggled_cb),
+ NULL);
+
+ image = gtk_image_new_from_icon_name ("input-keyboard-symbolic", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (self), image);
+ gtk_button_set_always_show_image (GTK_BUTTON (self), TRUE);
+
+ on_osk_availability_changed (self, NULL, self->osk);
+ on_osk_visibility_changed (self, NULL, self->osk);
+}
+
+
+static void
+phosh_osk_button_dispose (GObject *object)
+{
+ PhoshOskButton *self = PHOSH_OSK_BUTTON (object);
+
+ g_clear_object (&self->osk);
+ G_OBJECT_CLASS (phosh_osk_button_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_osk_button_class_init (PhoshOskButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = phosh_osk_button_constructed;
+ object_class->dispose = phosh_osk_button_dispose;
+}
+
+
+static void
+phosh_osk_button_init (PhoshOskButton *self)
+{
+}
+
+
+GtkWidget *
+phosh_osk_button_new (void)
+{
+ return g_object_new (PHOSH_TYPE_OSK_BUTTON, NULL);
+}
diff -Nru phosh-0.8.0/src/osk-button.h phosh-0.13.1/src/osk-button.h
--- phosh-0.8.0/src/osk-button.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/osk-button.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#pragma once
+
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_OSK_BUTTON (phosh_osk_button_get_type())
+
+G_DECLARE_FINAL_TYPE (PhoshOskButton, phosh_osk_button, PHOSH, OSK_BUTTON, GtkToggleButton)
+
+GtkWidget * phosh_osk_button_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/overview.c phosh-0.13.1/src/overview.c
--- phosh-0.8.0/src/overview.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/overview.c 2021-08-31 09:15:52.000000000 +0000
@@ -10,20 +10,20 @@
#include "config.h"
-#include "overview.h"
#include "activity.h"
-#include "app-grid.h"
#include "app-grid-button.h"
+#include "app-grid.h"
+#include "overview.h"
+#include "wlr-screencopy-unstable-v1-client-protocol.h"
+#include "phosh-private-client-protocol.h"
+#include "phosh-wayland.h"
#include "shell.h"
-#include "util.h"
#include "toplevel-manager.h"
#include "toplevel-thumbnail.h"
-#include "phosh-private-client-protocol.h"
-#include "phosh-wayland.h"
+#include "util.h"
#include
-#define HANDY_USE_UNSTABLE_API
#include
#define OVERVIEW_ICON_SIZE 64
@@ -60,7 +60,7 @@
/* Running activities */
GtkWidget *carousel_running_activities;
GtkWidget *app_grid;
- GtkWidget *activity;
+ PhoshActivity *activity;
int has_activities;
} PhoshOverviewPrivate;
@@ -170,11 +170,21 @@
static void
-on_toplevel_closed (PhoshToplevel *toplevel, PhoshActivity *activity)
+on_toplevel_closed (PhoshToplevel *toplevel, PhoshOverview *overview)
{
+ PhoshActivity *activity;
+ PhoshOverviewPrivate *priv;
+
g_return_if_fail (PHOSH_IS_TOPLEVEL (toplevel));
+ g_return_if_fail (PHOSH_IS_OVERVIEW (overview));
+ priv = phosh_overview_get_instance_private (overview);
+
+ activity = find_activity_by_toplevel (overview, toplevel);
g_return_if_fail (PHOSH_IS_ACTIVITY (activity));
gtk_widget_destroy (GTK_WIDGET (activity));
+
+ if (priv->activity == activity)
+ priv->activity = NULL;
}
@@ -187,9 +197,9 @@
g_return_if_fail (PHOSH_IS_TOPLEVEL (toplevel));
priv = phosh_overview_get_instance_private (overview);
- activity = find_activity_by_toplevel (overview, toplevel);
if (phosh_toplevel_is_activated (toplevel)) {
- priv->activity = GTK_WIDGET (activity);
+ activity = find_activity_by_toplevel (overview, toplevel);
+ priv->activity = activity;
hdy_carousel_scroll_to (HDY_CAROUSEL (priv->carousel_running_activities), GTK_WIDGET (activity));
}
}
@@ -248,6 +258,7 @@
PhoshOverviewPrivate *priv;
GtkWidget *activity;
const char *app_id, *title;
+ float scale;
g_return_if_fail (PHOSH_IS_OVERVIEW (self));
priv = phosh_overview_get_instance_private (self);
@@ -257,9 +268,10 @@
g_debug ("Building activator for '%s' (%s)", app_id, title);
activity = phosh_activity_new (app_id, title);
+ scale = phosh_monitor_get_fractional_scale (monitor);
g_object_set (activity,
- "win-width", monitor->width / monitor->scale, /* TODO: Get the real size somehow */
- "win-height", monitor->height / monitor->scale,
+ "win-width", (int)(monitor->width / scale),
+ "win-height", (int)(monitor->height / scale),
"maximized", phosh_toplevel_is_maximized (toplevel),
NULL);
g_object_set_data (G_OBJECT (activity), "toplevel", toplevel);
@@ -271,7 +283,7 @@
g_signal_connect_swapped (activity, "closed",
G_CALLBACK (on_activity_closed), self);
- g_signal_connect_object (toplevel, "closed", G_CALLBACK (on_toplevel_closed), activity, 0);
+ g_signal_connect_object (toplevel, "closed", G_CALLBACK (on_toplevel_closed), self, 0);
g_signal_connect_object (toplevel, "notify::activated", G_CALLBACK (on_toplevel_activated_changed), self, 0);
g_object_bind_property (toplevel, "maximized", activity, "maximized", G_BINDING_DEFAULT);
@@ -282,7 +294,7 @@
if (phosh_toplevel_is_activated (toplevel)) {
hdy_carousel_scroll_to (HDY_CAROUSEL (priv->carousel_running_activities), activity);
- priv->activity = GTK_WIDGET (activity);
+ priv->activity = PHOSH_ACTIVITY (activity);
}
}
@@ -438,8 +450,6 @@
object_class->get_property = phosh_overview_get_property;
widget_class->size_allocate = phosh_overview_size_allocate;
- gtk_widget_class_set_css_name (widget_class, "phosh-overview");
-
props[PROP_HAS_ACTIVITIES] =
g_param_spec_boolean (
"has-activities",
@@ -509,6 +519,18 @@
phosh_app_grid_focus_search (PHOSH_APP_GRID (priv->app_grid));
}
+
+gboolean
+phosh_overview_handle_search (PhoshOverview *self, GdkEvent *event)
+{
+ PhoshOverviewPrivate *priv;
+
+ g_return_val_if_fail(PHOSH_IS_OVERVIEW (self), GDK_EVENT_PROPAGATE);
+ priv = phosh_overview_get_instance_private (self);
+ return phosh_app_grid_handle_search (PHOSH_APP_GRID (priv->app_grid), event);
+}
+
+
gboolean
phosh_overview_has_running_activities (PhoshOverview *self)
{
@@ -519,3 +541,15 @@
return priv->has_activities;
}
+
+
+PhoshAppGrid *
+phosh_overview_get_app_grid (PhoshOverview *self)
+{
+ PhoshOverviewPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_OVERVIEW (self), NULL);
+ priv = phosh_overview_get_instance_private (self);
+
+ return PHOSH_APP_GRID (priv->app_grid);
+}
diff -Nru phosh-0.8.0/src/overview.h phosh-0.13.1/src/overview.h
--- phosh-0.8.0/src/overview.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/overview.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,8 +6,12 @@
#pragma once
+#include "app-grid.h"
+
#include
+G_BEGIN_DECLS
+
#define PHOSH_TYPE_OVERVIEW (phosh_overview_get_type())
G_DECLARE_FINAL_TYPE (PhoshOverview, phosh_overview, PHOSH, OVERVIEW, GtkBox)
@@ -17,3 +21,7 @@
void phosh_overview_reset (PhoshOverview *self);
void phosh_overview_focus_app_search (PhoshOverview *self);
gboolean phosh_overview_has_running_activities (PhoshOverview *self);
+gboolean phosh_overview_handle_search (PhoshOverview *self, GdkEvent *event);
+PhoshAppGrid *phosh_overview_get_app_grid (PhoshOverview *self);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/panel.c phosh-0.13.1/src/panel.c
--- phosh-0.8.0/src/panel.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/panel.c 1970-01-01 00:00:00.000000000 +0000
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2018 Purism SPC
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- * Author: Guido Günther
- *
- * Somewhat based on maynard's panel which is
- * Copyright (C) 2014 Collabora Ltd. *
- * Author: Jonny Lamb
- */
-
-#define G_LOG_DOMAIN "phosh-panel"
-
-#include "config.h"
-
-#include "bt-info.h"
-#include "connectivity-info.h"
-#include "docked-info.h"
-#include "panel.h"
-#include "shell.h"
-#include "session-manager.h"
-#include "settings.h"
-#include "util.h"
-
-#define GNOME_DESKTOP_USE_UNSTABLE_API
-#include
-#include
-
-#include
-
-/**
- * SECTION:panel
- * @short_description: The top panel
- * @Title: PhoshPanel
- *
- * The top panel containing the clock and status indicators.
- */
-
-enum {
- SETTINGS_ACTIVATED,
- N_SIGNALS
-};
-static guint signals[N_SIGNALS] = { 0 };
-
-typedef struct {
- PhoshPanelState state;
-
- GtkWidget *stack;
- GtkWidget *box; /* main content box */
- GtkWidget *btn_top_panel;
- GtkWidget *lbl_clock;
- GtkWidget *lbl_lang;
- GtkWidget *settings; /* settings menu */
-
- GnomeWallClock *wall_clock;
- GnomeXkbInfo *xkbinfo;
- GSettings *input_settings;
- GdkSeat *seat;
-
- GSimpleActionGroup *actions;
-} PhoshPanelPrivate;
-
-typedef struct _PhoshPanel
-{
- PhoshLayerSurface parent;
-} PhoshPanel;
-
-G_DEFINE_TYPE_WITH_PRIVATE (PhoshPanel, phosh_panel, PHOSH_TYPE_LAYER_SURFACE)
-
-
-static void
-on_shutdown_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- PhoshPanel *self = PHOSH_PANEL(data);
- PhoshSessionManager *sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- phosh_session_manager_shutdown (sm);
- /* TODO: Since we don't implement
- * gnome.SessionManager.EndSessionDialog yet */
- phosh_session_manager_shutdown (sm);
- phosh_panel_fold (self);
-}
-
-
-static void
-on_restart_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- PhoshPanel *self = PHOSH_PANEL(data);
- PhoshSessionManager *sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- g_return_if_fail (PHOSH_IS_SESSION_MANAGER (sm));
-
- phosh_session_manager_reboot (sm);
- /* TODO: Since we don't implement
- * gnome.SessionManager.EndSessionDialog yet */
- phosh_session_manager_reboot (sm);
- phosh_panel_fold (self);
-}
-
-
-static void
-on_lockscreen_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- PhoshPanel *self = PHOSH_PANEL(data);
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- phosh_shell_lock (phosh_shell_get_default ());
- phosh_panel_fold (self);
-}
-
-
-static void
-on_logout_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- PhoshPanel *self = PHOSH_PANEL(data);
- PhoshSessionManager *sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- g_return_if_fail (PHOSH_IS_SESSION_MANAGER (sm));
- phosh_session_manager_logout (sm);
- phosh_panel_fold (self);
-}
-
-
-static void
-top_panel_clicked_cb (PhoshPanel *self, GtkButton *btn)
-{
- g_return_if_fail (PHOSH_IS_PANEL (self));
- g_return_if_fail (GTK_IS_BUTTON (btn));
- g_signal_emit(self, signals[SETTINGS_ACTIVATED], 0);
-}
-
-
-static void
-wall_clock_notify_cb (PhoshPanel *self,
- GParamSpec *pspec,
- GnomeWallClock *wall_clock)
-{
- PhoshPanelPrivate *priv = phosh_panel_get_instance_private (self);
- const char *str;
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- g_return_if_fail (GNOME_IS_WALL_CLOCK (wall_clock));
-
- str = gnome_wall_clock_get_clock(wall_clock);
- gtk_label_set_text (GTK_LABEL (priv->lbl_clock), str);
-}
-
-
-static gboolean
-needs_keyboard_label (PhoshPanel *self)
-{
- PhoshPanelPrivate *priv;
- GList *slaves;
- g_autoptr(GVariant) sources = NULL;
-
- priv = phosh_panel_get_instance_private (self);
- g_return_val_if_fail (GDK_IS_SEAT (priv->seat), FALSE);
- g_return_val_if_fail (G_IS_SETTINGS (priv->input_settings), FALSE);
-
- sources = g_settings_get_value(priv->input_settings, "sources");
- if (g_variant_n_children (sources) < 2)
- return FALSE;
-
- slaves = gdk_seat_get_slaves (priv->seat, GDK_SEAT_CAPABILITY_KEYBOARD);
- if (!slaves)
- return FALSE;
-
- g_list_free (slaves);
- return TRUE;
-}
-
-
-static void
-on_seat_device_changed (PhoshPanel *self, GdkDevice *device, GdkSeat *seat)
-{
- gboolean visible;
- PhoshPanelPrivate *priv;
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- g_return_if_fail (GDK_IS_SEAT (seat));
-
- priv = phosh_panel_get_instance_private (self);
- visible = needs_keyboard_label (self);
- gtk_widget_set_visible (priv->lbl_lang, visible);
-}
-
-
-static void
-on_input_setting_changed (PhoshPanel *self,
- const char *key,
- GSettings *settings)
-{
- PhoshPanelPrivate *priv = phosh_panel_get_instance_private (self);
- g_autoptr(GVariant) sources = NULL;
- GVariantIter iter;
- g_autofree char *id = NULL;
- g_autofree char *type = NULL;
- const char *name;
-
- if (!needs_keyboard_label (self)) {
- gtk_widget_hide (priv->lbl_lang);
- return;
- }
-
- sources = g_settings_get_value(settings, "sources");
- g_variant_iter_init (&iter, sources);
- g_variant_iter_next (&iter, "(ss)", &type, &id);
-
- if (g_strcmp0 (type, "xkb")) {
- g_debug ("Not a xkb layout: '%s' - ignoring", id);
- return;
- }
-
- if (!gnome_xkb_info_get_layout_info (priv->xkbinfo, id,
- NULL, &name, NULL, NULL)) {
- g_debug ("Failed to get layout info for %s", id);
- name = id;
- }
- g_debug ("Layout is %s", name);
- gtk_label_set_text (GTK_LABEL (priv->lbl_lang), name);
- gtk_widget_show (priv->lbl_lang);
-}
-
-
-static gboolean
-on_key_press_event (PhoshPanel *self, GdkEventKey *event, gpointer data)
-{
- gboolean handled = FALSE;
- PhoshPanelPrivate *priv;
-
- g_return_val_if_fail (PHOSH_IS_PANEL (self), FALSE);
- priv = phosh_panel_get_instance_private (self);
-
- if (!priv->settings)
- return handled;
-
- switch (event->keyval) {
- case GDK_KEY_Escape:
- phosh_panel_fold (self);
- handled = TRUE;
- break;
- default:
- /* nothing to do */
- break;
- }
- return handled;
-}
-
-
-static gboolean
-on_button_press_event (PhoshPanel *self, GdkEventKey *event, gpointer data)
-{
- phosh_trigger_feedback ("button-pressed");
- phosh_panel_fold (self);
- return FALSE;
-}
-
-
-static GActionEntry entries[] = {
- { "poweroff", on_shutdown_action, NULL, NULL, NULL },
- { "restart", on_restart_action, NULL, NULL, NULL },
- { "lockscreen", on_lockscreen_action, NULL, NULL, NULL },
- { "logout", on_logout_action, NULL, NULL, NULL },
-};
-
-
-static void
-phosh_panel_constructed (GObject *object)
-{
- PhoshPanel *self = PHOSH_PANEL (object);
- PhoshPanelPrivate *priv = phosh_panel_get_instance_private (self);
- GdkDisplay *display = gdk_display_get_default ();
-
- G_OBJECT_CLASS (phosh_panel_parent_class)->constructed (object);
-
- priv->state = PHOSH_PANEL_STATE_FOLDED;
- priv->wall_clock = gnome_wall_clock_new ();
-
- g_signal_connect_object (priv->wall_clock,
- "notify::clock",
- G_CALLBACK (wall_clock_notify_cb),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->btn_top_panel,
- "clicked",
- G_CALLBACK (top_panel_clicked_cb),
- self,
- G_CONNECT_SWAPPED);
-
- phosh_connect_feedback (priv->btn_top_panel);
-
- gtk_window_set_title (GTK_WINDOW (self), "phosh panel");
- gtk_style_context_add_class (
- gtk_widget_get_style_context (GTK_WIDGET (self)),
- "phosh-panel");
-
- /* Button properites */
- gtk_style_context_remove_class (gtk_widget_get_style_context (priv->btn_top_panel),
- "button");
- gtk_style_context_remove_class (gtk_widget_get_style_context (priv->btn_top_panel),
- "image-button");
-
- wall_clock_notify_cb (self, NULL, priv->wall_clock);
-
- /* language indicator */
- if (display) {
- priv->input_settings = g_settings_new ("org.gnome.desktop.input-sources");
- priv->xkbinfo = gnome_xkb_info_new ();
- priv->seat = gdk_display_get_default_seat (display);
- g_object_connect (priv->seat,
- "swapped_signal::device-added", G_CALLBACK (on_seat_device_changed), self,
- "swapped_signal::device-removed", G_CALLBACK (on_seat_device_changed), self,
- NULL);
- g_signal_connect_swapped (priv->input_settings,
- "changed::sources", G_CALLBACK (on_input_setting_changed),
- self);
- on_input_setting_changed (self, NULL, priv->input_settings);
- }
-
- /* Settings menu and it's top-bar / menu */
- gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
- g_signal_connect (G_OBJECT (self),
- "key-press-event",
- G_CALLBACK (on_key_press_event),
- NULL);
- g_signal_connect (G_OBJECT (self),
- "button-press-event",
- G_CALLBACK (on_button_press_event),
- NULL);
-
- priv->actions = g_simple_action_group_new ();
- gtk_widget_insert_action_group (GTK_WIDGET (self), "panel",
- G_ACTION_GROUP (priv->actions));
- g_action_map_add_action_entries (G_ACTION_MAP (priv->actions),
- entries, G_N_ELEMENTS (entries),
- self);
- if (!phosh_shell_started_by_display_manager (phosh_shell_get_default ())) {
- GAction *action = g_action_map_lookup_action (G_ACTION_MAP (priv->actions),
- "logout");
- g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
- }
-}
-
-
-static void
-phosh_panel_dispose (GObject *object)
-{
- PhoshPanel *self = PHOSH_PANEL (object);
- PhoshPanelPrivate *priv = phosh_panel_get_instance_private (self);
-
- g_clear_object (&priv->wall_clock);
- g_clear_object (&priv->xkbinfo);
- g_clear_object (&priv->input_settings);
- g_clear_object (&priv->actions);
- priv->seat = NULL;
-
- G_OBJECT_CLASS (phosh_panel_parent_class)->dispose (object);
-}
-
-
-static void
-phosh_panel_class_init (PhoshPanelClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *)klass;
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->constructed = phosh_panel_constructed;
- object_class->dispose = phosh_panel_dispose;
-
- signals[SETTINGS_ACTIVATED] = g_signal_new ("settings-activated",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- NULL, G_TYPE_NONE, 0);
-
- g_type_ensure (PHOSH_TYPE_BT_INFO);
- g_type_ensure (PHOSH_TYPE_CONNECTIVITY_INFO);
- g_type_ensure (PHOSH_TYPE_DOCKED_INFO);
- g_type_ensure (PHOSH_TYPE_SETTINGS);
-
- gtk_widget_class_set_template_from_resource (widget_class,
- "/sm/puri/phosh/ui/top-panel.ui");
- gtk_widget_class_bind_template_child_private (widget_class, PhoshPanel, btn_top_panel);
- gtk_widget_class_bind_template_child_private (widget_class, PhoshPanel, lbl_clock);
- gtk_widget_class_bind_template_child_private (widget_class, PhoshPanel, lbl_lang);
- gtk_widget_class_bind_template_child_private (widget_class, PhoshPanel, box);
- gtk_widget_class_bind_template_child_private (widget_class, PhoshPanel, stack);
- gtk_widget_class_bind_template_child_private (widget_class, PhoshPanel, settings);
-}
-
-
-static void
-phosh_panel_init (PhoshPanel *self)
-{
- gtk_widget_init_template (GTK_WIDGET (self));
-}
-
-
-GtkWidget *
-phosh_panel_new (struct zwlr_layer_shell_v1 *layer_shell,
- struct wl_output *wl_output)
-{
- return g_object_new (PHOSH_TYPE_PANEL,
- "layer-shell", layer_shell,
- "wl-output", wl_output,
- "height", PHOSH_PANEL_HEIGHT,
- "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
- "layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
- "kbd-interactivity", FALSE,
- "exclusive-zone", PHOSH_PANEL_HEIGHT,
- "namespace", "phosh",
- NULL);
-}
-
-
-void
-phosh_panel_fold (PhoshPanel *self)
-{
- PhoshPanelPrivate *priv;
- int width;
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- priv = phosh_panel_get_instance_private (self);
-
- if (priv->state == PHOSH_PANEL_STATE_FOLDED)
- return;
-
- gtk_stack_set_transition_type (GTK_STACK (priv->stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP);
- gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "topbar");
- gtk_widget_hide (priv->settings);
- phosh_layer_surface_set_kbd_interactivity (PHOSH_LAYER_SURFACE (self), FALSE);
- gtk_window_get_size (GTK_WINDOW (self), &width, NULL);
- gtk_window_resize (GTK_WINDOW (self), width, PHOSH_PANEL_HEIGHT);
- priv->state = PHOSH_PANEL_STATE_FOLDED;
-}
-
-
-void
-phosh_panel_unfold (PhoshPanel *self)
-{
- PhoshPanelPrivate *priv;
-
- g_return_if_fail (PHOSH_IS_PANEL (self));
- priv = phosh_panel_get_instance_private (self);
-
- if (priv->state == PHOSH_PANEL_STATE_UNFOLDED)
- return;
-
- phosh_layer_surface_set_kbd_interactivity (PHOSH_LAYER_SURFACE (self), TRUE);
- gtk_widget_show (priv->settings);
- gtk_stack_set_transition_type (GTK_STACK (priv->stack), GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN);
- gtk_stack_set_visible_child_name(GTK_STACK (priv->stack), "settings");
- g_signal_connect_swapped (priv->settings,
- "setting-done",
- G_CALLBACK(phosh_panel_fold),
- self);
- priv->state =PHOSH_PANEL_STATE_UNFOLDED;
-}
-
-
-void
-phosh_panel_toggle_fold (PhoshPanel *self)
-{
- PhoshPanelPrivate *priv;
- g_return_if_fail (PHOSH_IS_PANEL (self));
-
- priv = phosh_panel_get_instance_private (self);
- if (priv->state == PHOSH_PANEL_STATE_UNFOLDED) {
- phosh_panel_fold (self);
- } else {
- phosh_panel_unfold (self);
- }
-}
-
-
-PhoshPanelState
-phosh_panel_get_state (PhoshPanel *self)
-{
- PhoshPanelPrivate *priv;
- g_return_val_if_fail (PHOSH_IS_PANEL (self), PHOSH_PANEL_STATE_FOLDED);
-
- priv = phosh_panel_get_instance_private (self);
- return priv->state;
-}
diff -Nru phosh-0.8.0/src/panel.h phosh-0.13.1/src/panel.h
--- phosh-0.8.0/src/panel.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/panel.h 1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 Purism SPC
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-#pragma once
-
-#include "layersurface.h"
-
-#define PHOSH_TYPE_PANEL (phosh_panel_get_type ())
-
-G_DECLARE_FINAL_TYPE (PhoshPanel, phosh_panel, PHOSH, PANEL, PhoshLayerSurface)
-
-#define PHOSH_PANEL_HEIGHT 32
-
-/**
- * PhoshPanelState:
- * @PHOSH_PANEL_STATE_FOLDED: Only top-bar is visible
- * @PHOSH_PANEL_STATE_UNFOLDED: Settings menu is unfolded
- */
-typedef enum {
- PHOSH_PANEL_STATE_FOLDED,
- PHOSH_PANEL_STATE_UNFOLDED,
-} PhoshPanelState;
-
-GtkWidget * phosh_panel_new (struct zwlr_layer_shell_v1 *layer_shell,
- struct wl_output *wl_output);
-void phosh_panel_toggle_fold (PhoshPanel *self);
-void phosh_panel_fold (PhoshPanel *self);
-void phosh_panel_unfold (PhoshPanel *self);
-PhoshPanelState phosh_panel_get_state (PhoshPanel *self);
diff -Nru phosh-0.8.0/src/phosh-enums.c.in phosh-0.13.1/src/phosh-enums.c.in
--- phosh-0.8.0/src/phosh-enums.c.in 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/phosh-enums.c.in 2021-08-31 09:15:52.000000000 +0000
@@ -2,13 +2,18 @@
#include "config.h"
+#include "app-grid.h"
#include "app-grid-button.h"
+#include "gnome-shell-manager.h"
#include "home.h"
+#include "lockscreen.h"
#include "mode-manager.h"
#include "monitor/monitor.h"
#include "notifications/notification.h"
#include "notifications/notify-manager.h"
#include "phosh-wayland.h"
+#include "rotation-manager.h"
+#include "shell.h"
#include "wwan/phosh-wwan-backend.h"
#include "phosh-enums.h"
diff -Nru phosh-0.8.0/src/phosh.gresources.xml phosh-0.13.1/src/phosh.gresources.xml
--- phosh-0.8.0/src/phosh.gresources.xml 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/phosh.gresources.xml 2021-08-31 09:15:52.000000000 +0000
@@ -2,8 +2,11 @@
ui/activity.ui
+ ui/app-auth-prompt.ui
ui/app-grid.ui
ui/app-grid-button.ui
+ ui/end-session-dialog.ui
+ ui/gtk-mount-prompt.ui
ui/overview.ui
ui/home.ui
ui/lockscreen.ui
@@ -12,11 +15,15 @@
ui/notification-frame.ui
ui/polkit-auth-prompt.ui
ui/network-auth-prompt.ui
+ ui/osd-window.ui
ui/settings-menu.ui
+ ui/system-modal-dialog.ui
ui/system-prompt.ui
ui/top-panel.ui
ui/quick-setting.ui
- style.css
+ stylesheet/adwaita-dark.css
+ stylesheet/adwaita-hc-light.css
+ stylesheet/common.css
../data/fake-app.svg
@@ -26,8 +33,11 @@
../data/auth-sim-locked-symbolic.svg
../data/auth-sim-missing-symbolic.svg
+ ../data/camera-hardware-disabled-symbolic.svg
../data/eye-not-looking-symbolic.svg
../data/eye-open-negative-filled-symbolic.svg
+ ../data/feedback-quiet-symbolic.svg
+ ../data/microphone-hardware-disabled-symbolic.svg
../data/network-cellular-disabled-symbolic.svg
../data/network-wireless-disabled-symbolic.svg
../data/phone-docked-symbolic.svg
diff -Nru phosh-0.8.0/src/phosh-wayland.c phosh-0.13.1/src/phosh-wayland.c
--- phosh-0.8.0/src/phosh-wayland.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/phosh-wayland.c 2021-08-31 09:15:52.000000000 +0000
@@ -38,6 +38,7 @@
struct gamma_control_manager *gamma_control_manager;
struct org_kde_kwin_idle *idle_manager;
struct phosh_private *phosh_private;
+ struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1;
struct wl_display *display;
struct wl_registry *registry;
struct wl_seat *wl_seat;
@@ -48,6 +49,7 @@
struct zwlr_output_manager_v1 *zwlr_output_manager_v1;
struct zwlr_output_power_manager_v1 *zwlr_output_power_manager_v1;
struct zxdg_output_manager_v1 *zxdg_output_manager_v1;
+ struct zwlr_screencopy_manager_v1 *zwlr_screencopy_manager_v1;
struct wl_shm *wl_shm;
GHashTable *wl_outputs;
PhoshWaylandSeatCapabilities seat_capabilities;
@@ -142,6 +144,18 @@
name,
&zwlr_foreign_toplevel_manager_v1_interface,
2);
+ } else if (!strcmp (interface, zwlr_screencopy_manager_v1_interface.name)) {
+ self->zwlr_screencopy_manager_v1 = wl_registry_bind (
+ registry,
+ name,
+ &zwlr_screencopy_manager_v1_interface,
+ 2);
+ } else if (!strcmp (interface, zwp_virtual_keyboard_manager_v1_interface.name)) {
+ self->zwp_virtual_keyboard_manager_v1 = wl_registry_bind (
+ registry,
+ name,
+ &zwp_virtual_keyboard_manager_v1_interface,
+ 1);
}
}
@@ -436,6 +450,24 @@
return self->zwlr_foreign_toplevel_manager_v1;
}
+
+struct zwlr_screencopy_manager_v1*
+phosh_wayland_get_zwlr_screencopy_manager_v1 (PhoshWayland *self)
+{
+ g_return_val_if_fail (PHOSH_IS_WAYLAND (self), NULL);
+
+ return self->zwlr_screencopy_manager_v1;
+}
+
+struct zwp_virtual_keyboard_manager_v1*
+phosh_wayland_get_zwp_virtual_keyboard_manager_v1 (PhoshWayland *self)
+{
+ g_return_val_if_fail (PHOSH_IS_WAYLAND (self), NULL);
+
+ return self->zwp_virtual_keyboard_manager_v1;
+}
+
+
/**
* phosh_wayland_get_wl_outputs:
* @self: The #PhoshWayland singleton
diff -Nru phosh-0.8.0/src/phosh-wayland.h phosh-0.13.1/src/phosh-wayland.h
--- phosh-0.8.0/src/phosh-wayland.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/phosh-wayland.h 2021-08-31 09:15:52.000000000 +0000
@@ -9,16 +9,20 @@
#include "gamma-control-client-protocol.h"
#include "idle-client-protocol.h"
-#include "wlr-screencopy-unstable-v1-client-protocol.h"
-#include "phosh-private-client-protocol.h"
+#include "virtual-keyboard-unstable-v1-client-protocol.h"
#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
#include "wlr-input-inhibitor-unstable-v1-client-protocol.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
#include "wlr-output-management-unstable-v1-client-protocol.h"
#include "wlr-output-power-management-unstable-v1-client-protocol.h"
+#include "wlr-screencopy-unstable-v1-client-protocol.h"
+#include "wlr-screencopy-unstable-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
#include "xdg-shell-client-protocol.h"
+/* This goes past the other wl protocols since it might need their structs */
+#include "phosh-private-client-protocol.h"
+
#include
G_BEGIN_DECLS
@@ -59,6 +63,8 @@
struct zwlr_output_manager_v1 *phosh_wayland_get_zwlr_output_manager_v1 (PhoshWayland *self);
struct zwlr_output_power_manager_v1 *phosh_wayland_get_zwlr_output_power_manager_v1 (PhoshWayland *self);
struct zxdg_output_manager_v1 *phosh_wayland_get_zxdg_output_manager_v1 (PhoshWayland *self);
+struct zwlr_screencopy_manager_v1 *phosh_wayland_get_zwlr_screencopy_manager_v1 (PhoshWayland *self);
+struct zwp_virtual_keyboard_manager_v1 *phosh_wayland_get_zwp_virtual_keyboard_manager_v1 (PhoshWayland *self);
void phosh_wayland_roundtrip (PhoshWayland *self);
PhoshWaylandSeatCapabilities phosh_wayland_get_seat_capabilities (PhoshWayland *self);
diff -Nru phosh-0.8.0/src/polkit-auth-agent.c phosh-0.13.1/src/polkit-auth-agent.c
--- phosh-0.8.0/src/polkit-auth-agent.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/polkit-auth-agent.c 2021-08-31 09:15:52.000000000 +0000
@@ -11,7 +11,6 @@
#include "polkit-auth-agent.h"
#include "polkit-auth-prompt.h"
#include "shell.h"
-#include "phosh-wayland.h"
#include
#include
@@ -65,27 +64,30 @@
static gboolean
agent_register (PhoshPolkitAuthAgent *self)
{
- GError *err = NULL;
- g_autoptr(PolkitSubject) subject;
+ g_autoptr (GError) err = NULL;
+ g_autoptr (PolkitSubject) subject;
subject = polkit_unix_session_new_for_process_sync (getpid (),
- NULL, /* GCancellable* */
+ NULL, /* GCancellable */
&err);
if (subject == NULL) {
- g_warning("PolKit failed to properly get our session");
+ if (g_str_has_prefix (err->message, "No session for pid"))
+ g_message ("PolKit failed to properly get our session: %s", err->message);
+ else
+ g_warning ("PolKit failed to properly get our session: %s", err->message);
return FALSE;
}
/* FIXME: this blocks so we should do it async */
self->handle = polkit_agent_listener_register (POLKIT_AGENT_LISTENER (self),
- POLKIT_AGENT_REGISTER_FLAGS_NONE,
- subject,
- NULL, /* use default object path */
- NULL, /* GCancellable */
- &err);
+ POLKIT_AGENT_REGISTER_FLAGS_NONE,
+ subject,
+ NULL, /* use default object path */
+ NULL, /* GCancellable */
+ &err);
if (!self->handle) {
- g_warning("Auth agent failed to register: %s", err->message);
+ g_warning ("Auth agent failed to register: %s", err->message);
return FALSE;
}
@@ -131,9 +133,6 @@
static void
auth_request_initiate (AuthRequest *request)
{
- PhoshWayland *wl = phosh_wayland_get_default ();
- PhoshShell *shell = phosh_shell_get_default ();
- PhoshMonitor *primary_monitor;
g_auto(GStrv) user_names;
GPtrArray *p;
GList *l;
@@ -167,8 +166,7 @@
user_names = (char **) g_ptr_array_free (p, FALSE);
g_debug("New prompt for %s", request->message);
- primary_monitor = phosh_shell_get_primary_monitor (shell);
- /* We must not issue a new prompt when there's one alread */
+ /* We must not issue a new prompt when there's one already */
g_return_if_fail (!request->agent->current_prompt);
request->agent->current_prompt = PHOSH_POLKIT_AUTH_PROMPT (
phosh_polkit_auth_prompt_new (
@@ -176,9 +174,7 @@
request->message,
request->icon_name,
request->cookie,
- user_names,
- phosh_wayland_get_zwlr_layer_shell_v1(wl),
- primary_monitor->wl_output));
+ user_names));
g_signal_connect (request->agent->current_prompt,
"done",
@@ -195,8 +191,8 @@
maybe_process_next_request (PhoshPolkitAuthAgent *self)
{
auth_debug ("cur=%p len(scheduled)=%d",
- self->current_request,
- g_list_length (self->scheduled_requests));
+ self->current_request,
+ g_list_length (self->scheduled_requests));
if (self->current_request == NULL && self->scheduled_requests != NULL) {
AuthRequest *request;
@@ -219,7 +215,7 @@
gboolean is_current = self->current_request == request;
auth_debug ("completing %s %s cookie %s", is_current ? "current" : "scheduled",
- request->action_id, request->cookie);
+ request->action_id, request->cookie);
if (!is_current)
self->scheduled_requests = g_list_remove (self->scheduled_requests, request);
@@ -256,7 +252,7 @@
}
/*
- * on_request_canelled:
+ * on_request_cancelled:
*
* This happens when the application requesting authentication
* is closed.
diff -Nru phosh-0.8.0/src/polkit-auth-prompt.c phosh-0.13.1/src/polkit-auth-prompt.c
--- phosh-0.8.0/src/polkit-auth-prompt.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/polkit-auth-prompt.c 2021-08-31 09:15:52.000000000 +0000
@@ -51,7 +51,7 @@
struct _PhoshPolkitAuthPrompt
{
- PhoshLayerSurface parent;
+ PhoshSystemModalDialog parent;
GtkWidget *lbl_message;
GtkWidget *lbl_user_name;
@@ -75,7 +75,7 @@
gboolean done_emitted;
};
-G_DEFINE_TYPE(PhoshPolkitAuthPrompt, phosh_polkit_auth_prompt, PHOSH_TYPE_LAYER_SURFACE);
+G_DEFINE_TYPE(PhoshPolkitAuthPrompt, phosh_polkit_auth_prompt, PHOSH_TYPE_SYSTEM_MODAL_DIALOG);
static void phosh_polkit_auth_prompt_initiate (PhoshPolkitAuthPrompt *self);
@@ -289,7 +289,7 @@
PolkitAgentSession *session)
{
g_debug ("%s", text);
- gtk_entry_set_text (GTK_ENTRY (self->lbl_info), text);
+ gtk_label_set_text (GTK_LABEL (self->lbl_info), text);
}
@@ -299,7 +299,7 @@
PolkitAgentSession *session)
{
g_debug ("%s", text);
- gtk_entry_set_text (GTK_ENTRY (self->lbl_info), text);
+ gtk_label_set_text (GTK_LABEL (self->lbl_info), text);
}
@@ -365,8 +365,10 @@
static void
-on_btn_cancel_clicked (PhoshPolkitAuthPrompt *self, GtkButton *btn)
+on_dialog_canceled (PhoshPolkitAuthPrompt *self, gpointer unused)
{
+ g_return_if_fail (PHOSH_IS_POLKIT_AUTH_PROMPT (self));
+
polkit_agent_session_cancel (self->session);
emit_done (self, TRUE);
}
@@ -389,27 +391,6 @@
}
-static gboolean
-on_key_press_event (PhoshPolkitAuthPrompt *self, GdkEventKey *event, gpointer data)
-{
- gboolean handled = FALSE;
- g_return_val_if_fail (PHOSH_IS_POLKIT_AUTH_PROMPT (self), FALSE);
-
- switch (event->keyval) {
- case GDK_KEY_Escape:
- polkit_agent_session_cancel (self->session);
- emit_done (self, TRUE);
- handled = TRUE;
- break;
- default:
- /* nothing to do */
- break;
- }
-
- return handled;
-}
-
-
static void
phosh_polkit_auth_prompt_dispose (GObject *obj)
{
@@ -448,35 +429,6 @@
gtk_entry_set_buffer (GTK_ENTRY (self->entry_password),
GTK_ENTRY_BUFFER (self->password_buffer));
- g_signal_connect_object (self->btn_cancel,
- "clicked",
- G_CALLBACK (on_btn_cancel_clicked),
- self,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (self->btn_authenticate,
- "clicked",
- G_CALLBACK (on_btn_authenticate_clicked),
- self,
- G_CONNECT_SWAPPED);
-
- gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
- g_signal_connect (G_OBJECT (self),
- "key_press_event",
- G_CALLBACK (on_key_press_event),
- NULL);
-
- {
- GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- GtkWidget *lbl = gtk_label_new (_("Authenticate"));
-
- self->spinner_authenticate = gtk_spinner_new ();
- gtk_widget_set_no_show_all (self->spinner_authenticate, TRUE);
- gtk_container_add (GTK_CONTAINER (self->btn_authenticate), box);
- gtk_container_add (GTK_CONTAINER (box), self->spinner_authenticate);
- gtk_container_add (GTK_CONTAINER (box), lbl);
- gtk_widget_show_all (self->btn_authenticate);
- }
-
phosh_polkit_auth_prompt_initiate (self);
}
@@ -546,6 +498,9 @@
gtk_widget_class_bind_template_child (widget_class, PhoshPolkitAuthPrompt, btn_authenticate);
gtk_widget_class_bind_template_child (widget_class, PhoshPolkitAuthPrompt, btn_cancel);
gtk_widget_class_bind_template_child (widget_class, PhoshPolkitAuthPrompt, entry_password);
+ gtk_widget_class_bind_template_child (widget_class, PhoshPolkitAuthPrompt, spinner_authenticate);
+ gtk_widget_class_bind_template_callback (widget_class, on_dialog_canceled);
+ gtk_widget_class_bind_template_callback (widget_class, on_btn_authenticate_clicked);
}
@@ -561,9 +516,7 @@
const char *message,
const char *icon_name,
const char *cookie,
- GStrv user_names,
- gpointer layer_shell,
- gpointer wl_output)
+ GStrv user_names)
{
return g_object_new (PHOSH_TYPE_POLKIT_AUTH_PROMPT,
/* polkit prompt */
@@ -572,16 +525,5 @@
"message", message,
"icon-name", icon_name,
"user-names", user_names,
- /* layer shell */
- "layer-shell", layer_shell,
- "wl-output", wl_output,
- "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
- "layer", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
- "kbd-interactivity", TRUE,
- "exclusive-zone", -1,
- "namespace", "phosh prompter",
NULL);
}
diff -Nru phosh-0.8.0/src/polkit-auth-prompt.h phosh-0.13.1/src/polkit-auth-prompt.h
--- phosh-0.8.0/src/polkit-auth-prompt.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/polkit-auth-prompt.h 2021-08-31 09:15:52.000000000 +0000
@@ -7,18 +7,16 @@
#pragma once
#include
-#include "layersurface.h"
+#include "system-modal-dialog.h"
#define PHOSH_TYPE_POLKIT_AUTH_PROMPT (phosh_polkit_auth_prompt_get_type())
-G_DECLARE_FINAL_TYPE (PhoshPolkitAuthPrompt, phosh_polkit_auth_prompt, PHOSH, POLKIT_AUTH_PROMPT, PhoshLayerSurface);
+G_DECLARE_FINAL_TYPE (PhoshPolkitAuthPrompt, phosh_polkit_auth_prompt, PHOSH, POLKIT_AUTH_PROMPT, PhoshSystemModalDialog);
GtkWidget *phosh_polkit_auth_prompt_new (const char *action_id,
const char *message,
const char *icon_name,
const char *cookie,
- GStrv user_names,
- gpointer layer_shell,
- gpointer wl_output);
+ GStrv user_names);
diff -Nru phosh-0.8.0/src/proximity.c phosh-0.13.1/src/proximity.c
--- phosh-0.8.0/src/proximity.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/proximity.c 2021-08-31 09:15:52.000000000 +0000
@@ -19,13 +19,16 @@
* SECTION:proximity
* @short_description: Proximity sensor handling
* @Title: PhoshProximity
+ *
+ * #PhoshProximity handles enabling and disabling the proximity detection
+ * based on e.g. active calls.
*/
enum {
PROP_0,
PROP_SENSOR_PROXY_MANAGER,
- PROP_LOCKSCREEN_MANAGER,
+ PROP_CALLS_MANAGER,
LAST_PROP,
};
static GParamSpec *props[LAST_PROP];
@@ -35,7 +38,7 @@
gboolean claimed;
PhoshSensorProxyManager *sensor_proxy_manager;
- PhoshLockscreenManager *lockscreen_manager;
+ PhoshCallsManager *calls_manager;
PhoshFader *fader;
} PhoshProximity;
@@ -65,6 +68,7 @@
}
}
+
static void
on_proximity_released (PhoshSensorProxyManager *sensor_proxy_manager,
GAsyncResult *res,
@@ -86,8 +90,10 @@
} else {
g_warning ("Failed to release proximity sensor: %s", err->message);
}
+ g_clear_pointer (&self->fader, phosh_cp_widget_destroy);
}
+
static void
phosh_proximity_claim_proximity (PhoshProximity *self, gboolean claim)
{
@@ -117,28 +123,32 @@
{
gboolean has_proximity;
- /* Don't claim if locked to save power */
- if (phosh_lockscreen_manager_get_locked(self->lockscreen_manager))
- return;
-
has_proximity = phosh_dbus_sensor_proxy_get_has_proximity (
PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager));
g_debug ("Found %s proximity sensor", has_proximity ? "a" : "no");
+
+ /* If prox went a way we always unclaim but only claim on ongoing calls: */
+ if (!phosh_calls_manager_get_active_call_handle (self->calls_manager) && has_proximity)
+ return;
+
phosh_proximity_claim_proximity (self, has_proximity);
}
+
static void
-on_lockscreen_manager_locked (PhoshProximity *self, GParamSpec *pspec,
- PhoshLockscreenManager *lockscreen_manager)
+on_calls_manager_active_call_changed (PhoshProximity *self,
+ GParamSpec *pspec,
+ PhoshCallsManager *calls_manager)
{
- gboolean locked;
+ gboolean active;
g_return_if_fail (PHOSH_IS_PROXIMITY (self));
- g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (lockscreen_manager));
+ g_return_if_fail (PHOSH_IS_CALLS_MANAGER (calls_manager));
- locked = phosh_lockscreen_manager_get_locked(self->lockscreen_manager);
- phosh_proximity_claim_proximity (self, !locked);
+ active = !!phosh_calls_manager_get_active_call_handle (self->calls_manager);
+ phosh_proximity_claim_proximity (self, active);
+ /* TODO: if call is over wait until we hit the threshold */
}
@@ -148,19 +158,19 @@
PhoshSensorProxyManager *sensor)
{
gboolean near;
+ PhoshShell *shell = phosh_shell_get_default ();
+ PhoshMonitor *monitor = phosh_shell_get_builtin_monitor (shell);
near = phosh_dbus_sensor_proxy_get_proximity_near (
PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager));
g_debug ("Proximity near changed: %d", near);
- if (near) {
- PhoshShell *shell = phosh_shell_get_default ();
- PhoshWayland *wl = phosh_wayland_get_default ();
- PhoshMonitor *monitor = phosh_shell_get_builtin_monitor (shell);
-
+ if (near && monitor) {
if (!self->fader) {
- self->fader = phosh_fader_new (phosh_wayland_get_zwlr_layer_shell_v1 (wl),
- monitor->wl_output);
+ self->fader = g_object_new (PHOSH_TYPE_FADER,
+ "monitor", monitor,
+ "style-class", "phosh-fader-proximity-fade",
+ NULL);
gtk_widget_show (GTK_WIDGET (self->fader));
}
} else {
@@ -181,9 +191,9 @@
/* construct only */
self->sensor_proxy_manager = g_value_dup_object (value);
break;
- case PROP_LOCKSCREEN_MANAGER:
+ case PROP_CALLS_MANAGER:
/* construct only */
- self->lockscreen_manager = g_value_dup_object (value);
+ self->calls_manager = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -191,6 +201,7 @@
}
}
+
static void
phosh_proximity_get_property (GObject *object,
guint property_id,
@@ -203,8 +214,8 @@
case PROP_SENSOR_PROXY_MANAGER:
g_value_set_object (value, self->sensor_proxy_manager);
break;
- case PROP_LOCKSCREEN_MANAGER:
- g_value_set_object (value, self->lockscreen_manager);
+ case PROP_CALLS_MANAGER:
+ g_value_set_object (value, self->calls_manager);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -212,14 +223,15 @@
}
}
+
static void
phosh_proximity_constructed (GObject *object)
{
PhoshProximity *self = PHOSH_PROXIMITY (object);
- g_signal_connect_swapped (self->lockscreen_manager,
- "notify::locked",
- G_CALLBACK (on_lockscreen_manager_locked),
+ g_signal_connect_swapped (self->calls_manager,
+ "notify::active-call",
+ G_CALLBACK (on_calls_manager_active_call_changed),
self);
g_signal_connect_swapped (self->sensor_proxy_manager,
@@ -236,6 +248,7 @@
G_OBJECT_CLASS (phosh_proximity_parent_class)->constructed (object);
}
+
static void
phosh_proximity_dispose (GObject *object)
{
@@ -249,16 +262,17 @@
g_clear_object (&self->sensor_proxy_manager);
}
- if (self->lockscreen_manager) {
- g_signal_handlers_disconnect_by_data (self->lockscreen_manager,
+ if (self->calls_manager) {
+ g_signal_handlers_disconnect_by_data (self->calls_manager,
self);
- g_clear_object (&self->lockscreen_manager);
+ g_clear_object (&self->calls_manager);
}
g_clear_pointer (&self->fader, phosh_cp_widget_destroy);
G_OBJECT_CLASS (phosh_proximity_parent_class)->dispose (object);
}
+
static void
phosh_proximity_class_init (PhoshProximityClass *klass)
{
@@ -278,18 +292,19 @@
PHOSH_TYPE_SENSOR_PROXY_MANAGER,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- props[PROP_LOCKSCREEN_MANAGER] =
+ props[PROP_CALLS_MANAGER] =
g_param_spec_object (
- "lockscreen-manager",
- "Lockscren manager",
- "The object managing the lock screen",
- PHOSH_TYPE_LOCKSCREEN_MANAGER,
+ "calls-manager",
+ "",
+ "",
+ PHOSH_TYPE_CALLS_MANAGER,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, props);
}
+
static void
phosh_proximity_init (PhoshProximity *self)
{
@@ -298,10 +313,10 @@
PhoshProximity *
phosh_proximity_new (PhoshSensorProxyManager *sensor_proxy_manager,
- PhoshLockscreenManager *lockscreen_manager)
+ PhoshCallsManager *calls_manager)
{
return g_object_new (PHOSH_TYPE_PROXIMITY,
"sensor-proxy-manager", sensor_proxy_manager,
- "lockscreen-manager", lockscreen_manager,
+ "calls-manager", calls_manager,
NULL);
}
diff -Nru phosh-0.8.0/src/proximity.h phosh-0.13.1/src/proximity.h
--- phosh-0.8.0/src/proximity.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/proximity.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,7 +6,7 @@
#pragma once
-#include "lockscreen-manager.h"
+#include "calls-manager.h"
#include "sensor-proxy-manager.h"
G_BEGIN_DECLS
@@ -16,6 +16,6 @@
G_DECLARE_FINAL_TYPE (PhoshProximity, phosh_proximity, PHOSH, PROXIMITY, GObject);
PhoshProximity *phosh_proximity_new (PhoshSensorProxyManager *sensor_proxy_manager,
- PhoshLockscreenManager *lockscreen_manager);
+ PhoshCallsManager *calls_manager);
G_END_DECLS
diff -Nru phosh-0.8.0/src/rotateinfo.c phosh-0.13.1/src/rotateinfo.c
--- phosh-0.8.0/src/rotateinfo.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/rotateinfo.c 2021-08-31 09:15:52.000000000 +0000
@@ -15,29 +15,45 @@
/**
* SECTION:rotateinfo
- * @short_description: A widget to display the rotate status
+ * @short_description: A widget to display the rotate lock status
* @Title: PhoshRotateInfo
*
- * Rotate Info widget
+ * A #PhoshStatusIcon to display the rotation lock status.
+ * It can either display whether a rotation lock is currently active or
+ * if the output is in portrait/landscape mode.
*/
+enum {
+ PROP_0,
+ PROP_PRESENT,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
typedef struct _PhoshRotateInfo {
- PhoshStatusIcon parent;
+ PhoshStatusIcon parent;
+
+ PhoshRotationManager *manager;
+ gboolean present;
} PhoshRotateInfo;
G_DEFINE_TYPE (PhoshRotateInfo, phosh_rotate_info, PHOSH_TYPE_STATUS_ICON)
-
static void
-set_state (PhoshRotateInfo *self)
+on_transform_changed (PhoshRotateInfo *self)
{
- PhoshShell *shell = phosh_shell_get_default ();
- PhoshMonitor *monitor = phosh_shell_get_primary_monitor (shell);
+ PhoshMonitor *monitor = phosh_rotation_manager_get_monitor (self->manager);
gboolean monitor_is_landscape;
gboolean portrait;
- switch (phosh_shell_get_transform (shell)) {
+ if (phosh_rotation_manager_get_mode (self->manager) != PHOSH_ROTATION_MANAGER_MODE_OFF)
+ return;
+
+ if (!monitor)
+ return;
+
+ switch (phosh_rotation_manager_get_transform (self->manager)) {
case PHOSH_MONITOR_TRANSFORM_NORMAL:
case PHOSH_MONITOR_TRANSFORM_FLIPPED:
case PHOSH_MONITOR_TRANSFORM_180:
@@ -59,7 +75,7 @@
monitor_is_landscape = ((double)monitor->width / (double)monitor->height) > 1.0;
portrait = monitor_is_landscape ? !portrait : portrait;
- g_debug ("Potrait: %d, width: %d, height: %d", portrait, monitor->width , monitor->height);
+ g_debug ("Potrait: %d, width: %d, height: %d", portrait, monitor->width, monitor->height);
if (portrait) {
phosh_status_icon_set_icon_name (PHOSH_STATUS_ICON (self), "screen-rotation-portrait-symbolic");
phosh_status_icon_set_info (PHOSH_STATUS_ICON (self), _("Portrait"));
@@ -71,13 +87,69 @@
static void
-phosh_rotate_info_finalize (GObject *object)
+on_orientation_lock_changed (PhoshRotateInfo *self)
+{
+ gboolean locked = phosh_rotation_manager_get_orientation_locked (self->manager);
+ const char *icon_name;
+
+ if (phosh_rotation_manager_get_mode (self->manager) != PHOSH_ROTATION_MANAGER_MODE_SENSOR)
+ return;
+
+ g_debug ("Orientation locked: %d", locked);
+
+ icon_name = locked ? "rotation-locked-symbolic" : "rotation-allowed-symbolic";
+ phosh_status_icon_set_icon_name (PHOSH_STATUS_ICON (self), icon_name);
+ /* Translators: Automatic screen orientation is either on (enabled) or off (locked/disabled) */
+ phosh_status_icon_set_info (PHOSH_STATUS_ICON (self), locked ? _("Off") : _("On"));
+
+ return;
+}
+
+
+static void
+on_mode_or_monitor_changed (PhoshRotateInfo *self)
{
- PhoshRotateInfo *self = PHOSH_ROTATE_INFO(object);
+ PhoshRotationManagerMode mode = phosh_rotation_manager_get_mode (self->manager);
+ gboolean present = !!phosh_rotation_manager_get_monitor (self->manager);
+
+ g_debug ("Rotation manager mode: %d, has-builtin: %d", mode, present);
+ switch (mode) {
+ case PHOSH_ROTATION_MANAGER_MODE_OFF:
+ on_transform_changed (self);
+ break;
+ case PHOSH_ROTATION_MANAGER_MODE_SENSOR:
+ on_orientation_lock_changed (self);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (self->present == present)
+ return;
+
+ self->present = present;
+ g_debug ("Built-in monitor present: %d", present);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PRESENT]);
+}
- g_signal_handlers_disconnect_by_data (phosh_shell_get_default (), self);
- G_OBJECT_CLASS (phosh_rotate_info_parent_class)->finalize (object);
+static void
+phosh_rotate_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshRotateInfo *self = PHOSH_ROTATE_INFO (object);
+
+ switch (property_id) {
+ case PROP_PRESENT:
+ g_value_set_boolean (value, self->present);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
@@ -85,23 +157,55 @@
phosh_rotate_info_class_init (PhoshRotateInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = phosh_rotate_info_finalize;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = phosh_rotate_info_get_property;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-rotate-info");
+
+ props[PROP_PRESENT] =
+ g_param_spec_boolean ("present",
+ "Present",
+ "Whether a builtin display to rotate is present",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
static void
phosh_rotate_info_init (PhoshRotateInfo *self)
{
- g_signal_connect_swapped (phosh_shell_get_default (),
- "notify::transform",
- G_CALLBACK (set_state),
- self);
- set_state (self);
-}
+ self->manager = phosh_shell_get_rotation_manager (phosh_shell_get_default());
+ phosh_status_icon_set_icon_name (PHOSH_STATUS_ICON (self), "rotation-locked-symbolic");
+ /* Translators: Automatic screen orientation is off (locked/disabled) */
+ phosh_status_icon_set_info (PHOSH_STATUS_ICON (self), _("Off"));
+
+ /* We don't use property bindings since we flip info/icon based on rotation and lock */
+ g_signal_connect_object (self->manager,
+ "notify::transform",
+ G_CALLBACK (on_transform_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->manager,
+ "notify::orientation-locked",
+ G_CALLBACK (on_orientation_lock_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->manager,
+ "notify::mode",
+ G_CALLBACK (on_mode_or_monitor_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->manager,
+ "notify::monitor",
+ G_CALLBACK (on_mode_or_monitor_changed),
+ self,
+ G_CONNECT_SWAPPED);
-GtkWidget *
-phosh_rotate_info_new (void)
-{
- return g_object_new (PHOSH_TYPE_ROTATE_INFO, NULL);
+ on_mode_or_monitor_changed (self);
}
diff -Nru phosh-0.8.0/src/rotateinfo.h phosh-0.13.1/src/rotateinfo.h
--- phosh-0.8.0/src/rotateinfo.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/rotateinfo.h 2021-08-31 09:15:52.000000000 +0000
@@ -11,10 +11,24 @@
G_BEGIN_DECLS
+/**
+ * PhoshRotateInfoMode:
+ * @PHOSH_ROTATE_INFO_MODE_LOCK: Button toggles rotation lock
+ * @PHOSH_ROTATE_INFO_MODE_TOGGLE: Button toggles potrait/landscape
+ *
+ * The power save mode of a monitor
+ */
+typedef enum {
+ PHOSH_ROTATE_INFO_MODE_LOCK,
+ PHOSH_ROTATE_INFO_MODE_TOGGLE,
+} PhoshRotateInfoMode;
+
#define PHOSH_TYPE_ROTATE_INFO (phosh_rotate_info_get_type())
G_DECLARE_FINAL_TYPE (PhoshRotateInfo, phosh_rotate_info, PHOSH, ROTATE_INFO, PhoshStatusIcon)
-GtkWidget * phosh_rotate_info_new (void);
+GtkWidget *phosh_rotate_info_new (void);
+PhoshRotateInfoMode phosh_rotate_info_get_mode (PhoshRotateInfo *self);
+void phosh_rotate_info_set_mode (PhoshRotateInfo *self, PhoshRotateInfoMode mode);
G_END_DECLS
diff -Nru phosh-0.8.0/src/rotation-manager.c phosh-0.13.1/src/rotation-manager.c
--- phosh-0.8.0/src/rotation-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/rotation-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,709 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-rotation-manager"
+
+#include "config.h"
+#include "rotation-manager.h"
+#include "shell.h"
+#include "sensor-proxy-manager.h"
+#include "util.h"
+
+#define ORIENTATION_LOCK_SCHEMA_ID "org.gnome.settings-daemon.peripherals.touchscreen"
+#define ORIENTATION_LOCK_KEY "orientation-lock"
+
+/**
+ * SECTION:rotation-manager
+ * @short_description: The Rotation Manager
+ * @Title: PhoshRotationManager
+ *
+ * #PhoshRotationManager is responsible for managing the rotation of
+ * a given #PhoshMonitor. Depending on the #PhoshRotationManagerMode
+ * this can happen by interfacing with a #PhoshSensorProxyManager or
+ * by setting the #PhoshMonitorTransform explicitly.
+ * It also takes the #PhoshLockscreenManager:locked status into account
+ * to ensure the lockscreen is rotated accordingly on small phones.
+ */
+
+enum {
+ PROP_0,
+ PROP_SENSOR_PROXY_MANAGER,
+ PROP_LOCKSCREEN_MANAGER,
+ PROP_ORIENTATION_LOCKED,
+ PROP_MONITOR,
+ PROP_MODE,
+ PROP_TRANSFORM,
+ LAST_PROP,
+};
+static GParamSpec *props[LAST_PROP];
+
+typedef struct _PhoshRotationManager {
+ GObject parent;
+
+ gboolean claimed;
+ GCancellable *cancel;
+ PhoshSensorProxyManager *sensor_proxy_manager;
+ PhoshLockscreenManager *lockscreen_manager;
+ PhoshMonitor *monitor;
+ PhoshMonitorTransform transform;
+ PhoshMonitorTransform prelock_transform;
+
+ GSettings *settings;
+ gboolean orientation_locked;
+
+ PhoshRotationManagerMode mode;
+} PhoshRotationManager;
+
+G_DEFINE_TYPE (PhoshRotationManager, phosh_rotation_manager, G_TYPE_OBJECT);
+
+
+static void
+apply_transform (PhoshRotationManager *self, PhoshMonitorTransform transform)
+{
+ PhoshMonitorTransform current;
+ PhoshMonitorManager *monitor_manager = phosh_shell_get_monitor_manager (phosh_shell_get_default());
+
+ g_return_if_fail (PHOSH_IS_MONITOR_MANAGER (monitor_manager));
+
+ if (!self->monitor)
+ return;
+
+ g_debug ("Rotating %s: %d", self->monitor->name, transform);
+
+ current = phosh_monitor_get_transform (self->monitor);
+ if (current == transform)
+ return;
+
+ phosh_monitor_manager_set_monitor_transform (monitor_manager,
+ self->monitor,
+ transform);
+ phosh_monitor_manager_apply_monitor_config (monitor_manager);
+}
+
+/**
+ * match_orientation:
+ * @self: The #PhoshRotationManager
+ *
+ * Match the screen orientation to the sensor output.
+ * Do nothing if orientation lock is on or there's no
+ * sensor claimed.
+ */
+static void
+match_orientation (PhoshRotationManager *self)
+{
+ const gchar *orient;
+ PhoshMonitorTransform transform;
+
+ if (self->orientation_locked || !self->claimed ||
+ self->mode == PHOSH_ROTATION_MANAGER_MODE_OFF)
+ return;
+
+ orient = phosh_dbus_sensor_proxy_get_accelerometer_orientation (
+ PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager));
+
+ g_debug ("Orientation changed: %s, locked: %d, claimed: %d",
+ orient, self->orientation_locked, self->claimed);
+
+ if (!g_strcmp0 ("normal", orient)) {
+ transform = PHOSH_MONITOR_TRANSFORM_NORMAL;
+ } else if (!g_strcmp0 ("right-up", orient)) {
+ transform = PHOSH_MONITOR_TRANSFORM_270;
+ } else if (!g_strcmp0 ("bottom-up", orient)) {
+ transform = PHOSH_MONITOR_TRANSFORM_180;
+ } else if (!g_strcmp0 ("left-up", orient)) {
+ transform = PHOSH_MONITOR_TRANSFORM_90;
+ } else if (!g_strcmp0 ("undefined", orient)) {
+ return; /* just leave as is */
+ } else {
+ g_warning ("Unknown orientation '%s'", orient);
+ return;
+ }
+
+ apply_transform (self, transform);
+}
+
+static void
+on_accelerometer_claimed (PhoshSensorProxyManager *sensor_proxy_manager,
+ GAsyncResult *res,
+ PhoshRotationManager *self)
+{
+ g_autoptr (GError) err = NULL;
+ gboolean success;
+
+ g_return_if_fail (PHOSH_IS_SENSOR_PROXY_MANAGER (sensor_proxy_manager));
+
+ success = phosh_dbus_sensor_proxy_call_claim_accelerometer_finish (
+ PHOSH_DBUS_SENSOR_PROXY (sensor_proxy_manager),
+ res, &err);
+
+ if (!success) {
+ phosh_async_error_warn (err, "Failed to claim accelerometer");
+ return;
+ }
+
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (sensor_proxy_manager == self->sensor_proxy_manager);
+
+ g_debug ("Claimed accelerometer");
+ self->claimed = TRUE;
+ match_orientation (self);
+}
+
+static void
+on_accelerometer_released (PhoshSensorProxyManager *sensor_proxy_manager,
+ GAsyncResult *res,
+ PhoshRotationManager *self)
+{
+ g_autoptr (GError) err = NULL;
+ gboolean success;
+
+ g_return_if_fail (PHOSH_IS_SENSOR_PROXY_MANAGER (sensor_proxy_manager));
+
+ success = phosh_dbus_sensor_proxy_call_release_accelerometer_finish (
+ PHOSH_DBUS_SENSOR_PROXY (sensor_proxy_manager),
+ res, &err);
+
+ if (!success) {
+ phosh_async_error_warn (err, "Failed to release accelerometer");
+ return;
+ }
+
+ g_debug ("Released rotation sensor");
+ self->claimed = FALSE;
+}
+
+static void
+phosh_rotation_manager_claim_accelerometer (PhoshRotationManager *self, gboolean claim)
+{
+ if (claim == self->claimed)
+ return;
+
+ if (!self->sensor_proxy_manager)
+ return;
+
+ if (claim) {
+ phosh_dbus_sensor_proxy_call_claim_accelerometer (
+ PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager),
+ self->cancel,
+ (GAsyncReadyCallback)on_accelerometer_claimed,
+ self);
+ } else {
+ phosh_dbus_sensor_proxy_call_release_accelerometer (
+ PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager),
+ self->cancel,
+ (GAsyncReadyCallback)on_accelerometer_released,
+ self);
+ }
+}
+
+static void
+on_has_accelerometer_changed (PhoshRotationManager *self,
+ GParamSpec *pspec,
+ PhoshSensorProxyManager *proxy)
+{
+ gboolean has_accel;
+ PhoshRotationManagerMode mode;
+
+ has_accel = phosh_dbus_sensor_proxy_get_has_accelerometer (
+ PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager));
+
+ g_debug ("Found %s accelerometer", has_accel ? "a" : "no");
+
+ mode = has_accel ? PHOSH_ROTATION_MANAGER_MODE_SENSOR : PHOSH_ROTATION_MANAGER_MODE_OFF;
+ phosh_rotation_manager_set_mode (self, mode);
+}
+
+/**
+ * fixup_lockscreen_orientation:
+ * @self: The PhoshRotationManager
+ * @force: Whether to force the monitor to portait orientation
+ *
+ * On phones the lock screen doesn't work in landscape so fix that up
+ * until https://source.puri.sm/Librem5/phosh/-/issues/388
+ * is fixed. Keep all of this local to this function.
+ */
+static void
+fixup_lockscreen_orientation (PhoshRotationManager *self, gboolean force)
+{
+ PhoshShell *shell = phosh_shell_get_default ();
+ PhoshModeManager *mode_manager = phosh_shell_get_mode_manager(shell);
+
+ g_return_if_fail (PHOSH_IS_MODE_MANAGER (mode_manager));
+
+ if (!self->monitor)
+ return;
+
+ /* Only bother on phones */
+ if (phosh_mode_manager_get_device_type(mode_manager) != PHOSH_MODE_DEVICE_TYPE_PHONE &&
+ phosh_mode_manager_get_device_type(mode_manager) != PHOSH_MODE_DEVICE_TYPE_UNKNOWN)
+ return;
+
+ /* Don't mess with transforms on external screens either */
+ if (!phosh_monitor_is_builtin (self->monitor))
+ return;
+
+ if (phosh_lockscreen_manager_get_locked (self->lockscreen_manager)) {
+ if (force) {
+ PhoshMonitorTransform transform;
+ /* Use prelock transform if portrait, else use normal */
+ transform = (self->prelock_transform % 2) == 0 ? self->prelock_transform :
+ PHOSH_MONITOR_TRANSFORM_NORMAL;
+ g_debug ("Forcing portrait transform: %d", transform);
+ apply_transform (self, transform);
+ } else {
+ self->prelock_transform = phosh_monitor_get_transform (self->monitor);
+ g_debug ("Saving transform %d", self->prelock_transform);
+ }
+ } else {
+ g_debug ("Restoring transform %d", self->prelock_transform);
+ apply_transform (self, self->prelock_transform);
+ }
+}
+
+
+static void
+on_power_mode_changed (PhoshRotationManager *self,
+ GParamSpec *pspec,
+ PhoshMonitor *monitor)
+{
+ PhoshMonitorPowerSaveMode mode;
+
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_MONITOR (monitor));
+
+ mode = phosh_monitor_get_power_save_mode (monitor);
+ g_debug ("Powersave mode: %d", mode);
+ if (mode != PHOSH_MONITOR_POWER_SAVE_MODE_ON)
+ return;
+
+ fixup_lockscreen_orientation (self, TRUE);
+}
+
+
+static void
+claim_or_release_accelerometer (PhoshRotationManager *self)
+{
+ gboolean claim = TRUE;
+
+ /* No need for accel on screen lock, saves power */
+ if (phosh_lockscreen_manager_get_locked (self->lockscreen_manager))
+ claim = FALSE;
+
+ /* No need for accel on orientation lock, saves power */
+ if (self->orientation_locked)
+ claim = FALSE;
+
+ /* No need for accel when automatic rotation is not requested or possible */
+ if (self->mode == PHOSH_ROTATION_MANAGER_MODE_OFF)
+ claim = FALSE;
+
+ if (claim == self->claimed)
+ return;
+
+ phosh_rotation_manager_claim_accelerometer (self, claim);
+}
+
+
+static void
+on_lockscreen_manager_locked (PhoshRotationManager *self, GParamSpec *pspec,
+ PhoshLockscreenManager *lockscreen_manager)
+{
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (lockscreen_manager));
+
+ claim_or_release_accelerometer (self);
+ fixup_lockscreen_orientation (self, FALSE);
+}
+
+
+static void
+on_accelerometer_orientation_changed (PhoshRotationManager *self,
+ GParamSpec *pspec,
+ PhoshSensorProxyManager *sensor)
+{
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (self->sensor_proxy_manager == sensor);
+
+ match_orientation (self);
+}
+
+
+static void
+on_monitor_configured (PhoshRotationManager *self,
+ PhoshMonitor *monitor)
+{
+ PhoshMonitorTransform transform;
+
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_MONITOR (monitor));
+
+ transform = phosh_monitor_get_transform (monitor);
+ if (transform == self->transform)
+ return;
+
+ self->transform = transform;
+ g_debug ("Rotation-manager transform %d", transform);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TRANSFORM]);
+}
+
+
+static void
+phosh_rotation_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshRotationManager *self = PHOSH_ROTATION_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_SENSOR_PROXY_MANAGER:
+ /* construct only */
+ self->sensor_proxy_manager = g_value_dup_object (value);
+ break;
+ case PROP_LOCKSCREEN_MANAGER:
+ /* construct only */
+ self->lockscreen_manager = g_value_dup_object (value);
+ break;
+ case PROP_MONITOR:
+ phosh_rotation_manager_set_monitor (self, g_value_get_object (value));
+ break;
+ case PROP_ORIENTATION_LOCKED:
+ phosh_rotation_manager_set_orientation_locked (self,
+ g_value_get_boolean (value));
+ break;
+ case PROP_MODE:
+ phosh_rotation_manager_set_mode (self, g_value_get_enum (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+phosh_rotation_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshRotationManager *self = PHOSH_ROTATION_MANAGER (object);
+
+ switch (property_id) {
+ case PROP_SENSOR_PROXY_MANAGER:
+ g_value_set_object (value, self->sensor_proxy_manager);
+ break;
+ case PROP_LOCKSCREEN_MANAGER:
+ g_value_set_object (value, self->lockscreen_manager);
+ break;
+ case PROP_ORIENTATION_LOCKED:
+ g_value_set_boolean (value, self->orientation_locked);
+ break;
+ case PROP_MODE:
+ g_value_set_enum (value, self->mode);
+ break;
+ case PROP_TRANSFORM:
+ g_value_set_enum (value, self->transform);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+phosh_rotation_manager_constructed (GObject *object)
+{
+ PhoshRotationManager *self = PHOSH_ROTATION_MANAGER (object);
+
+ G_OBJECT_CLASS (phosh_rotation_manager_parent_class)->constructed (object);
+
+ self->settings = g_settings_new (ORIENTATION_LOCK_SCHEMA_ID);
+
+ g_settings_bind (self->settings,
+ ORIENTATION_LOCK_KEY,
+ self,
+ "orientation-locked",
+ G_BINDING_SYNC_CREATE
+ | G_BINDING_BIDIRECTIONAL);
+
+ g_signal_connect_swapped (self->lockscreen_manager,
+ "notify::locked",
+ (GCallback) on_lockscreen_manager_locked,
+ self);
+ on_lockscreen_manager_locked (self, NULL, self->lockscreen_manager);
+
+ if (!self->sensor_proxy_manager) {
+ g_message ("Got no sensor-proxy, no automatic rotation");
+ return;
+ }
+
+ g_signal_connect_swapped (self->sensor_proxy_manager,
+ "notify::accelerometer-orientation",
+ (GCallback) on_accelerometer_orientation_changed,
+ self);
+
+ g_signal_connect_swapped (self->sensor_proxy_manager,
+ "notify::has-accelerometer",
+ (GCallback) on_has_accelerometer_changed,
+ self);
+ on_has_accelerometer_changed (self, NULL, self->sensor_proxy_manager);
+}
+
+
+static void
+phosh_rotation_manager_dispose (GObject *object)
+{
+ PhoshRotationManager *self = PHOSH_ROTATION_MANAGER (object);
+
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
+ g_clear_object (&self->settings);
+
+ if (self->sensor_proxy_manager) {
+ g_signal_handlers_disconnect_by_data (self->sensor_proxy_manager,
+ self);
+ /* Sync call since we're going away */
+ phosh_dbus_sensor_proxy_call_release_accelerometer_sync (
+ PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager), NULL, NULL);
+ g_clear_object (&self->sensor_proxy_manager);
+ }
+
+ if (self->lockscreen_manager) {
+ g_signal_handlers_disconnect_by_data (self->lockscreen_manager,
+ self);
+ g_clear_object (&self->lockscreen_manager);
+ }
+
+ if (self->monitor) {
+ g_signal_handlers_disconnect_by_data (self->monitor,
+ self);
+ g_clear_object (&self->monitor);
+ }
+
+ G_OBJECT_CLASS (phosh_rotation_manager_parent_class)->dispose (object);
+}
+
+static void
+phosh_rotation_manager_class_init (PhoshRotationManagerClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *)klass;
+
+ object_class->constructed = phosh_rotation_manager_constructed;
+ object_class->dispose = phosh_rotation_manager_dispose;
+
+ object_class->set_property = phosh_rotation_manager_set_property;
+ object_class->get_property = phosh_rotation_manager_get_property;
+
+ props[PROP_SENSOR_PROXY_MANAGER] =
+ g_param_spec_object (
+ "sensor-proxy-manager",
+ "Sensor proxy manager",
+ "The object inerfacing with iio-sensor-proxy",
+ PHOSH_TYPE_SENSOR_PROXY_MANAGER,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_LOCKSCREEN_MANAGER] =
+ g_param_spec_object (
+ "lockscreen-manager",
+ "Lockscren manager",
+ "The object managing the lock screen",
+ PHOSH_TYPE_LOCKSCREEN_MANAGER,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_MONITOR] =
+ g_param_spec_object (
+ "monitor",
+ "Monitor",
+ "The monitor to rotate",
+ PHOSH_TYPE_MONITOR,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_ORIENTATION_LOCKED] =
+ g_param_spec_boolean (
+ "orientation-locked",
+ "Screen orientation locked",
+ "Whether the screen orientation is locked",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_MODE] =
+ g_param_spec_enum (
+ "mode",
+ "Rotation mode",
+ "The current rotation mode",
+ PHOSH_TYPE_ROTATION_MANAGER_MODE,
+ PHOSH_ROTATION_MANAGER_MODE_OFF,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ props[PROP_TRANSFORM] =
+ g_param_spec_enum ("transform",
+ "Transform",
+ "Monitor transform of the rotation monitor",
+ PHOSH_TYPE_MONITOR_TRANSFORM,
+ PHOSH_MONITOR_TRANSFORM_NORMAL,
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, props);
+}
+
+static void
+phosh_rotation_manager_init (PhoshRotationManager *self)
+{
+ self->cancel = g_cancellable_new ();
+}
+
+
+PhoshRotationManager *
+phosh_rotation_manager_new (PhoshSensorProxyManager *sensor_proxy_manager,
+ PhoshLockscreenManager *lockscreen_manager,
+ PhoshMonitor *monitor)
+{
+ return g_object_new (PHOSH_TYPE_ROTATION_MANAGER,
+ "sensor-proxy-manager", sensor_proxy_manager,
+ "lockscreen-manager", lockscreen_manager,
+ "monitor", monitor,
+ NULL);
+}
+
+void
+phosh_rotation_manager_set_orientation_locked (PhoshRotationManager *self, gboolean locked)
+{
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+
+ if (locked == self->orientation_locked)
+ return;
+
+ self->orientation_locked = locked;
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ORIENTATION_LOCKED]);
+
+ /* We don't need accel if orientation locked and vice versa */
+ if (self->claimed == self->orientation_locked)
+ claim_or_release_accelerometer (self);
+ else
+ match_orientation (self);
+}
+
+gboolean
+phosh_rotation_manager_get_orientation_locked (PhoshRotationManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_ROTATION_MANAGER (self), TRUE);
+
+ return self->orientation_locked;
+}
+
+PhoshRotationManagerMode
+phosh_rotation_manager_get_mode (PhoshRotationManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_ROTATION_MANAGER (self), PHOSH_ROTATION_MANAGER_MODE_OFF);
+
+ return self->mode;
+}
+
+/**
+ * phosh_rotation_manager_set_mode:
+ * @self: The #PhoshRotationManager
+ * @mode: The #PhoshRotationManagerMode to set
+ *
+ * Sets the given mode.
+ * Returns: %TRUE if setting the mode was possible, otherwise %FALSE (e.g. when trying
+ * to set %PHOSH_ROTATION_MANAGER_MODE_SENSOR without having a sensor.
+ */
+gboolean
+phosh_rotation_manager_set_mode (PhoshRotationManager *self, PhoshRotationManagerMode mode)
+{
+ gboolean has_accel;
+
+ g_return_val_if_fail (PHOSH_IS_ROTATION_MANAGER (self), FALSE);
+
+ if (mode == self->mode)
+ return TRUE;
+
+ has_accel = phosh_dbus_sensor_proxy_get_has_accelerometer (
+ PHOSH_DBUS_SENSOR_PROXY (self->sensor_proxy_manager));
+
+ if (mode == PHOSH_ROTATION_MANAGER_MODE_SENSOR && !has_accel)
+ return FALSE;
+
+ self->mode = mode;
+
+ g_debug ("Setting mode: %d", mode);
+ claim_or_release_accelerometer (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_MODE]);
+ return TRUE;
+}
+
+
+void
+phosh_rotation_manager_set_transform (PhoshRotationManager *self,
+ PhoshMonitorTransform transform)
+{
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (self->mode == PHOSH_ROTATION_MANAGER_MODE_OFF);
+
+ apply_transform (self, transform);
+}
+
+PhoshMonitorTransform
+phosh_rotation_manager_get_transform (PhoshRotationManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_ROTATION_MANAGER (self), PHOSH_MONITOR_TRANSFORM_NORMAL);
+ g_return_val_if_fail (PHOSH_IS_MONITOR (self->monitor), PHOSH_MONITOR_TRANSFORM_NORMAL);
+
+ return self->monitor->transform;
+}
+
+/**
+ * phosh_rotation_manager_get_monitor:
+ * @self: The PhoshRotationManager
+ *
+ * Returns: The #PhoshMonitor this manager acts on
+ */
+PhoshMonitor *
+phosh_rotation_manager_get_monitor (PhoshRotationManager *self)
+{
+ g_return_val_if_fail (PHOSH_IS_ROTATION_MANAGER (self), NULL);
+
+ return self->monitor;
+}
+
+
+void
+phosh_rotation_manager_set_monitor (PhoshRotationManager *self, PhoshMonitor *monitor)
+{
+ g_return_if_fail (PHOSH_IS_ROTATION_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_MONITOR (monitor) || monitor == NULL);
+
+ g_debug ("Using monitor %p", monitor);
+
+ if (self->monitor == monitor)
+ return;
+
+ if (self->monitor) {
+ g_signal_handlers_disconnect_by_data (self->monitor, self);
+ g_clear_object (&self->monitor);
+ }
+
+ if (monitor == NULL) {
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_MONITOR]);
+ return;
+ }
+
+ self->monitor = g_object_ref (monitor);
+ g_signal_connect_swapped (self->monitor,
+ "notify::power-mode",
+ G_CALLBACK (on_power_mode_changed),
+ self);
+ on_power_mode_changed (self, NULL, self->monitor);
+
+ g_signal_connect_swapped (self->monitor,
+ "configured",
+ G_CALLBACK (on_monitor_configured),
+ self);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_MONITOR]);
+}
diff -Nru phosh-0.8.0/src/rotation-manager.h phosh-0.13.1/src/rotation-manager.h
--- phosh-0.8.0/src/rotation-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/rotation-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#pragma once
+
+#include "lockscreen-manager.h"
+#include "sensor-proxy-manager.h"
+#include "monitor/monitor.h"
+
+G_BEGIN_DECLS
+
+/**
+ * PhoshRotationManagerMode:
+ * @PHOSH_ROTATION_MANAGER_MODE_OFF: automatic rotation off
+ * @PHOSH_ROTATION_MANAGER_MODE_SENSOR: rotation driven by sensor orientation
+ *
+ * The mode of a #PhoshRotationManager
+ */
+typedef enum {
+ PHOSH_ROTATION_MANAGER_MODE_OFF,
+ PHOSH_ROTATION_MANAGER_MODE_SENSOR,
+} PhoshRotationManagerMode;
+
+#define PHOSH_TYPE_ROTATION_MANAGER (phosh_rotation_manager_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshRotationManager, phosh_rotation_manager, PHOSH, ROTATION_MANAGER, GObject);
+
+PhoshRotationManager *phosh_rotation_manager_new (PhoshSensorProxyManager *sensor_proxy_manager,
+ PhoshLockscreenManager *lockscreen_manager,
+ PhoshMonitor *monitor);
+void phosh_rotation_manager_set_orientation_locked (PhoshRotationManager *self,
+ gboolean locked);
+gboolean phosh_rotation_manager_get_orientation_locked (PhoshRotationManager *self);
+
+PhoshRotationManagerMode phosh_rotation_manager_get_mode (PhoshRotationManager *self);
+gboolean phosh_rotation_manager_set_mode (PhoshRotationManager *self,
+ PhoshRotationManagerMode mode);
+void phosh_rotation_manager_set_transform (PhoshRotationManager *self,
+ PhoshMonitorTransform tranform);
+PhoshMonitorTransform phosh_rotation_manager_get_transform (PhoshRotationManager *self);
+PhoshMonitor *phosh_rotation_manager_get_monitor (PhoshRotationManager *self);
+void phosh_rotation_manager_set_monitor (PhoshRotationManager *self,
+ PhoshMonitor *monitor);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/screen-saver-manager.c phosh-0.13.1/src/screen-saver-manager.c
--- phosh-0.8.0/src/screen-saver-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/screen-saver-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -45,6 +45,7 @@
{
PhoshScreenSaverDBusScreenSaverSkeleton parent;
+ int idle_id;
int dbus_name_id;
PhoshLockscreenManager *lockscreen_manager;
@@ -69,7 +70,7 @@
switch (property_id) {
case PROP_LOCKSCREEN_MANAGER:
- self->lockscreen_manager = g_value_get_object (value);
+ self->lockscreen_manager = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -205,7 +206,7 @@
skeleton = G_DBUS_INTERFACE_SKELETON (self);
locked = phosh_lockscreen_manager_get_locked(self->lockscreen_manager);
- g_debug ("Signal ActiveChanged: %d", locked);
+ g_debug ("Signaling ActiveChanged: %d", locked);
g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton),
NULL,
g_dbus_interface_skeleton_get_object_path (skeleton),
@@ -227,7 +228,7 @@
g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (lockscreen_manager));
skeleton = G_DBUS_INTERFACE_SKELETON (self);
- g_debug ("Signal WakeUpScreen");
+ g_debug ("Signaling WakeUpScreen");
g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton),
NULL,
g_dbus_interface_skeleton_get_object_path (skeleton),
@@ -292,7 +293,7 @@
const char *name,
gpointer user_data)
{
- PhoshScreenSaverManager *self = user_data;
+ PhoshScreenSaverManager *self = PHOSH_SCREEN_SAVER_MANAGER (user_data);
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
connection,
@@ -306,6 +307,12 @@
{
PhoshScreenSaverManager *self = PHOSH_SCREEN_SAVER_MANAGER (object);
+ g_clear_handle_id (&self->idle_id, g_source_remove);
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
+
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
g_clear_object (&self->lockscreen_manager);
g_clear_object (&self->logind_session_proxy);
g_clear_object (&self->logind_manager_proxy);
@@ -324,7 +331,7 @@
self->logind_session_proxy = phosh_login1_session_dbus_login_session_proxy_new_for_bus_finish (
res, &err);
if (!self->logind_session_proxy) {
- g_warning ("Failed to get login1 session proxy: %s", err->message);
+ phosh_dbus_service_error_warn (err, "Failed to get login1 session proxy");
goto out;
}
@@ -382,7 +389,7 @@
phosh_login1_manager_dbus_login_manager_proxy_new_for_bus_finish (res, &err);
if (!self->logind_manager_proxy) {
- g_warning ("Failed to get login1 manager proxy: %s", err->message);
+ phosh_dbus_service_error_warn (err, "Failed to get login1 manager proxy");
goto out;
}
@@ -405,7 +412,7 @@
static gboolean
-on_idle (PhoshTorchManager *self)
+on_idle (PhoshScreenSaverManager *self)
{
/* Connect to logind's session manager */
phosh_login1_manager_dbus_login_manager_proxy_new_for_bus (
@@ -417,6 +424,7 @@
(GAsyncReadyCallback) on_logind_manager_proxy_new_for_bus_finish,
g_object_ref (self));
+ self->idle_id = 0;
return G_SOURCE_REMOVE;
}
@@ -434,13 +442,13 @@
on_bus_acquired,
on_name_acquired,
on_name_lost,
- g_object_ref (self),
- g_object_unref);
+ self,
+ NULL);
g_return_if_fail (PHOSH_IS_LOCKSCREEN_MANAGER (self->lockscreen_manager));
/* Perform login1 setup when idle */
- g_idle_add ((GSourceFunc)on_idle, self);
+ self->idle_id = g_idle_add ((GSourceFunc)on_idle, self);
}
diff -Nru phosh-0.8.0/src/screenshot-manager.c phosh-0.13.1/src/screenshot-manager.c
--- phosh-0.8.0/src/screenshot-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/screenshot-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-screenshot-manager"
+
+#include "config.h"
+#include "fader.h"
+#include "phosh-wayland.h"
+#include "screenshot-manager.h"
+#include "shell.h"
+#include "util.h"
+#include "wl-buffer.h"
+
+#include "dbus/phosh-screenshot-dbus.h"
+
+#define BUS_NAME "org.gnome.Shell.Screenshot"
+#define OBJECT_PATH "/org/gnome/Shell/Screenshot"
+
+#define FLASH_FADER_TIMEOUT 500
+
+/**
+ * SECTION:screenshot-manager
+ * @short_description: Screenshot interaction
+ * @Title: PhoshScreenshotManager
+ *
+ * The #PhoshScreenshotManager is responsible for
+ * taking screenshots.
+ */
+
+static void phosh_screenshot_manager_screenshot_iface_init (
+ PhoshDBusScreenshotIface *iface);
+
+
+typedef struct _ScreencopyFrame {
+ struct zwlr_screencopy_frame_v1 *frame;
+ uint32_t flags;
+ char *filename;
+ GDBusMethodInvocation *invocation;
+ PhoshWlBuffer *buffer;
+ gboolean flash;
+ GdkPixbuf *pixbuf;
+} ScreencopyFrame;
+
+
+typedef struct _PhoshScreenshotManager {
+ PhoshDBusScreenshotSkeleton parent;
+
+ int dbus_name_id;
+ struct zwlr_screencopy_manager_v1 *wl_scm;
+ ScreencopyFrame *frame;
+
+ PhoshFader *fader;
+ guint fader_id;
+ PhoshFader *opaque;
+ guint opaque_id;
+} PhoshScreenshotManager;
+
+
+G_DEFINE_TYPE_WITH_CODE (PhoshScreenshotManager,
+ phosh_screenshot_manager,
+ PHOSH_DBUS_TYPE_SCREENSHOT_SKELETON,
+ G_IMPLEMENT_INTERFACE (
+ PHOSH_DBUS_TYPE_SCREENSHOT,
+ phosh_screenshot_manager_screenshot_iface_init));
+
+
+static void
+screencopy_frame_dispose (ScreencopyFrame *frame)
+{
+ phosh_wl_buffer_destroy (frame->buffer);
+ g_clear_pointer (&frame->frame, zwlr_screencopy_frame_v1_destroy);
+ g_clear_object (&frame->pixbuf);
+ g_free (frame->filename);
+ g_free (frame);
+}
+
+
+static void
+screencopy_frame_handle_buffer (void *data,
+ struct zwlr_screencopy_frame_v1 *frame,
+ uint32_t format,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (data);
+
+ g_return_if_fail (PHOSH_IS_SCREENSHOT_MANAGER (self));
+
+ g_debug ("Handling buffer %dx%d for %s", width, height,
+ self->frame->filename ?: "");
+ self->frame->buffer = phosh_wl_buffer_new (format, width, height, stride);
+ g_return_if_fail (self->frame->buffer);
+
+ zwlr_screencopy_frame_v1_copy (frame, self->frame->buffer->wl_buffer);
+}
+
+
+static void
+screencopy_frame_handle_flags (void *data,
+ struct zwlr_screencopy_frame_v1 *frame,
+ uint32_t flags)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (data);
+
+ g_return_if_fail (PHOSH_IS_SCREENSHOT_MANAGER (self));
+ g_return_if_fail (self->frame);
+
+ self->frame->flags = flags;
+}
+
+static gboolean
+on_fader_timeout (gpointer user_data)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (user_data);
+
+ g_clear_pointer (&self->fader, phosh_cp_widget_destroy);
+
+ self->fader_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+
+static void
+show_fader (PhoshScreenshotManager *self)
+{
+ PhoshMonitor *monitor = phosh_shell_get_primary_monitor (phosh_shell_get_default ());
+
+ self->fader_id = g_timeout_add (FLASH_FADER_TIMEOUT, on_fader_timeout, self);
+ g_source_set_name_by_id (self->fader_id, "[phosh] screenshot fader");
+ self->fader = g_object_new (PHOSH_TYPE_FADER,
+ "monitor", monitor,
+ "style-class", "phosh-fader-flash-fade",
+ NULL);
+ gtk_widget_show (GTK_WIDGET (self->fader));
+}
+
+
+static void
+screencopy_done (PhoshScreenshotManager *self, gboolean success)
+{
+ phosh_dbus_screenshot_complete_screenshot (PHOSH_DBUS_SCREENSHOT (self),
+ self->frame->invocation,
+ success,
+ self->frame->filename ?: "");
+ /* TODO: GNOME >= 40 wants us to emit the click sound from here */
+ if (self->frame->flash && success)
+ show_fader (self);
+
+ g_clear_pointer (&self->frame, screencopy_frame_dispose);
+}
+
+
+static void
+on_save_pixbuf_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ gboolean success;
+ g_autoptr (GError) err = NULL;
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (user_data);
+
+ g_return_if_fail (PHOSH_IS_SCREENSHOT_MANAGER (self));
+
+ success = gdk_pixbuf_save_to_stream_finish (res, &err);
+ if (!success)
+ g_warning ("Failed to save screenshot to %s: %s", self->frame->filename, err->message);
+
+ screencopy_done (self, success);
+ g_object_unref (self);
+}
+
+
+static gboolean
+on_opaque_timeout (PhoshScreenshotManager *self)
+{
+ GdkDisplay *display = gdk_display_get_default ();
+ GtkClipboard *clipboard;
+
+ if (!display) {
+ g_critical ("Couldn't get GDK display");
+ goto out;
+ }
+
+ clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_image (clipboard, self->frame->pixbuf);
+ g_debug ("Updated clipboard with %p", self->frame);
+ screencopy_done (self, TRUE);
+
+ out:
+ g_clear_pointer (&self->opaque, phosh_cp_widget_destroy);
+ self->opaque_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+
+static void
+screencopy_frame_handle_ready (void *data,
+ struct zwlr_screencopy_frame_v1 *frame,
+ uint32_t tv_sec_hi,
+ uint32_t tv_sec_lo,
+ uint32_t tv_nsec)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (data);
+
+ g_autoptr (GdkPixbuf) pixbuf = NULL;
+ g_autoptr (GError) err = NULL;
+ g_autoptr (GFileOutputStream) stream = NULL;
+ g_autoptr (GFile) file = NULL;
+ g_autoptr (GBytes) bytes = NULL;
+
+ g_return_if_fail (PHOSH_IS_SCREENSHOT_MANAGER (self));
+ g_debug ("Frame %p %dx%d, stride %d, format 0x%x ready, saving to %s",
+ frame,
+ self->frame->buffer->width,
+ self->frame->buffer->height,
+ self->frame->buffer->stride,
+ self->frame->buffer->format,
+ self->frame->filename ?: "");
+
+ switch ((uint32_t) self->frame->buffer->format) {
+ case WL_SHM_FORMAT_ABGR8888:
+ case WL_SHM_FORMAT_XBGR8888:
+ break;
+ case WL_SHM_FORMAT_ARGB8888:
+ case WL_SHM_FORMAT_XRGB8888: { /* ARGB -> ABGR */
+ PhoshWlBuffer *buffer = self->frame->buffer;
+ uint8_t *d = buffer->data;
+ for (int i = 0; i < buffer->height; ++i) {
+ for (int j = 0; j < buffer->width; ++j) {
+ uint32_t *px = (uint32_t *)(d + i * buffer->stride + j * 4);
+ uint8_t a = (*px >> 24) & 0xFF;
+ uint8_t b = (*px >> 16) & 0xFF;
+ uint8_t g = (*px >> 8) & 0xFF;
+ uint8_t r = *px & 0xFF;
+ *px = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ }
+ if (buffer->format == WL_SHM_FORMAT_ARGB8888)
+ buffer->format = WL_SHM_FORMAT_ABGR8888;
+ else
+ buffer->format = WL_SHM_FORMAT_XBGR8888;
+ }
+ break;
+ default:
+ goto error;
+ }
+
+ bytes = phosh_wl_buffer_get_bytes (self->frame->buffer);
+ pixbuf = gdk_pixbuf_new_from_bytes (bytes,
+ GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ self->frame->buffer->width,
+ self->frame->buffer->height,
+ self->frame->buffer->stride);
+ if (self->frame->flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT) {
+ GdkPixbuf *tmp = gdk_pixbuf_flip (pixbuf, FALSE);
+ g_object_unref (pixbuf);
+ pixbuf = tmp;
+ }
+
+ if (self->frame->filename) {
+ file = g_file_new_for_path (self->frame->filename);
+ stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &err);
+ if (!stream) {
+ g_warning ("Failed to save screenshot %s: %s", self->frame->filename, err->message);
+ goto error;
+ }
+
+ gdk_pixbuf_save_to_stream_async (pixbuf,
+ G_OUTPUT_STREAM (stream),
+ "png",
+ NULL,
+ on_save_pixbuf_ready,
+ g_object_ref (self),
+ NULL);
+ } else {
+ PhoshMonitor *monitor = phosh_shell_get_primary_monitor (phosh_shell_get_default ());
+
+ /* The wayland clipboard only works if we have focus so use a fully opaque surface */
+ self->opaque = g_object_new (PHOSH_TYPE_FADER,
+ "monitor", monitor,
+ "style-class", "phosh-fader-screenshot-opaque",
+ "kbd-interactivity", TRUE,
+ NULL);
+ self->frame->pixbuf = g_steal_pointer (&pixbuf);
+ /* FIXME: Would be better to trigger when the opaque window is up and got
+ input focus but all such attempts failed */
+ self->opaque_id = g_timeout_add_seconds (1, (GSourceFunc) on_opaque_timeout, self);
+ g_source_set_name_by_id (self->opaque_id, "[phosh] screenshot opaque");
+
+ gtk_widget_show (GTK_WIDGET (self->opaque));
+ }
+ return;
+
+error:
+ screencopy_done (self, FALSE);
+}
+
+
+static void
+screencopy_frame_handle_failed (void *data,
+ struct zwlr_screencopy_frame_v1 *frame)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (data);
+
+ g_return_if_fail (PHOSH_IS_SCREENSHOT_MANAGER (self));
+
+ g_warning ("Failed to copy output\n");
+ screencopy_done (self, FALSE);
+}
+
+
+static const struct zwlr_screencopy_frame_v1_listener screencopy_frame_listener = {
+ .buffer = screencopy_frame_handle_buffer,
+ .flags = screencopy_frame_handle_flags,
+ .ready = screencopy_frame_handle_ready,
+ .failed = screencopy_frame_handle_failed,
+};
+
+
+/**
+ * build_screenshot_filename:
+ * @pattern: Absolute path or relative name without extension
+ *
+ * Builds an absolute filename based on the given input pattern.
+ * Returns: The target filename or %NULL on errors.
+ */
+static char *
+build_screenshot_filename (const char *pattern)
+{
+ g_autofree char *filename = NULL;
+
+ if (g_path_is_absolute (pattern)) {
+ return g_strdup (pattern);
+ } else {
+ const char *dir = NULL;
+ const char *const *dirs = (const char * []) {
+ g_get_user_special_dir (G_USER_DIRECTORY_PICTURES),
+ g_get_home_dir (),
+ NULL
+ };
+
+ for (int i = 0; i < g_strv_length ((GStrv) dirs); i++) {
+ if (g_file_test (dirs[i], G_FILE_TEST_EXISTS)) {
+ dir = dirs[i];
+ break;
+ }
+ }
+
+ if (!dir)
+ return NULL;
+
+ filename = g_build_filename (dir, pattern, NULL);
+ }
+ if (!g_str_has_suffix (filename, ".png")) {
+ g_autofree gchar *tmp = filename;
+ filename = g_strdup_printf ("%s.png", filename);
+ }
+
+ return g_steal_pointer (&filename);
+}
+
+
+static gboolean
+handle_screenshot (PhoshDBusScreenshot *object,
+ GDBusMethodInvocation *invocation,
+ gboolean arg_include_cursor,
+ gboolean arg_flash,
+ const char *arg_filename)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (object);
+ PhoshWayland *wl = phosh_wayland_get_default ();
+ struct zwlr_screencopy_manager_v1 *wl_scm;
+ PhoshMonitor *monitor;
+ ScreencopyFrame *frame;
+
+ g_debug ("DBus call %s, cursor: %d, flash %d, to %s",
+ __func__, arg_include_cursor, arg_flash, arg_filename);
+
+ g_return_val_if_fail (PHOSH_IS_WAYLAND (wl), FALSE);
+
+ wl_scm = phosh_wayland_get_zwlr_screencopy_manager_v1 (wl);
+ if (!wl_scm) {
+ phosh_dbus_screenshot_complete_screenshot (object, invocation, FALSE, "");
+ return TRUE;
+ }
+
+ if (self->frame) {
+ g_debug ("Screenshot already in progress");
+ phosh_dbus_screenshot_complete_screenshot (object, invocation, FALSE, "");
+ return TRUE;
+ }
+
+ monitor = phosh_shell_get_primary_monitor (phosh_shell_get_default ());
+ frame = g_new0 (ScreencopyFrame, 1);
+
+ frame->frame = zwlr_screencopy_manager_v1_capture_output (
+ self->wl_scm, arg_include_cursor, monitor->wl_output);
+ frame->invocation = invocation;
+ frame->flash = arg_flash;
+ self->frame = frame;
+
+ if (STR_IS_NULL_OR_EMPTY (arg_filename)) {
+ /* Copy to clipboard */
+ frame->filename = NULL;
+ } else {
+ frame->filename = build_screenshot_filename (arg_filename);
+ if (!frame->filename) {
+ screencopy_done (self, FALSE);
+ return TRUE;
+ }
+ }
+
+ zwlr_screencopy_frame_v1_add_listener (frame->frame, &screencopy_frame_listener, self);
+ return TRUE;
+}
+
+
+static void
+phosh_screenshot_manager_screenshot_iface_init (PhoshDBusScreenshotIface *iface)
+{
+ iface->handle_screenshot = handle_screenshot;
+}
+
+
+static void
+on_name_acquired (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (user_data);
+
+ g_return_if_fail (PHOSH_IS_SCREENSHOT_MANAGER (self));
+ g_debug ("Acquired name %s", name);
+}
+
+
+static void
+on_name_lost (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ g_debug ("Lost or failed to acquire name %s", name);
+}
+
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (user_data);
+ g_autoptr (GError) err = NULL;
+
+ if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
+ connection,
+ OBJECT_PATH,
+ &err)) {
+ g_warning ("Failed to export screensaver interface skeleton: %s", err->message);
+ }
+
+}
+
+
+static void
+phosh_screenshot_manager_constructed (GObject *object)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (object);
+ PhoshWayland *wl = phosh_wayland_get_default ();
+
+ G_OBJECT_CLASS (phosh_screenshot_manager_parent_class)->constructed (object);
+
+ self->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+ BUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ self,
+ NULL);
+
+ g_return_if_fail (PHOSH_IS_WAYLAND (wl));
+ self->wl_scm = phosh_wayland_get_zwlr_screencopy_manager_v1 (wl);
+}
+
+
+static void
+phosh_screenshot_manager_dispose (GObject *object)
+{
+ PhoshScreenshotManager *self = PHOSH_SCREENSHOT_MANAGER (object);
+
+ g_clear_handle_id (&self->dbus_name_id, g_bus_unown_name);
+
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_handle_id (&self->fader_id, g_source_remove);
+ g_clear_handle_id (&self->opaque_id, g_source_remove);
+ g_clear_pointer (&self->fader, phosh_cp_widget_destroy);
+
+ G_OBJECT_CLASS (phosh_screenshot_manager_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_screenshot_manager_class_init (PhoshScreenshotManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = phosh_screenshot_manager_constructed;
+ object_class->dispose = phosh_screenshot_manager_dispose;
+}
+
+
+static void
+phosh_screenshot_manager_init (PhoshScreenshotManager *self)
+{
+}
+
+PhoshScreenshotManager *
+phosh_screenshot_manager_new (void)
+{
+ return PHOSH_SCREENSHOT_MANAGER (g_object_new (PHOSH_TYPE_SCREENSHOT_MANAGER, NULL));
+}
diff -Nru phosh-0.8.0/src/screenshot-manager.h phosh-0.13.1/src/screenshot-manager.h
--- phosh-0.8.0/src/screenshot-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/screenshot-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "dbus/phosh-screenshot-dbus.h"
+
+#include
+
+G_BEGIN_DECLS
+
+#define PHOSH_TYPE_SCREENSHOT_MANAGER phosh_screenshot_manager_get_type ()
+
+G_DECLARE_FINAL_TYPE (PhoshScreenshotManager, phosh_screenshot_manager,
+ PHOSH, SCREENSHOT_MANAGER, PhoshDBusScreenshotSkeleton)
+
+PhoshScreenshotManager *phosh_screenshot_manager_new (void);
+
+G_END_DECLS
diff -Nru phosh-0.8.0/src/sensor-proxy-manager.c phosh-0.13.1/src/sensor-proxy-manager.c
--- phosh-0.8.0/src/sensor-proxy-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/sensor-proxy-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -52,27 +52,13 @@
PhoshSensorProxyManager *
-phosh_sensor_proxy_manager_get_default_failable (void)
+phosh_sensor_proxy_manager_new (GError **err)
{
- static PhoshSensorProxyManager *instance;
- GError *err = NULL;
- GInitable *ret;
-
- if (instance == NULL) {
- ret = g_initable_new (PHOSH_TYPE_SENSOR_PROXY_MANAGER, NULL, &err,
- "g-flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
- "g-name", IIO_SENSOR_PROXY_DBUS_NAME,
- "g-bus-type", G_BUS_TYPE_SYSTEM,
- "g-object-path", IIO_SENSOR_PROXY_DBUS_OBJECT,
- "g-interface-name", IIO_SENSOR_PROXY_DBUS_IFACE_NAME,
- NULL);
- if (ret != NULL) {
- instance = PHOSH_SENSOR_PROXY_MANAGER (ret);
- } else {
- g_warning ("Can't connect to iio-sensor-sensor proxy: %s", err->message);
- return NULL;
- }
- g_object_add_weak_pointer (G_OBJECT (instance), (gpointer *)&instance);
- }
- return instance;
+ return g_initable_new (PHOSH_TYPE_SENSOR_PROXY_MANAGER, NULL, err,
+ "g-flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+ "g-name", IIO_SENSOR_PROXY_DBUS_NAME,
+ "g-bus-type", G_BUS_TYPE_SYSTEM,
+ "g-object-path", IIO_SENSOR_PROXY_DBUS_OBJECT,
+ "g-interface-name", IIO_SENSOR_PROXY_DBUS_IFACE_NAME,
+ NULL);
}
diff -Nru phosh-0.8.0/src/sensor-proxy-manager.h phosh-0.13.1/src/sensor-proxy-manager.h
--- phosh-0.8.0/src/sensor-proxy-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/sensor-proxy-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -13,6 +13,6 @@
G_DECLARE_FINAL_TYPE (PhoshSensorProxyManager, phosh_sensor_proxy_manager,
PHOSH, SENSOR_PROXY_MANAGER, PhoshDBusSensorProxyProxy)
-PhoshSensorProxyManager *phosh_sensor_proxy_manager_get_default_failable (void);
+PhoshSensorProxyManager *phosh_sensor_proxy_manager_new (GError **err);
gboolean phosh_sensor_proxy_manager_claim_proximity_sync (PhoshSensorProxyManager *self,
GError **err);
diff -Nru phosh-0.8.0/src/session-manager.c phosh-0.13.1/src/session-manager.c
--- phosh-0.8.0/src/session-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/session-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -9,8 +9,10 @@
#define G_LOG_DOMAIN "phosh-session-manager"
#include "config.h"
+#include "end-session-dialog.h"
#include "session-manager.h"
#include "shell.h"
+#include "util.h"
#include "dbus/gnome-session-dbus.h"
#include "dbus/gnome-session-client-private-dbus.h"
@@ -18,6 +20,8 @@
#define BUS_NAME "org.gnome.SessionManager"
#define OBJECT_PATH "/org/gnome/SessionManager"
+#define END_SESSION_DIALOG_OBJECT_PATH "/org/gnome/SessionManager/EndSessionDialog"
+
#define SESSION_SHUTDOWN_TIMEOUT 15
/**
@@ -36,17 +40,114 @@
};
static GParamSpec *props[PHOSH_SESSION_MANAGER_PROP_LAST_PROP];
+static void phosh_session_manager_end_session_dialog_iface_init (
+ PhoshDBusEndSessionDialogIface *iface);
typedef struct _PhoshSessionManager {
- GObject parent;
+ PhoshDBusEndSessionDialogSkeleton parent;
gboolean active;
PhoshSessionDBusSessionManager *proxy;
+ GCancellable *cancel;
PhoshSessionClientPrivateDBusClientPrivate *priv_proxy;
+
+ PhoshEndSessionDialog *dialog;
+
} PhoshSessionManager;
-G_DEFINE_TYPE (PhoshSessionManager, phosh_session_manager, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (PhoshSessionManager,
+ phosh_session_manager,
+ PHOSH_DBUS_TYPE_END_SESSION_DIALOG_SKELETON,
+ G_IMPLEMENT_INTERFACE (
+ PHOSH_DBUS_TYPE_END_SESSION_DIALOG,
+ phosh_session_manager_end_session_dialog_iface_init))
+
+
+static void
+on_end_session_dialog_closed (PhoshSessionManager *self, PhoshEndSessionDialog *dialog)
+{
+ gint action;
+ gboolean confirmed;
+ PhoshDBusEndSessionDialog *object;
+
+ g_return_if_fail (PHOSH_IS_SESSION_MANAGER (self));
+ g_return_if_fail (PHOSH_IS_END_SESSION_DIALOG (dialog));
+
+ object = PHOSH_DBUS_END_SESSION_DIALOG (self);
+
+ confirmed = phosh_end_session_dialog_get_action_confirmed (dialog);
+ action = phosh_end_session_dialog_get_action (dialog);
+ g_clear_pointer (&self->dialog, phosh_cp_widget_destroy);
+
+ g_debug ("Action %d confirmed: %d", action, confirmed);
+
+ if (!confirmed) {
+ phosh_dbus_end_session_dialog_emit_canceled (object);
+ return;
+ }
+
+ switch (action) {
+ case PHOSH_END_SESSION_ACTION_LOGOUT:
+ phosh_dbus_end_session_dialog_emit_confirmed_logout (object);
+ break;
+ case PHOSH_END_SESSION_ACTION_SHUTDOWN:
+ phosh_dbus_end_session_dialog_emit_confirmed_shutdown (object);
+ break;
+ case PHOSH_END_SESSION_ACTION_REBOOT:
+ phosh_dbus_end_session_dialog_emit_confirmed_reboot (object);
+ break;
+ /* not used by gnome-session */
+ case PHOSH_END_SESSION_ACTION_HIBERNATE:
+ case PHOSH_END_SESSION_ACTION_SUSPEND:
+ case PHOSH_END_SESSION_ACTION_HYBRID_SLEEP:
+ default:
+ g_return_if_reached ();
+ }
+}
+
+
+static gboolean
+handle_end_session_open (PhoshDBusEndSessionDialog *object,
+ GDBusMethodInvocation *invocation,
+ guint arg_type,
+ guint arg_timestamp,
+ guint arg_seconds_to_stay_open,
+ const gchar *const *arg_inhibitor_object_paths)
+{
+ PhoshSessionManager *self = PHOSH_SESSION_MANAGER (object);
+
+ g_debug ("DBus call %s, type: %d, seconds %d",
+ __func__, arg_type, arg_seconds_to_stay_open);
+
+ if (self->dialog != NULL) {
+ g_object_set (self->dialog,
+ "inhibitor-paths", arg_inhibitor_object_paths,
+ NULL);
+ gtk_widget_show (GTK_WIDGET (self->dialog));
+ phosh_dbus_end_session_dialog_complete_open (
+ object, invocation);
+ return TRUE;
+ }
+
+ self->dialog = PHOSH_END_SESSION_DIALOG (phosh_end_session_dialog_new (arg_type,
+ arg_seconds_to_stay_open,
+ arg_inhibitor_object_paths));
+ g_signal_connect_swapped (self->dialog, "closed",
+ G_CALLBACK (on_end_session_dialog_closed), self);
+
+ gtk_widget_show (GTK_WIDGET (self->dialog));
+ phosh_dbus_end_session_dialog_complete_open (object, invocation);
+
+ return TRUE;
+}
+
+
+static void
+phosh_session_manager_end_session_dialog_iface_init (PhoshDBusEndSessionDialogIface *iface)
+{
+ iface->handle_open = handle_end_session_open;
+}
static void
@@ -184,14 +285,12 @@
PhoshSessionManager *self)
{
g_autofree gchar *client_id = NULL;
-
g_autoptr (GError) err = NULL;
if (!phosh_session_dbus_session_manager_call_register_client_finish (proxy, &client_id, res, &err)) {
- g_warning ("Failed to register client: %s", err->message);
- goto out;
+ phosh_async_error_warn (err, "Failed to register client");
+ return;
}
-
g_debug ("Registered client at '%s'", client_id);
phosh_session_client_private_dbus_client_private_proxy_new_for_bus (
@@ -202,9 +301,6 @@
NULL,
(GAsyncReadyCallback)on_client_private_proxy_new_for_bus_finish,
g_object_ref (self));
-
-out:
- g_object_unref (self);
}
@@ -283,6 +379,13 @@
{
PhoshSessionManager *self = PHOSH_SESSION_MANAGER (object);
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
+ if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self)))
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
+
+ g_clear_pointer (&self->dialog, phosh_cp_widget_destroy);
g_clear_object (&self->priv_proxy);
g_clear_object (&self->proxy);
@@ -318,6 +421,7 @@
static void
phosh_session_manager_init (PhoshSessionManager *self)
{
+ self->cancel = g_cancellable_new ();
}
@@ -348,9 +452,9 @@
phosh_session_dbus_session_manager_call_register_client (self->proxy,
app_id,
startup_id ? startup_id : "",
- NULL,
+ self->cancel,
(GAsyncReadyCallback) on_client_registered,
- g_object_ref (self));
+ self);
}
void
@@ -391,3 +495,15 @@
(GAsyncReadyCallback)on_reboot_finished,
g_object_ref (self));
}
+
+void
+phosh_session_manager_export_end_session (PhoshSessionManager *self,
+ GDBusConnection *connection)
+{
+ g_return_if_fail (PHOSH_IS_SESSION_MANAGER (self));
+
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
+ connection,
+ END_SESSION_DIALOG_OBJECT_PATH,
+ NULL);
+}
diff -Nru phosh-0.8.0/src/session-manager.h phosh-0.13.1/src/session-manager.h
--- phosh-0.8.0/src/session-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/session-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,14 +6,17 @@
#pragma once
+#include "dbus/phosh-end-session-dialog-dbus.h"
+
#include
+#include
G_BEGIN_DECLS
#define PHOSH_TYPE_SESSION_MANAGER phosh_session_manager_get_type ()
G_DECLARE_FINAL_TYPE (PhoshSessionManager, phosh_session_manager,
- PHOSH, SESSION_MANAGER, GObject)
+ PHOSH, SESSION_MANAGER, PhoshDBusEndSessionDialogSkeleton)
PhoshSessionManager *phosh_session_manager_new (void);
gboolean phosh_session_manager_is_active (PhoshSessionManager *self);
@@ -22,4 +25,7 @@
void phosh_session_manager_shutdown (PhoshSessionManager *self);
void phosh_session_manager_reboot (PhoshSessionManager *self);
+void phosh_session_manager_export_end_session (PhoshSessionManager *self,
+ GDBusConnection *connection);
+
G_END_DECLS
diff -Nru phosh-0.8.0/src/settings/brightness.c phosh-0.13.1/src/settings/brightness.c
--- phosh-0.8.0/src/settings/brightness.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/settings/brightness.c 2021-08-31 09:15:52.000000000 +0000
@@ -12,9 +12,11 @@
#include
#include "settings/brightness.h"
+#include "util.h"
GDBusProxy *brightness_proxy;
+GCancellable *gsd_power_cancel;
gboolean setting_brightness;
@@ -51,8 +53,8 @@
int value;
brightness_proxy = g_dbus_proxy_new_finish (res, &err);
- if (!brightness_proxy || err) {
- g_warning ("Could not connect to brightness service %s", err->message);
+ if (brightness_proxy == NULL) {
+ phosh_async_error_warn (err, "Could not connect to brightness service");
return;
}
@@ -83,17 +85,18 @@
session_con = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &err);
if (err != NULL) {
- g_error ("Can not connect to session bus: %s", err->message);
+ g_warning ("Can not connect to session bus: %s", err->message);
return;
}
+ gsd_power_cancel = g_cancellable_new ();
g_dbus_proxy_new (session_con,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.gnome.SettingsDaemon.Power",
"/org/gnome/SettingsDaemon/Power",
"org.gnome.SettingsDaemon.Power.Screen",
- NULL,
+ gsd_power_cancel,
(GAsyncReadyCallback)brightness_init_cb,
scale);
}
@@ -148,5 +151,7 @@
void
brightness_dispose (void)
{
- g_clear_pointer (&brightness_proxy, g_object_unref);
+ g_cancellable_cancel (gsd_power_cancel);
+ g_clear_object (&gsd_power_cancel);
+ g_clear_object (&brightness_proxy);
}
diff -Nru phosh-0.8.0/src/settings/meson.build phosh-0.13.1/src/settings/meson.build
--- phosh-0.8.0/src/settings/meson.build 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/settings/meson.build 2021-08-31 09:15:52.000000000 +0000
@@ -1,4 +1,4 @@
-phosh_settings_widgets_sources = [
- 'settings/brightness.c',
- 'settings/gvc-channel-bar.c',
-]
+phosh_settings_widgets_sources = files(
+ 'brightness.c',
+ 'gvc-channel-bar.c',
+)
diff -Nru phosh-0.8.0/src/settings.c phosh-0.13.1/src/settings.c
--- phosh-0.8.0/src/settings.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/settings.c 2021-08-31 09:15:52.000000000 +0000
@@ -10,8 +10,6 @@
#include
-#include "bt-info.h"
-#include "docked-info.h"
#include "mode-manager.h"
#include "shell.h"
#include "settings.h"
@@ -19,13 +17,11 @@
#include "settings/brightness.h"
#include "settings/gvc-channel-bar.h"
#include "torch-info.h"
+#include "torch-manager.h"
#include "wwan/phosh-wwan-mm.h"
-#include "rotateinfo.h"
-#include "feedbackinfo.h"
-#include "feedback-manager.h"
#include "notifications/notify-manager.h"
#include "notifications/notification-frame.h"
-#include "media-player.h"
+#include "rotateinfo.h"
#include
#include "gvc-mixer-control.h"
@@ -35,9 +31,6 @@
#include
-#define LIBFEEDBACK_USE_UNSTABLE_API
-#include
-
/**
* SECTION:settings
* @short_description: The settings menu
@@ -67,8 +60,12 @@
/* Notifications */
GtkWidget *list_notifications;
- GtkWidget *sw_notifications;
- LfbEvent *notify_event;
+ GtkWidget *box_notifications;
+
+ /* Torch */
+ PhoshTorchManager *torch_manager;
+ GtkWidget *scale_torch;
+ gboolean setting_torch;
} PhoshSettings;
@@ -76,6 +73,13 @@
static void
+close_settings_menu (PhoshSettings *self)
+{
+ g_signal_emit (self, signals[SETTING_DONE], 0);
+ phosh_trigger_feedback ("button-pressed");
+}
+
+static void
brightness_value_changed_cb (GtkScale *scale_brightness, gpointer *unused)
{
int brightness;
@@ -88,14 +92,56 @@
rotation_setting_clicked_cb (PhoshSettings *self)
{
PhoshShell *shell = phosh_shell_get_default ();
+ PhoshRotationManager *rotation_manager;
+ PhoshRotationManagerMode mode;
PhoshMonitorTransform transform;
+ gboolean locked;
g_return_if_fail (PHOSH_IS_SETTINGS (self));
- transform = phosh_shell_get_transform (shell);
- phosh_shell_set_transform (shell, transform == PHOSH_MONITOR_TRANSFORM_NORMAL
- ? PHOSH_MONITOR_TRANSFORM_270
- : PHOSH_MONITOR_TRANSFORM_NORMAL);
- g_signal_emit (self, signals[SETTING_DONE], 0);
+
+ rotation_manager = phosh_shell_get_rotation_manager (shell);
+ g_return_if_fail (rotation_manager);
+ mode = phosh_rotation_manager_get_mode (PHOSH_ROTATION_MANAGER (rotation_manager));
+
+ switch (mode) {
+ case PHOSH_ROTATION_MANAGER_MODE_OFF:
+ transform = phosh_rotation_manager_get_transform (rotation_manager) ?
+ PHOSH_MONITOR_TRANSFORM_NORMAL : PHOSH_MONITOR_TRANSFORM_270;
+ phosh_rotation_manager_set_transform (rotation_manager, transform);
+ g_signal_emit (self, signals[SETTING_DONE], 0);
+ break;
+ case PHOSH_ROTATION_MANAGER_MODE_SENSOR:
+ locked = phosh_rotation_manager_get_orientation_locked (rotation_manager);
+ phosh_rotation_manager_set_orientation_locked (rotation_manager, !locked);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+rotation_setting_long_pressed_cb (PhoshSettings *self)
+{
+ PhoshShell *shell = phosh_shell_get_default ();
+ PhoshRotateInfoMode mode;
+ PhoshRotationManager *rotation_manager;
+
+ rotation_manager = phosh_shell_get_rotation_manager (shell);
+ g_return_if_fail (rotation_manager);
+
+ mode = phosh_rotation_manager_get_mode (rotation_manager);
+ switch (mode) {
+ case PHOSH_ROTATION_MANAGER_MODE_OFF:
+ mode = PHOSH_ROTATION_MANAGER_MODE_SENSOR;
+ break;
+ case PHOSH_ROTATION_MANAGER_MODE_SENSOR:
+ mode = PHOSH_ROTATION_MANAGER_MODE_OFF;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ g_debug ("Rotation manager mode: %d", mode);
+ phosh_rotation_manager_set_mode (rotation_manager, mode);
}
static void
@@ -108,43 +154,90 @@
g_return_if_fail (PHOSH_IS_SHELL (shell));
manager = phosh_shell_get_feedback_manager (shell);
g_return_if_fail (PHOSH_IS_FEEDBACK_MANAGER (manager));
- manager = phosh_shell_get_feedback_manager (shell);
phosh_feedback_manager_toggle (manager);
}
static void
wifi_setting_clicked_cb (PhoshSettings *self)
{
+ PhoshShell *shell = phosh_shell_get_default ();
+ PhoshWifiManager *manager;
+ gboolean enabled;
+
+ g_return_if_fail (PHOSH_IS_SETTINGS (self));
+
+ manager = phosh_shell_get_wifi_manager (shell);
+ g_return_if_fail (PHOSH_IS_WIFI_MANAGER (manager));
+
+ enabled = phosh_wifi_manager_get_enabled (manager);
+ phosh_wifi_manager_set_enabled (manager, !enabled);
+}
+
+static void
+wifi_setting_long_pressed_cb (PhoshSettings *self)
+{
phosh_quick_setting_open_settings_panel ("wifi");
- g_signal_emit (self, signals[SETTING_DONE], 0);
+ close_settings_menu (self);
}
static void
wwan_setting_clicked_cb (PhoshSettings *self)
{
+ PhoshShell *shell = phosh_shell_get_default ();
+ PhoshWWan *wwan;
+ gboolean enabled;
+
+ g_return_if_fail (PHOSH_IS_SETTINGS (self));
+
+ wwan = phosh_shell_get_wwan (shell);
+ g_return_if_fail (PHOSH_IS_WWAN (wwan));
+
+ enabled = phosh_wwan_is_enabled (wwan);
+ phosh_wwan_set_enabled (wwan, !enabled);
+}
+
+static void
+wwan_setting_long_pressed_cb (PhoshSettings *self)
+{
phosh_quick_setting_open_settings_panel ("wwan");
- g_signal_emit (self, signals[SETTING_DONE], 0);
+ close_settings_menu (self);
}
static void
bt_setting_clicked_cb (PhoshSettings *self)
{
+ PhoshShell *shell = phosh_shell_get_default ();
+ PhoshBtManager *manager;
+ gboolean enabled;
+
+ g_return_if_fail (PHOSH_IS_SETTINGS (self));
+
+ manager = phosh_shell_get_bt_manager (shell);
+ g_return_if_fail (PHOSH_IS_BT_MANAGER (manager));
+
+ enabled = phosh_bt_manager_get_enabled (manager);
+ phosh_bt_manager_set_enabled (manager, !enabled);
+}
+
+static void
+bt_setting_long_pressed_cb (PhoshSettings *self)
+{
phosh_quick_setting_open_settings_panel ("bluetooth");
- g_signal_emit (self, signals[SETTING_DONE], 0);
+ close_settings_menu (self);
}
static void
feedback_setting_long_pressed_cb (PhoshSettings *self)
{
phosh_quick_setting_open_settings_panel ("notifications");
- g_signal_emit (self, signals[SETTING_DONE], 0);
+ close_settings_menu (self);
}
static void
battery_setting_clicked_cb (PhoshSettings *self)
{
phosh_quick_setting_open_settings_panel ("power");
- g_signal_emit (self, signals[SETTING_DONE], 0);
+ close_settings_menu (self);
}
@@ -178,6 +271,13 @@
phosh_docked_manager_set_enabled (manager, !enabled);
}
+static void
+docked_setting_long_pressed_cb (PhoshSettings *self)
+{
+ phosh_quick_setting_open_settings_panel ("display");
+ close_settings_menu (self);
+}
+
static void
update_output_vol_bar (PhoshSettings *self)
@@ -229,18 +329,20 @@
if (self->output_stream)
g_signal_handlers_disconnect_by_data (self->output_stream, self);
- self->output_stream = gvc_mixer_control_get_default_sink (self->mixer_control);
+ g_set_object (&self->output_stream,
+ gvc_mixer_control_get_default_sink (self->mixer_control));
g_return_if_fail (self->output_stream);
- g_signal_connect (self->output_stream,
- "notify::volume",
- G_CALLBACK (output_stream_notify_volume_cb),
- self);
+ g_signal_connect_object (self->output_stream,
+ "notify::volume",
+ G_CALLBACK (output_stream_notify_volume_cb),
+ self, 0);
+
+ g_signal_connect_object (self->output_stream,
+ "notify::is-muted",
+ G_CALLBACK (output_stream_notify_is_muted_cb),
+ self, 0);
- g_signal_connect (self->output_stream,
- "notify::is-muted",
- G_CALLBACK (output_stream_notify_is_muted_cb),
- self);
update_output_vol_bar (self);
}
@@ -253,7 +355,7 @@
g_autofree char *name = NULL;
if (!self->output_stream)
- self->output_stream = gvc_mixer_control_get_default_sink (self->mixer_control);
+ self->output_stream = g_object_ref (gvc_mixer_control_get_default_sink (self->mixer_control));
volume = gtk_adjustment_get_value (adjustment);
rounded = round (volume);
@@ -287,6 +389,18 @@
g_signal_emit (self, signals[SETTING_DONE], 0);
}
+
+static void
+on_notifications_clear_all_clicked (PhoshSettings *self)
+{
+ PhoshNotifyManager *manager;
+
+ manager = phosh_notify_manager_get_default ();
+ phosh_notify_manager_close_all_notifications (manager, PHOSH_NOTIFICATION_REASON_DISMISSED);
+ g_signal_emit (self, signals[SETTING_DONE], 0);
+}
+
+
static GtkWidget *
create_notification_row (gpointer item, gpointer data)
{
@@ -298,7 +412,7 @@
"visible", TRUE,
NULL);
- frame = phosh_notification_frame_new ();
+ frame = phosh_notification_frame_new (TRUE);
phosh_notification_frame_bind_model (PHOSH_NOTIFICATION_FRAME (frame), item);
gtk_widget_show (frame);
@@ -310,19 +424,46 @@
static void
-end_notify_feedback (PhoshSettings *self)
+on_torch_scale_value_changed (PhoshSettings *self, GtkScale *scale_torch)
{
- if (lfb_event_get_state (self->notify_event) == LFB_EVENT_STATE_RUNNING)
- lfb_event_end_feedback_async (self->notify_event, NULL, NULL, NULL);
+ double value;
+
+ g_return_if_fail (PHOSH_IS_SETTINGS (self));
+ g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self->torch_manager));
+
+ /* Only react to scale changes when torch is enabled */
+ if (!phosh_torch_manager_get_enabled (self->torch_manager))
+ return;
+
+ self->setting_torch = TRUE;
+ value = gtk_range_get_value (GTK_RANGE (self->scale_torch));
+ g_debug ("Setting torch brightness to %.2f", value);
+ phosh_torch_manager_set_scaled_brightness (self->torch_manager, value / 100.0);
}
static void
-on_notifcation_items_changed (PhoshSettings *self,
- guint position,
- guint removed,
- guint added,
- GListModel *list)
+on_torch_brightness_changed (PhoshSettings *self, GParamSpec *pspec, PhoshTorchManager *manager)
+{
+ g_return_if_fail (PHOSH_IS_SETTINGS (self));
+ g_return_if_fail (PHOSH_IS_TORCH_MANAGER (manager));
+
+ if (self->setting_torch) {
+ self->setting_torch = FALSE;
+ return;
+ }
+
+ gtk_range_set_value (GTK_RANGE (self->scale_torch),
+ 100.0 * phosh_torch_manager_get_scaled_brightness (self->torch_manager));
+}
+
+
+static void
+on_notifcation_frames_items_changed (PhoshSettings *self,
+ guint position,
+ guint removed,
+ guint added,
+ GListModel *list)
{
gboolean is_empty;
@@ -332,14 +473,9 @@
is_empty = !g_list_model_get_n_items (list);
g_debug("Notification list empty: %d", is_empty);
- gtk_widget_set_visible (GTK_WIDGET (self->sw_notifications), !is_empty);
- if (is_empty) {
+ gtk_widget_set_visible (GTK_WIDGET (self->box_notifications), !is_empty);
+ if (is_empty)
g_signal_emit (self, signals[SETTING_DONE], 0);
- end_notify_feedback (self);
- } else if (phosh_shell_get_locked (phosh_shell_get_default ())) {
- if (lfb_event_get_state (self->notify_event) != LFB_EVENT_STATE_RUNNING)
- lfb_event_trigger_feedback_async (self->notify_event, NULL, NULL, NULL);
- }
}
@@ -358,6 +494,24 @@
static void
+setup_torch (PhoshSettings *self)
+{
+ PhoshShell *shell = phosh_shell_get_default ();
+
+ self->torch_manager = g_object_ref(phosh_shell_get_torch_manager (shell));
+
+ gtk_range_set_range (GTK_RANGE (self->scale_torch), 40, 100);
+ gtk_range_set_value (GTK_RANGE (self->scale_torch),
+ phosh_torch_manager_get_scaled_brightness (self->torch_manager) * 100.0);
+ g_signal_connect_object (self->torch_manager,
+ "notify::brightness",
+ G_CALLBACK(on_torch_brightness_changed),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+
+static void
setup_volume_bar (PhoshSettings *self)
{
GtkAdjustment *adj;
@@ -393,6 +547,7 @@
setup_brightness_range (self);
setup_volume_bar (self);
+ setup_torch (self);
g_signal_connect (self->quick_settings,
"child-activated",
@@ -407,11 +562,11 @@
NULL);
g_signal_connect_object (phosh_notify_manager_get_list (manager),
"items-changed",
- G_CALLBACK (on_notifcation_items_changed),
+ G_CALLBACK (on_notifcation_frames_items_changed),
self,
G_CONNECT_SWAPPED);
- on_notifcation_items_changed (self, -1, -1, -1,
- G_LIST_MODEL (phosh_notify_manager_get_list (manager)));
+ on_notifcation_frames_items_changed (self, -1, -1, -1,
+ G_LIST_MODEL (phosh_notify_manager_get_list (manager)));
G_OBJECT_CLASS (phosh_settings_parent_class)->constructed (object);
}
@@ -424,10 +579,9 @@
brightness_dispose ();
- if (self->notify_event) {
- end_notify_feedback (self);
- g_clear_object (&self->notify_event);
- }
+ g_clear_object (&self->output_stream);
+
+ g_clear_object (&self->torch_manager);
G_OBJECT_CLASS (phosh_settings_parent_class)->dispose (object);
}
@@ -462,38 +616,36 @@
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
NULL, G_TYPE_NONE, 0);
- g_type_ensure (PHOSH_TYPE_BT_INFO);
- g_type_ensure (PHOSH_TYPE_DOCKED_INFO);
- g_type_ensure (PHOSH_TYPE_FEEDBACK_INFO);
- g_type_ensure (PHOSH_TYPE_MEDIA_PLAYER);
- g_type_ensure (PHOSH_TYPE_QUICK_SETTING);
- g_type_ensure (PHOSH_TYPE_ROTATE_INFO);
- g_type_ensure (PHOSH_TYPE_TORCH_INFO);
-
gtk_widget_class_bind_template_child (widget_class, PhoshSettings, box_settings);
gtk_widget_class_bind_template_child (widget_class, PhoshSettings, list_notifications);
gtk_widget_class_bind_template_child (widget_class, PhoshSettings, quick_settings);
gtk_widget_class_bind_template_child (widget_class, PhoshSettings, scale_brightness);
- gtk_widget_class_bind_template_child (widget_class, PhoshSettings, sw_notifications);
+ gtk_widget_class_bind_template_child (widget_class, PhoshSettings, scale_torch);
+ gtk_widget_class_bind_template_child (widget_class, PhoshSettings, box_notifications);
gtk_widget_class_bind_template_callback (widget_class, battery_setting_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, bt_setting_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, bt_setting_long_pressed_cb);
gtk_widget_class_bind_template_callback (widget_class, docked_setting_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, docked_setting_long_pressed_cb);
gtk_widget_class_bind_template_callback (widget_class, feedback_setting_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, feedback_setting_long_pressed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_media_player_raised);
gtk_widget_class_bind_template_callback (widget_class, rotation_setting_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, rotation_setting_long_pressed_cb);
gtk_widget_class_bind_template_callback (widget_class, torch_setting_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, wifi_setting_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, wifi_setting_long_pressed_cb);
gtk_widget_class_bind_template_callback (widget_class, wwan_setting_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, wwan_setting_long_pressed_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_torch_scale_value_changed);
+ gtk_widget_class_bind_template_callback (widget_class, on_notifications_clear_all_clicked);
}
static void
phosh_settings_init (PhoshSettings *self)
{
- self->notify_event = lfb_event_new ("message-missed-notification");
-
gtk_widget_init_template (GTK_WIDGET (self));
}
diff -Nru phosh-0.8.0/src/shell.c phosh-0.13.1/src/shell.c
--- phosh-0.8.0/src/shell.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/shell.c 2021-08-31 09:15:52.000000000 +0000
@@ -25,34 +25,50 @@
#include "config.h"
#include "shell.h"
-
#include "batteryinfo.h"
#include "background-manager.h"
+#include "bt-info.h"
#include "bt-manager.h"
+#include "connectivity-info.h"
+#include "calls-manager.h"
+#include "docked-info.h"
#include "docked-manager.h"
#include "fader.h"
+#include "feedbackinfo.h"
#include "feedback-manager.h"
#include "gnome-shell-manager.h"
+#include "gtk-mount-manager.h"
+#include "hks-info.h"
#include "home.h"
#include "idle-manager.h"
#include "keyboard-events.h"
+#include "location-info.h"
+#include "location-manager.h"
#include "lockscreen-manager.h"
+#include "media-player.h"
#include "mode-manager.h"
#include "monitor-manager.h"
#include "monitor/monitor.h"
#include "mount-manager.h"
+#include "settings.h"
+#include "system-modal-dialog.h"
#include "notifications/notify-manager.h"
#include "notifications/notification-banner.h"
#include "osk-manager.h"
-#include "panel.h"
#include "phosh-wayland.h"
#include "polkit-auth-agent.h"
#include "proximity.h"
+#include "quick-setting.h"
+#include "rotateinfo.h"
+#include "rotation-manager.h"
#include "sensor-proxy-manager.h"
#include "screen-saver-manager.h"
+#include "screenshot-manager.h"
#include "session-manager.h"
#include "system-prompter.h"
+#include "top-panel.h"
#include "torch-manager.h"
+#include "torch-info.h"
#include "util.h"
#include "wifiinfo.h"
#include "wwaninfo.h"
@@ -66,19 +82,26 @@
* @Title: PhoshShell
*
* #PhoshShell is responsible for instantiating the GUI
- * parts of the shell#PhoshPanel, #PhoshHome,… and the managers that
+ * parts of the shell#PhoshTopPanel, #PhoshHome,… and the managers that
* interface with DBus #PhoshMonitorManager, #PhoshFeedbackManager, …
* and coordinates between them.
*/
enum {
- PHOSH_SHELL_PROP_0,
- PHOSH_SHELL_PROP_TRANSFORM,
- PHOSH_SHELL_PROP_LOCKED,
- PHOSH_SHELL_PROP_PRIMARY_MONITOR,
- PHOSH_SHELL_PROP_LAST_PROP
+ PROP_0,
+ PROP_LOCKED,
+ PROP_BUILTIN_MONITOR,
+ PROP_PRIMARY_MONITOR,
+ PROP_SHELL_STATE,
+ PROP_LAST_PROP
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+enum {
+ READY,
+ N_SIGNALS
};
-static GParamSpec *props[PHOSH_SHELL_PROP_LAST_PROP];
+static guint signals[N_SIGNALS] = { 0 };
typedef struct
{
@@ -90,6 +113,7 @@
PhoshSessionManager *session_manager;
PhoshBackgroundManager *background_manager;
+ PhoshCallsManager *calls_manager;
PhoshMonitor *primary_monitor;
PhoshMonitor *builtin_monitor;
PhoshMonitorManager *monitor_manager;
@@ -100,6 +124,7 @@
PhoshWifiManager *wifi_manager;
PhoshPolkitAuthAgent *polkit_auth_agent;
PhoshScreenSaverManager *screen_saver_manager;
+ PhoshScreenshotManager *screenshot_manager;
PhoshNotifyManager *notify_manager;
PhoshFeedbackManager *feedback_manager;
PhoshBtManager *bt_manager;
@@ -108,19 +133,26 @@
PhoshTorchManager *torch_manager;
PhoshModeManager *mode_manager;
PhoshDockedManager *docked_manager;
+ PhoshGtkMountManager *gtk_mount_manager;
+ PhoshHksManager *hks_manager;
PhoshKeyboardEvents *keyboard_events;
+ PhoshLocationManager *location_manager;
PhoshGnomeShellManager *gnome_shell_manager;
/* sensors */
PhoshSensorProxyManager *sensor_proxy_manager;
PhoshProximity *proximity;
+ PhoshRotationManager *rotation_manager;
gboolean startup_finished;
- PhoshMonitorTransform transform; /* current rotation of primary monitor */
/* Mirrors PhoshLockscreenManager's locked property */
gboolean locked;
+ PhoshShellStateFlags shell_state;
+
+ char *theme_name;
+ GtkCssProvider *css_provider;
} PhoshShellPrivate;
@@ -133,63 +165,16 @@
static void
-settings_activated_cb (PhoshShell *self,
- PhoshPanel *window)
+settings_activated_cb (PhoshShell *self,
+ PhoshTopPanel *window)
{
PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
- g_return_if_fail (PHOSH_IS_PANEL (priv->panel));
- phosh_panel_toggle_fold (PHOSH_PANEL(priv->panel));
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (priv->panel));
+ phosh_top_panel_toggle_fold (PHOSH_TOP_PANEL(priv->panel));
}
-void
-phosh_shell_lock (PhoshShell *self)
-{
- phosh_shell_set_locked (self, TRUE);
-}
-
-
-void
-phosh_shell_unlock (PhoshShell *self)
-{
- phosh_shell_set_locked (self, FALSE);
-}
-
-/**
- * phosh_shell_get_locked:
- * @self: The #PhoshShell singleton
- *
- * Returns: %TRUE if the shell is currently locked, otherwise %FALSE.
- */
-gboolean
-phosh_shell_get_locked (PhoshShell *self)
-{
- PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
-
- return priv->locked;
-}
-
-/**
- * phosh_shell_set_locked:
- * @self: The #PhoshShell singleton
- * @locked: %TRUE to lock the shell
- *
- * Lock the shell. We proxy to lockscreen-manager to avoid
- * that other parts of the shell need to care about this
- * abstraction.
- */
-void
-phosh_shell_set_locked (PhoshShell *self, gboolean locked)
-{
- PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
-
- if (locked == priv->locked)
- return;
-
- phosh_lockscreen_manager_set_locked (priv->lockscreen_manager, locked);
-}
-
static void
on_home_state_changed (PhoshShell *self, GParamSpec *pspec, PhoshHome *home)
{
@@ -203,9 +188,10 @@
g_object_get (priv->home, "state", &state, NULL);
if (state == PHOSH_HOME_STATE_UNFOLDED) {
- phosh_panel_fold (PHOSH_PANEL (priv->panel));
+ phosh_top_panel_fold (PHOSH_TOP_PANEL (priv->panel));
phosh_osk_manager_set_visible (priv->osk_manager, FALSE);
}
+ phosh_shell_set_state (self, PHOSH_STATE_OVERVIEW, state == PHOSH_HOME_STATE_UNFOLDED);
}
@@ -215,11 +201,12 @@
PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
PhoshMonitor *monitor;
PhoshWayland *wl = phosh_wayland_get_default ();
+ PhoshAppGrid *app_grid;
monitor = phosh_shell_get_primary_monitor (self);
g_return_if_fail (monitor);
- priv->panel = PHOSH_LAYER_SURFACE(phosh_panel_new (phosh_wayland_get_zwlr_layer_shell_v1(wl),
+ priv->panel = PHOSH_LAYER_SURFACE(phosh_top_panel_new (phosh_wayland_get_zwlr_layer_shell_v1(wl),
monitor->wl_output));
gtk_widget_show (GTK_WIDGET (priv->panel));
@@ -238,6 +225,13 @@
"notify::state",
G_CALLBACK(on_home_state_changed),
self);
+
+ app_grid = phosh_overview_get_app_grid (phosh_home_get_overview (PHOSH_HOME (priv->home)));
+ g_object_bind_property (priv->docked_manager,
+ "enabled",
+ app_grid,
+ "filter-adaptive",
+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
}
@@ -251,25 +245,38 @@
}
+/* Select proper style sheet in case of high contrast */
static void
-css_setup (PhoshShell *self)
+on_gtk_theme_name_changed (PhoshShell *self, GParamSpec *pspec, GtkSettings *settings)
{
- GtkCssProvider *provider;
- GFile *file;
- GError *error = NULL;
-
- provider = gtk_css_provider_new ();
- file = g_file_new_for_uri ("resource:///sm/puri/phosh/style.css");
-
- if (!gtk_css_provider_load_from_file (provider, file, &error)) {
- g_warning ("Failed to load CSS file: %s", error->message);
- g_clear_error (&error);
- g_object_unref (file);
+ const char *style;
+ g_autofree char *name = NULL;
+ PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
+ g_autoptr (GtkCssProvider) provider = gtk_css_provider_new ();
+
+ g_object_get (settings, "gtk-theme-name", &name, NULL);
+
+ if (g_strcmp0 (priv->theme_name, name) == 0)
return;
+
+ priv->theme_name = g_steal_pointer (&name);
+ g_debug ("GTK theme: %s", priv->theme_name);
+
+ if (priv->css_provider) {
+ gtk_style_context_remove_provider_for_screen(gdk_screen_get_default (),
+ GTK_STYLE_PROVIDER (priv->css_provider));
}
+
+ if (g_strcmp0 (priv->theme_name, "HighContrast") == 0)
+ style = "/sm/puri/phosh/stylesheet/adwaita-hc-light.css";
+ else
+ style = "/sm/puri/phosh/stylesheet/adwaita-dark.css";
+
+ gtk_css_provider_load_from_resource (provider, style);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
- GTK_STYLE_PROVIDER (provider), 600);
- g_object_unref (file);
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ g_set_object (&priv->css_provider, provider);
}
@@ -283,10 +290,11 @@
PhoshShellPrivate *priv = phosh_shell_get_instance_private(self);
switch (property_id) {
- case PHOSH_SHELL_PROP_LOCKED:
+ case PROP_LOCKED:
priv->locked = g_value_get_boolean (value);
+ phosh_shell_set_state (self, PHOSH_STATE_LOCKED, priv->locked);
break;
- case PHOSH_SHELL_PROP_PRIMARY_MONITOR:
+ case PROP_PRIMARY_MONITOR:
phosh_shell_set_primary_monitor (self, g_value_get_object (value));
break;
default:
@@ -306,15 +314,18 @@
PhoshShellPrivate *priv = phosh_shell_get_instance_private(self);
switch (property_id) {
- case PHOSH_SHELL_PROP_TRANSFORM:
- g_value_set_enum (value, phosh_monitor_get_transform(priv->primary_monitor));
- break;
- case PHOSH_SHELL_PROP_LOCKED:
+ case PROP_LOCKED:
g_value_set_boolean (value, priv->locked);
break;
- case PHOSH_SHELL_PROP_PRIMARY_MONITOR:
+ case PROP_BUILTIN_MONITOR:
+ g_value_set_object (value, phosh_shell_get_builtin_monitor (self));
+ break;
+ case PROP_PRIMARY_MONITOR:
g_value_set_object (value, phosh_shell_get_primary_monitor (self));
break;
+ case PROP_SHELL_STATE:
+ g_value_set_flags (value, priv->shell_state);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -328,20 +339,17 @@
PhoshShell *self = PHOSH_SHELL (object);
PhoshShellPrivate *priv = phosh_shell_get_instance_private(self);
- if (priv->sensor_proxy_manager) {
- phosh_dbus_sensor_proxy_call_release_accelerometer_sync (
- PHOSH_DBUS_SENSOR_PROXY(priv->sensor_proxy_manager),
- NULL, NULL);
- g_clear_object (&priv->sensor_proxy_manager);
- }
-
panels_dispose (self);
g_clear_pointer (&priv->faders, g_ptr_array_unref);
g_clear_object (&priv->notification_banner);
- g_clear_object (&priv->keyboard_events);
/* dispose managers in opposite order of declaration */
+ g_clear_object (&priv->screenshot_manager);
+ g_clear_object (&priv->calls_manager);
+ g_clear_object (&priv->location_manager);
+ g_clear_object (&priv->hks_manager);
+ g_clear_object (&priv->gtk_mount_manager);
g_clear_object (&priv->docked_manager);
g_clear_object (&priv->mode_manager);
g_clear_object (&priv->torch_manager);
@@ -362,13 +370,19 @@
g_clear_object (&priv->builtin_monitor);
g_clear_object (&priv->primary_monitor);
g_clear_object (&priv->background_manager);
+ g_clear_object (&priv->keyboard_events);
/* sensors */
g_clear_object (&priv->proximity);
+ g_clear_object (&priv->rotation_manager);
g_clear_object (&priv->sensor_proxy_manager);
+
phosh_system_prompter_unregister ();
g_clear_object (&priv->session_manager);
+ g_clear_pointer (&priv->theme_name, g_free);
+ g_clear_object (&priv->css_provider);
+
G_OBJECT_CLASS (phosh_shell_parent_class)->dispose (object);
}
@@ -421,7 +435,7 @@
}
if (phosh_notify_manager_get_show_notification_banner (manager, notification) &&
- phosh_panel_get_state (PHOSH_PANEL (priv->panel)) == PHOSH_PANEL_STATE_FOLDED &&
+ phosh_top_panel_get_state (PHOSH_TOP_PANEL (priv->panel)) == PHOSH_TOP_PANEL_STATE_FOLDED &&
!priv->locked) {
g_set_weak_pointer (&priv->notification_banner,
phosh_notification_banner_new (notification));
@@ -450,11 +464,16 @@
static gboolean
setup_idle_cb (PhoshShell *self)
{
+ g_autoptr (GError) err = NULL;
PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
priv->session_manager = phosh_session_manager_new ();
priv->mode_manager = phosh_mode_manager_new ();
+ priv->sensor_proxy_manager = phosh_sensor_proxy_manager_new (&err);
+ if (!priv->sensor_proxy_manager)
+ g_message ("Failed to connect to sensor-proxy: %s", err->message);
+
panels_create (self);
/* Create background after panel since it needs the panel's size */
priv->background_manager = phosh_background_manager_new ();
@@ -483,24 +502,27 @@
self,
G_CONNECT_SWAPPED);
- priv->sensor_proxy_manager = phosh_sensor_proxy_manager_get_default_failable ();
+ phosh_shell_get_location_manager (self);
if (priv->sensor_proxy_manager) {
priv->proximity = phosh_proximity_new (priv->sensor_proxy_manager,
- priv->lockscreen_manager);
- /* TODO: accelerometer */
+ priv->calls_manager);
+ phosh_monitor_manager_set_sensor_proxy_manager (priv->monitor_manager,
+ priv->sensor_proxy_manager);
}
+
priv->mount_manager = phosh_mount_manager_new ();
+ priv->gtk_mount_manager = phosh_gtk_mount_manager_new ();
phosh_session_manager_register (priv->session_manager,
PHOSH_APP_ID,
g_getenv ("DESKTOP_AUTOSTART_ID"));
g_unsetenv ("DESKTOP_AUTOSTART_ID");
- /* If we start rotated, fix this up */
- if (phosh_shell_get_transform (self) != PHOSH_MONITOR_TRANSFORM_NORMAL)
- phosh_shell_set_transform (self, PHOSH_MONITOR_TRANSFORM_NORMAL);
+ priv->gnome_shell_manager = phosh_gnome_shell_manager_get_default ();
+ priv->screenshot_manager = phosh_screenshot_manager_new ();
priv->startup_finished = TRUE;
+ g_signal_emit (self, signals[READY], 0);
return FALSE;
}
@@ -510,9 +532,22 @@
static void
type_setup (void)
{
- phosh_battery_info_get_type();
- phosh_wifi_info_get_type();
- phosh_wwan_info_get_type();
+ g_type_ensure (PHOSH_TYPE_BATTERY_INFO);
+ g_type_ensure (PHOSH_TYPE_BT_INFO);
+ g_type_ensure (PHOSH_TYPE_CONNECTIVITY_INFO);
+ g_type_ensure (PHOSH_TYPE_DOCKED_INFO);
+ g_type_ensure (PHOSH_TYPE_FEEDBACK_INFO);
+ g_type_ensure (PHOSH_TYPE_HKS_INFO);
+ g_type_ensure (PHOSH_TYPE_LOCATION_INFO);
+ g_type_ensure (PHOSH_TYPE_MEDIA_PLAYER);
+ g_type_ensure (PHOSH_TYPE_QUICK_SETTING);
+ g_type_ensure (PHOSH_TYPE_ROTATE_INFO);
+ g_type_ensure (PHOSH_TYPE_SETTINGS);
+ g_type_ensure (PHOSH_TYPE_SYSTEM_MODAL);
+ g_type_ensure (PHOSH_TYPE_SYSTEM_MODAL_DIALOG);
+ g_type_ensure (PHOSH_TYPE_TORCH_INFO);
+ g_type_ensure (PHOSH_TYPE_WIFI_INFO);
+ g_type_ensure (PHOSH_TYPE_WWAN_INFO);
}
@@ -520,34 +555,48 @@
on_builtin_monitor_power_mode_changed (PhoshShell *self, GParamSpec *pspec, PhoshMonitor *monitor)
{
PhoshMonitorPowerSaveMode mode;
+ PhoshShellPrivate *priv;
g_return_if_fail (PHOSH_IS_SHELL (self));
g_return_if_fail (PHOSH_IS_MONITOR (monitor));
+ priv = phosh_shell_get_instance_private (self);
g_object_get (monitor, "power-mode", &mode, NULL);
- if (mode == PHOSH_MONITOR_POWER_SAVE_MODE_OFF)
+ /* Might be emitted on startup before lockscreen_manager is up */
+ if (mode == PHOSH_MONITOR_POWER_SAVE_MODE_OFF && priv->lockscreen_manager)
phosh_shell_lock (self);
-}
+ phosh_shell_set_state (self, PHOSH_STATE_BLANKED, mode == PHOSH_MONITOR_POWER_SAVE_MODE_OFF);
+}
static void
-on_primary_monitor_configured (PhoshShell *self,
- PhoshMonitor *monitor)
+on_monitor_added (PhoshShell *self, PhoshMonitor *monitor)
{
PhoshShellPrivate *priv;
- PhoshMonitorTransform transform;
g_return_if_fail (PHOSH_IS_SHELL (self));
g_return_if_fail (PHOSH_IS_MONITOR (monitor));
-
priv = phosh_shell_get_instance_private (self);
- transform = phosh_monitor_get_transform (monitor);
- if (transform == priv->transform)
+
+ g_debug ("Monitor %p (%s)", monitor, monitor->name);
+
+ if (priv->builtin_monitor)
+ return;
+
+ if (!phosh_monitor_is_builtin (monitor))
return;
- priv->transform = transform;
- g_debug ("Primary monitor transform %d", transform);
- g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_SHELL_PROP_TRANSFORM]);
+ priv->builtin_monitor = g_object_ref (monitor);
+ g_signal_connect_swapped (priv->builtin_monitor,
+ "notify::power-mode",
+ G_CALLBACK(on_builtin_monitor_power_mode_changed),
+ self);
+
+ g_debug ("Updating builtin monitor to %s", monitor->name);
+ if (priv->rotation_manager)
+ phosh_rotation_manager_set_monitor (priv->rotation_manager, monitor);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_BUILTIN_MONITOR]);
}
@@ -560,27 +609,64 @@
g_return_if_fail (PHOSH_IS_MONITOR (monitor));
priv = phosh_shell_get_instance_private (self);
- if (priv->primary_monitor != monitor)
- return;
+ if (priv->builtin_monitor == monitor) {
+ g_debug ("Builtin monitor %p (%s) removed", monitor, monitor->name);
- g_debug ("Primary monitor removed %p", monitor);
+ if (priv->builtin_monitor) {
+ /* Power mode listener */
+ g_signal_handlers_disconnect_by_data (priv->builtin_monitor, self);
+ g_clear_object (&priv->builtin_monitor);
+ }
- /* Prefer built in monitor when primary is gone... */
- if (priv->builtin_monitor && monitor != priv->builtin_monitor) {
- phosh_shell_set_primary_monitor (self, priv->builtin_monitor);
- return;
+ if (priv->rotation_manager)
+ phosh_rotation_manager_set_monitor (priv->rotation_manager, NULL);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_BUILTIN_MONITOR]);
+ }
+
+ if (priv->primary_monitor == monitor) {
+ g_debug ("Primary monitor %p (%s) removed", monitor, monitor->name);
+
+ /* Prefer built in monitor when primary is gone... */
+ if (priv->builtin_monitor) {
+ phosh_shell_set_primary_monitor (self, priv->builtin_monitor);
+ return;
+ }
+
+ /* ...just pick the first one available otherwise */
+ for (int i = 0; i < phosh_monitor_manager_get_num_monitors (priv->monitor_manager); i++) {
+ PhoshMonitor *new_primary = phosh_monitor_manager_get_monitor (priv->monitor_manager, i);
+ if (new_primary != monitor) {
+ phosh_shell_set_primary_monitor (self, new_primary);
+ break;
+ }
+ }
+ g_assert (priv->primary_monitor && priv->primary_monitor != monitor);
}
+}
+
+
+static PhoshMonitor *
+find_builtin_monitor (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+ PhoshMonitor *monitor = NULL;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+
+ if (priv->builtin_monitor)
+ return priv->builtin_monitor;
- /* ...just pick the first one available otherwise */
for (int i = 0; i < phosh_monitor_manager_get_num_monitors (priv->monitor_manager); i++) {
- PhoshMonitor *new_primary = phosh_monitor_manager_get_monitor (priv->monitor_manager, i);
- if (new_primary != monitor) {
- phosh_shell_set_primary_monitor (self, new_primary);
+ PhoshMonitor *tmp = phosh_monitor_manager_get_monitor (priv->monitor_manager, i);
+ if (phosh_monitor_is_builtin (tmp)) {
+ monitor = tmp;
break;
}
}
- g_assert (priv->primary_monitor && priv->primary_monitor != monitor);
+ return monitor;
}
@@ -593,11 +679,14 @@
G_OBJECT_CLASS (phosh_shell_parent_class)->constructed (object);
/* We bind this early since a wl_display_roundtrip () would make us miss
- exising toplevels */
+ existing toplevels */
priv->toplevel_manager = phosh_toplevel_manager_new ();
- priv->transform = -1; /* force initial update */
- priv->monitor_manager = phosh_monitor_manager_new ();
+ priv->monitor_manager = phosh_monitor_manager_new (NULL);
+ g_signal_connect_swapped (priv->monitor_manager,
+ "monitor-added",
+ G_CALLBACK (on_monitor_added),
+ self);
g_signal_connect_swapped (priv->monitor_manager,
"monitor-removed",
G_CALLBACK (on_monitor_removed),
@@ -606,27 +695,34 @@
/* Make sure all outputs are up to date */
phosh_wayland_roundtrip (phosh_wayland_get_default ());
- if (phosh_monitor_manager_get_num_monitors(priv->monitor_manager)) {
- priv->builtin_monitor = phosh_shell_get_builtin_monitor (self);
+ if (phosh_monitor_manager_get_num_monitors (priv->monitor_manager)) {
+ PhoshMonitor *monitor = find_builtin_monitor (self);
+
+ /* Setup builtin monitor */
+ if (monitor) {
+ on_monitor_added (self, monitor);
+ g_debug ("Builtin monitor %p, configured: %d",
+ priv->builtin_monitor,
+ phosh_monitor_is_configured (priv->builtin_monitor));
+ }
- g_debug ("Builtin monitor is %s, %d", priv->builtin_monitor->name,
- phosh_monitor_is_configured (priv->builtin_monitor));
+ /* Setup primary monitor, prefer builtin */
/* Can't invoke phosh_shell_set_primary_monitor () since the shell
object does not really exist yet but we need the primary monitor
early for the panels */
- priv->primary_monitor = g_object_ref (priv->builtin_monitor);
- g_signal_connect_swapped (priv->primary_monitor,
- "configured",
- G_CALLBACK (on_primary_monitor_configured),
- self);
+ if (priv->builtin_monitor)
+ priv->primary_monitor = g_object_ref (priv->builtin_monitor);
+ else
+ priv->primary_monitor = g_object_ref (phosh_monitor_manager_get_monitor (priv->monitor_manager, 0));
+ } else {
+ g_error ("Need at least one monitor");
}
gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (),
"/sm/puri/phosh/icons");
- css_setup (self);
- type_setup ();
- priv->lockscreen_manager = phosh_lockscreen_manager_new ();
+ priv->calls_manager = phosh_calls_manager_new ();
+ priv->lockscreen_manager = phosh_lockscreen_manager_new (priv->calls_manager);
g_object_bind_property (priv->lockscreen_manager, "locked",
self, "locked",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
@@ -639,16 +735,6 @@
priv->polkit_auth_agent = phosh_polkit_auth_agent_new ();
priv->feedback_manager = phosh_feedback_manager_new ();
- priv->gnome_shell_manager = phosh_gnome_shell_manager_get_default ();
-
- if (priv->builtin_monitor) {
- g_signal_connect_swapped (
- priv->builtin_monitor,
- "notify::power-mode",
- G_CALLBACK(on_builtin_monitor_power_mode_changed),
- self);
- }
-
priv->keyboard_events = phosh_keyboard_events_new ();
g_idle_add ((GSourceFunc) setup_idle_cb, self);
@@ -666,71 +752,70 @@
object_class->set_property = phosh_shell_set_property;
object_class->get_property = phosh_shell_get_property;
- props[PHOSH_SHELL_PROP_TRANSFORM] =
- g_param_spec_enum ("transform",
- "Transform",
- "Monitor transform of the primary monitor",
- PHOSH_TYPE_MONITOR_TRANSFORM,
- PHOSH_MONITOR_TRANSFORM_NORMAL,
- G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
+ type_setup ();
- props[PHOSH_SHELL_PROP_LOCKED] =
+ props[PROP_LOCKED] =
g_param_spec_boolean ("locked",
"Locked",
"Whether the screen is locked",
FALSE,
- G_PARAM_READWRITE);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- props[PHOSH_SHELL_PROP_PRIMARY_MONITOR] =
+ /**
+ * PhoshShell:builtin-monitor:
+ *
+ * The built in monitor. This is a hardware property and hence can
+ * only be read. It can be %NULL when not present or disabled.
+ */
+ props[PROP_BUILTIN_MONITOR] =
+ g_param_spec_object ("builtin-monitor",
+ "Built in monitor",
+ "The builtin monitor",
+ PHOSH_TYPE_MONITOR,
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ /**
+ * PhoshShell:primary-monitor:
+ *
+ * The primary monitor that has the panels, lock screen etc. This can't be %NULL.
+ */
+ props[PROP_PRIMARY_MONITOR] =
g_param_spec_object ("primary-monitor",
"Primary monitor",
"The primary monitor",
PHOSH_TYPE_MONITOR,
- G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, PHOSH_SHELL_PROP_LAST_PROP, props);
+ props[PROP_SHELL_STATE] =
+ g_param_spec_flags ("shell-state",
+ "Shell state",
+ "The state of the shell",
+ PHOSH_TYPE_SHELL_STATE_FLAGS,
+ PHOSH_STATE_NONE,
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ signals[READY] = g_signal_new ("ready",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
}
static void
phosh_shell_init (PhoshShell *self)
{
+ PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
GtkSettings *gtk_settings;
gtk_settings = gtk_settings_get_default ();
g_object_set (G_OBJECT (gtk_settings), "gtk-application-prefer-dark-theme", TRUE, NULL);
-}
-
-
-PhoshMonitorTransform
-phosh_shell_get_transform (PhoshShell *self)
-{
- PhoshShellPrivate *priv;
-
- g_return_val_if_fail (PHOSH_IS_SHELL (self), PHOSH_MONITOR_TRANSFORM_NORMAL);
- priv = phosh_shell_get_instance_private (self);
- g_return_val_if_fail (priv->primary_monitor, PHOSH_MONITOR_TRANSFORM_NORMAL);
- return phosh_monitor_get_transform (priv->primary_monitor);
-}
-
-
-void
-phosh_shell_set_transform (PhoshShell *self,
- PhoshMonitorTransform transform)
-{
- PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
- PhoshMonitorTransform current;
- g_return_if_fail (priv->primary_monitor);
- current = phosh_monitor_get_transform (priv->primary_monitor);
- if (current == transform)
- return;
+ g_signal_connect_swapped (gtk_settings, "notify::gtk-theme-name", G_CALLBACK (on_gtk_theme_name_changed), self);
+ on_gtk_theme_name_changed (self, NULL, gtk_settings);
- phosh_monitor_manager_set_monitor_transform (priv->monitor_manager,
- priv->primary_monitor,
- transform);
- phosh_monitor_manager_apply_monitor_config (priv->monitor_manager);
- /* Notification change signalled in on_primary_monitor_configured */
+ priv->shell_state = PHOSH_STATE_NONE;
}
@@ -739,7 +824,6 @@
{
PhoshShellPrivate *priv;
PhoshMonitor *m = NULL;
- PhoshMonitorTransform transform;
g_return_if_fail (monitor);
g_return_if_fail (PHOSH_IS_SHELL (self));
@@ -755,25 +839,15 @@
}
g_return_if_fail (monitor == m);
- if (priv->primary_monitor)
- g_signal_handlers_disconnect_by_data (priv->primary_monitor, self);
g_clear_object (&priv->primary_monitor);
priv->primary_monitor = g_object_ref (monitor);
g_debug ("New primary monitor is %s", monitor->name);
- g_signal_connect_swapped (priv->primary_monitor,
- "configured",
- G_CALLBACK (on_primary_monitor_configured),
- self);
- /* Catch up if old and new primary monitor's rotation are different */
- transform = phosh_monitor_get_transform (priv->primary_monitor);
- if (transform != priv->transform)
- on_primary_monitor_configured (self, priv->primary_monitor);
/* Move panels to the new monitor by recreating the layer shell surfaces */
panels_dispose (self);
panels_create (self);
- g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_SHELL_PROP_PRIMARY_MONITOR]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PRIMARY_MONITOR]);
}
@@ -781,25 +855,12 @@
phosh_shell_get_builtin_monitor (PhoshShell *self)
{
PhoshShellPrivate *priv;
- PhoshMonitor *monitor = NULL;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
+ g_return_val_if_fail (PHOSH_IS_MONITOR (priv->builtin_monitor) || priv->builtin_monitor == NULL, NULL);
- if (priv->builtin_monitor)
- return priv->builtin_monitor;
-
- for (int i = 0; i < phosh_monitor_manager_get_num_monitors (priv->monitor_manager); i++) {
- monitor = phosh_monitor_manager_get_monitor (priv->monitor_manager, i);
- if (phosh_monitor_is_builtin (monitor))
- break;
- }
-
- if (!monitor)
- monitor = phosh_monitor_manager_get_monitor (priv->monitor_manager, 0);
- g_return_val_if_fail (monitor, NULL);
-
- return monitor;
+ return priv->builtin_monitor;
}
@@ -822,6 +883,59 @@
return monitor;
}
+/* Manager getters */
+
+PhoshBackgroundManager *
+phosh_shell_get_background_manager (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+ g_return_val_if_fail (PHOSH_IS_BACKGROUND_MANAGER (priv->background_manager), NULL);
+
+ return priv->background_manager;
+}
+
+
+PhoshCallsManager *
+phosh_shell_get_calls_manager (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+ g_return_val_if_fail (PHOSH_IS_CALLS_MANAGER (priv->calls_manager), NULL);
+
+ return priv->calls_manager;
+}
+
+
+PhoshFeedbackManager *
+phosh_shell_get_feedback_manager (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+ g_return_val_if_fail (PHOSH_IS_FEEDBACK_MANAGER (priv->feedback_manager), NULL);
+
+ return priv->feedback_manager;
+}
+
+
+PhoshGtkMountManager *
+phosh_shell_get_gtk_mount_manager (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+ g_return_val_if_fail (PHOSH_IS_GTK_MOUNT_MANAGER (priv->gtk_mount_manager), NULL);
+
+ return priv->gtk_mount_manager;
+}
+
PhoshLockscreenManager *
phosh_shell_get_lockscreen_manager (PhoshShell *self)
@@ -862,21 +976,32 @@
}
-PhoshWifiManager *
-phosh_shell_get_wifi_manager (PhoshShell *self)
+PhoshToplevelManager *
+phosh_shell_get_toplevel_manager (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- if (!priv->wifi_manager)
- priv->wifi_manager = phosh_wifi_manager_new ();
+ g_return_val_if_fail (PHOSH_IS_TOPLEVEL_MANAGER (priv->toplevel_manager), NULL);
+ return priv->toplevel_manager;
+}
- g_return_val_if_fail (PHOSH_IS_WIFI_MANAGER (priv->wifi_manager), NULL);
- return priv->wifi_manager;
+
+PhoshSessionManager *
+phosh_shell_get_session_manager (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+ g_return_val_if_fail (PHOSH_IS_SESSION_MANAGER (priv->session_manager), NULL);
+
+ return priv->session_manager;
}
+/* Manager getters that create them as needed */
PhoshBtManager *
phosh_shell_get_bt_manager (PhoshShell *self)
@@ -894,73 +1019,86 @@
}
-PhoshOskManager *
-phosh_shell_get_osk_manager (PhoshShell *self)
+PhoshDockedManager *
+phosh_shell_get_docked_manager (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- if (!priv->osk_manager)
- priv->osk_manager = phosh_osk_manager_new ();
+ if (!priv->docked_manager)
+ priv->docked_manager = phosh_docked_manager_new (priv->mode_manager);
- g_return_val_if_fail (PHOSH_IS_OSK_MANAGER (priv->osk_manager), NULL);
- return priv->osk_manager;
+ g_return_val_if_fail (PHOSH_IS_DOCKED_MANAGER (priv->docked_manager), NULL);
+ return priv->docked_manager;
}
-PhoshToplevelManager *
-phosh_shell_get_toplevel_manager (PhoshShell *self)
+PhoshHksManager *
+phosh_shell_get_hks_manager (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- g_return_val_if_fail (PHOSH_IS_TOPLEVEL_MANAGER (priv->toplevel_manager), NULL);
- return priv->toplevel_manager;
+ if (!priv->hks_manager)
+ priv->hks_manager = phosh_hks_manager_new ();
+
+ g_return_val_if_fail (PHOSH_IS_HKS_MANAGER (priv->hks_manager), NULL);
+ return priv->hks_manager;
}
-PhoshFeedbackManager *
-phosh_shell_get_feedback_manager (PhoshShell *self)
+PhoshLocationManager *
+phosh_shell_get_location_manager (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- g_return_val_if_fail (PHOSH_IS_FEEDBACK_MANAGER (priv->feedback_manager), NULL);
- return priv->feedback_manager;
+ if (!priv->location_manager)
+ priv->location_manager = phosh_location_manager_new ();
+
+ g_return_val_if_fail (PHOSH_IS_LOCATION_MANAGER (priv->location_manager), NULL);
+ return priv->location_manager;
}
-PhoshWWan *
-phosh_shell_get_wwan (PhoshShell *self)
+PhoshOskManager *
+phosh_shell_get_osk_manager (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- if (!priv->wwan) {
- g_autoptr (GSettings) settings = g_settings_new ("sm.puri.phosh");
- PhoshWWanBackend backend = g_settings_get_enum (settings, WWAN_BACKEND_KEY);
+ if (!priv->osk_manager)
+ priv->osk_manager = phosh_osk_manager_new ();
- switch (backend) {
- default:
- case PHOSH_WWAN_BACKEND_MM:
- priv->wwan = PHOSH_WWAN (phosh_wwan_mm_new());
- break;
- case PHOSH_WWAN_BACKEND_OFONO:
- priv->wwan = PHOSH_WWAN (phosh_wwan_ofono_new());
- break;
- }
- }
+ g_return_val_if_fail (PHOSH_IS_OSK_MANAGER (priv->osk_manager), NULL);
+ return priv->osk_manager;
+}
- g_return_val_if_fail (PHOSH_IS_WWAN (priv->wwan), NULL);
- return priv->wwan;
+
+PhoshRotationManager *
+phosh_shell_get_rotation_manager (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
+ priv = phosh_shell_get_instance_private (self);
+
+ if (!priv->rotation_manager)
+ priv->rotation_manager = phosh_rotation_manager_new (priv->sensor_proxy_manager,
+ priv->lockscreen_manager,
+ priv->builtin_monitor);
+
+ g_return_val_if_fail (PHOSH_IS_ROTATION_MANAGER (priv->rotation_manager), NULL);
+
+ return priv->rotation_manager;
}
@@ -980,34 +1118,48 @@
}
-PhoshDockedManager *
-phosh_shell_get_docked_manager (PhoshShell *self)
+PhoshWifiManager *
+phosh_shell_get_wifi_manager (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- if (!priv->docked_manager)
- priv->docked_manager = phosh_docked_manager_new (priv->mode_manager);
+ if (!priv->wifi_manager)
+ priv->wifi_manager = phosh_wifi_manager_new ();
- g_return_val_if_fail (PHOSH_IS_DOCKED_MANAGER (priv->docked_manager), NULL);
- return priv->docked_manager;
+ g_return_val_if_fail (PHOSH_IS_WIFI_MANAGER (priv->wifi_manager), NULL);
+ return priv->wifi_manager;
}
-PhoshSessionManager *
-phosh_shell_get_session_manager (PhoshShell *self)
+PhoshWWan *
+phosh_shell_get_wwan (PhoshShell *self)
{
PhoshShellPrivate *priv;
g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL);
priv = phosh_shell_get_instance_private (self);
- g_return_val_if_fail (PHOSH_IS_SESSION_MANAGER (priv->session_manager), NULL);
- return priv->session_manager;
-}
+ if (!priv->wwan) {
+ g_autoptr (GSettings) settings = g_settings_new ("sm.puri.phosh");
+ PhoshWWanBackend backend = g_settings_get_enum (settings, WWAN_BACKEND_KEY);
+
+ switch (backend) {
+ default:
+ case PHOSH_WWAN_BACKEND_MM:
+ priv->wwan = PHOSH_WWAN (phosh_wwan_mm_new());
+ break;
+ case PHOSH_WWAN_BACKEND_OFONO:
+ priv->wwan = PHOSH_WWAN (phosh_wwan_ofono_new());
+ break;
+ }
+ }
+ g_return_val_if_fail (PHOSH_IS_WWAN (priv->wwan), NULL);
+ return priv->wwan;
+}
/**
* Returns the usable area in pixels usable by a client on the phone
@@ -1019,7 +1171,7 @@
PhoshMonitor *monitor;
PhoshMonitorMode *mode;
int w, h;
- int scale;
+ float scale;
g_return_if_fail (PHOSH_IS_SHELL (self));
@@ -1028,11 +1180,11 @@
mode = phosh_monitor_get_current_mode (monitor);
g_return_if_fail (mode != NULL);
- scale = monitor->scale ? monitor->scale : 1;
+ scale = MAX(1.0, phosh_monitor_get_fractional_scale (monitor));
- g_debug ("Primary monitor %p scale is %d, transform is %d",
+ g_debug ("Primary monitor %p scale is %f, transform is %d",
monitor,
- monitor->scale,
+ scale,
monitor->transform);
switch (phosh_monitor_get_transform(monitor)) {
@@ -1041,18 +1193,18 @@
case PHOSH_MONITOR_TRANSFORM_FLIPPED:
case PHOSH_MONITOR_TRANSFORM_FLIPPED_180:
w = mode->width / scale;
- h = mode->height / scale - PHOSH_PANEL_HEIGHT - PHOSH_HOME_BUTTON_HEIGHT;
+ h = mode->height / scale - PHOSH_TOP_PANEL_HEIGHT - PHOSH_HOME_BUTTON_HEIGHT;
break;
default:
w = mode->height / scale;
- h = mode->width / scale - PHOSH_PANEL_HEIGHT - PHOSH_HOME_BUTTON_HEIGHT;
+ h = mode->width / scale - PHOSH_TOP_PANEL_HEIGHT - PHOSH_HOME_BUTTON_HEIGHT;
break;
}
if (x)
*x = 0;
if (y)
- *y = PHOSH_PANEL_HEIGHT;
+ *y = PHOSH_TOP_PANEL_HEIGHT;
if (width)
*width = w;
if (height)
@@ -1077,7 +1229,6 @@
phosh_shell_fade_out (PhoshShell *self, guint timeout)
{
PhoshShellPrivate *priv;
- PhoshWayland *wl = phosh_wayland_get_default ();
PhoshMonitorManager *monitor_manager;
g_debug ("Fading out...");
@@ -1090,8 +1241,7 @@
PhoshFader *fader;
PhoshMonitor *monitor = phosh_monitor_manager_get_monitor (monitor_manager, i);
- fader = phosh_fader_new (phosh_wayland_get_zwlr_layer_shell_v1 (wl),
- monitor->wl_output);
+ fader = phosh_fader_new (monitor);
g_ptr_array_add (priv->faders, fader);
gtk_widget_show (GTK_WIDGET (fader));
if (timeout > 0)
@@ -1177,9 +1327,7 @@
void
phosh_shell_remove_global_keyboard_action_entries (PhoshShell *self,
- const GActionEntry *entries,
- gint n_entries)
-
+ GStrv action_names)
{
PhoshShellPrivate *priv;
@@ -1187,9 +1335,9 @@
priv = phosh_shell_get_instance_private (self);
g_return_if_fail (priv->keyboard_events);
- for (int i = 0; i < n_entries; i++) {
+ for (int i = 0; i < g_strv_length (action_names); i++) {
g_action_map_remove_action (G_ACTION_MAP (priv->keyboard_events),
- entries[i].name);
+ action_names[i]);
}
}
@@ -1216,7 +1364,7 @@
* phosh_get_app_launch_context:
* @self: The shell
*
- * Returns: a an app launch context for the primary display
+ * Returns: an app launch context for the primary display
*/
GdkAppLaunchContext*
phosh_shell_get_app_launch_context (PhoshShell *self)
@@ -1228,3 +1376,120 @@
return gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (priv->panel)));
}
+
+/**
+ * phosh_shell_get_state
+ * @self: The shell
+ *
+ * Returns: The current #PhoshShellStateFlags
+ */
+PhoshShellStateFlags
+phosh_shell_get_state (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), PHOSH_STATE_NONE);
+ priv = phosh_shell_get_instance_private (self);
+
+ return priv->shell_state;
+}
+
+/**
+ * phosh_shell_set_state:
+ * @self: The shell
+ * @state: The #PhoshShellStateFlags to set
+ * @enabled: %TRUE to set a shell state, %FALSE to reset
+ *
+ * Set the shells state.
+ */
+void
+phosh_shell_set_state (PhoshShell *self,
+ PhoshShellStateFlags state,
+ gboolean enabled)
+{
+ PhoshShellPrivate *priv;
+ PhoshShellStateFlags old_state;
+ g_autofree gchar *str_state = NULL;
+ g_autofree gchar *str_new_flags = NULL;
+
+ g_return_if_fail (PHOSH_IS_SHELL (self));
+ priv = phosh_shell_get_instance_private (self);
+
+ old_state = priv->shell_state;
+
+ if (enabled)
+ priv->shell_state = priv->shell_state | state;
+ else
+ priv->shell_state = priv->shell_state & ~state;
+
+ if (old_state == priv->shell_state)
+ return;
+
+ str_state = g_flags_to_string (PHOSH_TYPE_SHELL_STATE_FLAGS,
+ state);
+ str_new_flags = g_flags_to_string (PHOSH_TYPE_SHELL_STATE_FLAGS,
+ priv->shell_state);
+
+ g_debug ("%s %s shells state. New state: %s",
+ enabled ? "Adding to" : "Removing from",
+ str_state, str_new_flags);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SHELL_STATE]);
+}
+
+void
+phosh_shell_lock (PhoshShell *self)
+{
+ g_return_if_fail (PHOSH_IS_SHELL (self));
+
+ phosh_shell_set_locked (self, TRUE);
+}
+
+
+void
+phosh_shell_unlock (PhoshShell *self)
+{
+ g_return_if_fail (PHOSH_IS_SHELL (self));
+
+ phosh_shell_set_locked (self, FALSE);
+}
+
+/**
+ * phosh_shell_get_locked:
+ * @self: The #PhoshShell singleton
+ *
+ * Returns: %TRUE if the shell is currently locked, otherwise %FALSE.
+ */
+gboolean
+phosh_shell_get_locked (PhoshShell *self)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SHELL (self), FALSE);
+ priv = phosh_shell_get_instance_private (self);
+
+ return priv->locked;
+}
+
+/**
+ * phosh_shell_set_locked:
+ * @self: The #PhoshShell singleton
+ * @locked: %TRUE to lock the shell
+ *
+ * Lock the shell. We proxy to lockscreen-manager to avoid
+ * that other parts of the shell need to care about this
+ * abstraction.
+ */
+void
+phosh_shell_set_locked (PhoshShell *self, gboolean locked)
+{
+ PhoshShellPrivate *priv;
+
+ g_return_if_fail (PHOSH_IS_SHELL (self));
+ priv = phosh_shell_get_instance_private (self);
+
+ if (locked == priv->locked)
+ return;
+
+ phosh_lockscreen_manager_set_locked (priv->lockscreen_manager, locked);
+}
diff -Nru phosh-0.8.0/src/shell.h phosh-0.13.1/src/shell.h
--- phosh-0.8.0/src/shell.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/shell.h 2021-08-31 09:15:52.000000000 +0000
@@ -8,13 +8,19 @@
#pragma once
+#include "background-manager.h"
#include "bt-manager.h"
+#include "calls-manager.h"
#include "docked-manager.h"
#include "feedback-manager.h"
+#include "gtk-mount-manager.h"
+#include "hks-manager.h"
+#include "location-manager.h"
#include "lockscreen-manager.h"
#include "monitor-manager.h"
#include "monitor/monitor.h"
#include "osk-manager.h"
+#include "rotation-manager.h"
#include "session-manager.h"
#include "toplevel-manager.h"
#include "torch-manager.h"
@@ -23,6 +29,27 @@
#include
+/**
+ * PhoshShellStateFlags:
+ * @PHOSH_STATE_NONE: No other state
+ * @PHOSH_STATE_MODAL_SYSTEM_PROMPT: any modal prompt shown
+ * @PHOSH_STATE_BLANKED: built-in display off
+ * @PHOSH_STATE_LOCKED: displays locked
+ * @PHOSH_STATE_SETTINGS: settings menu unfolded from top bar
+ * @PHOSH_STATE_OVERVIEW: overview unfolded from bottom bar
+ *
+ * These flags are used to keep track of the state
+ * the #PhoshShell is in.
+ */
+typedef enum {
+ PHOSH_STATE_NONE = 0,
+ PHOSH_STATE_MODAL_SYSTEM_PROMPT = 1 << 0,
+ PHOSH_STATE_BLANKED = 1 << 1,
+ PHOSH_STATE_LOCKED = 1 << 2,
+ PHOSH_STATE_SETTINGS = 1 << 3,
+ PHOSH_STATE_OVERVIEW = 1 << 4,
+} PhoshShellStateFlags;
+
G_BEGIN_DECLS
#define PHOSH_APP_ID "sm.puri.Phosh"
@@ -33,8 +60,6 @@
G_DECLARE_FINAL_TYPE (PhoshShell, phosh_shell, PHOSH, SHELL, GObject)
PhoshShell *phosh_shell_get_default (void);
-void phosh_shell_set_transform (PhoshShell *self, PhoshMonitorTransform transform);
-PhoshMonitorTransform phosh_shell_get_transform (PhoshShell *self);
void phosh_shell_get_usable_area (PhoshShell *self,
int *x,
int *y,
@@ -47,18 +72,28 @@
void phosh_shell_set_primary_monitor (PhoshShell *self, PhoshMonitor *monitor);
PhoshMonitor *phosh_shell_get_primary_monitor (PhoshShell *self);
PhoshMonitor *phosh_shell_get_builtin_monitor (PhoshShell *self);
+
+/* Created by the shell on startup */
+PhoshBackgroundManager *phosh_shell_get_background_manager (PhoshShell *self);
+PhoshCallsManager *phosh_shell_get_calls_manager (PhoshShell *self);
+PhoshFeedbackManager *phosh_shell_get_feedback_manager (PhoshShell *self);
+PhoshGtkMountManager *phosh_shell_get_gtk_mount_manager (PhoshShell *self);
PhoshLockscreenManager *phosh_shell_get_lockscreen_manager (PhoshShell *self);
-PhoshModeManager *phosh_shell_get_mode_manager (PhoshShell *self);
-PhoshMonitorManager *phosh_shell_get_monitor_manager (PhoshShell *self);
-PhoshOskManager *phosh_shell_get_osk_manager (PhoshShell *self);
-PhoshToplevelManager *phosh_shell_get_toplevel_manager (PhoshShell *self);
-PhoshWifiManager *phosh_shell_get_wifi_manager (PhoshShell *self);
-PhoshFeedbackManager *phosh_shell_get_feedback_manager (PhoshShell *self);
-PhoshBtManager *phosh_shell_get_bt_manager (PhoshShell *self);
-PhoshWWan *phosh_shell_get_wwan (PhoshShell *self);
-PhoshTorchManager *phosh_shell_get_torch_manager (PhoshShell *self);
-PhoshDockedManager *phosh_shell_get_docked_manager (PhoshShell *self);
-PhoshSessionManager *phosh_shell_get_session_manager (PhoshShell *self);
+PhoshModeManager *phosh_shell_get_mode_manager (PhoshShell *self);
+PhoshMonitorManager *phosh_shell_get_monitor_manager (PhoshShell *self);
+PhoshToplevelManager *phosh_shell_get_toplevel_manager (PhoshShell *self);
+PhoshSessionManager *phosh_shell_get_session_manager (PhoshShell *self);
+/* Created on the fly */
+PhoshBtManager *phosh_shell_get_bt_manager (PhoshShell *self);
+PhoshDockedManager *phosh_shell_get_docked_manager (PhoshShell *self);
+PhoshHksManager *phosh_shell_get_hks_manager (PhoshShell *self);
+PhoshLocationManager *phosh_shell_get_location_manager (PhoshShell *self);
+PhoshOskManager *phosh_shell_get_osk_manager (PhoshShell *self);
+PhoshRotationManager *phosh_shell_get_rotation_manager (PhoshShell *self);
+PhoshTorchManager *phosh_shell_get_torch_manager (PhoshShell *self);
+PhoshWifiManager *phosh_shell_get_wifi_manager (PhoshShell *self);
+PhoshWWan *phosh_shell_get_wwan (PhoshShell *self);
+
void phosh_shell_fade_out (PhoshShell *self, guint timeout);
void phosh_shell_enable_power_save (PhoshShell *self, gboolean enable);
gboolean phosh_shell_started_by_display_manager(PhoshShell *self);
@@ -68,9 +103,10 @@
gint n_entries,
gpointer user_data);
void phosh_shell_remove_global_keyboard_action_entries (PhoshShell *self,
- const GActionEntry *actions,
- gint n_entries);
+ GStrv action_names);
gboolean phosh_shell_is_session_active (PhoshShell *self);
GdkAppLaunchContext *phosh_shell_get_app_launch_context (PhoshShell *self);
+PhoshShellStateFlags phosh_shell_get_state (PhoshShell *self);
+void phosh_shell_set_state (PhoshShell *self, PhoshShellStateFlags state, gboolean enabled);
G_END_DECLS
diff -Nru phosh-0.8.0/src/status-icon.c phosh-0.13.1/src/status-icon.c
--- phosh-0.8.0/src/status-icon.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/status-icon.c 2021-08-31 09:15:52.000000000 +0000
@@ -30,10 +30,12 @@
typedef struct
{
- GtkWidget *image;
- GtkWidget *extra_widget;
- GtkIconSize icon_size;
- char *info;
+ GtkWidget *image;
+ GtkWidget *extra_widget;
+ GtkIconSize icon_size;
+ char *info;
+
+ guint idle_id;
} PhoshStatusIconPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (PhoshStatusIcon, phosh_status_icon, GTK_TYPE_BIN);
@@ -93,6 +95,46 @@
}
+static gboolean
+on_idle (PhoshStatusIcon *self)
+{
+ PhoshStatusIconClass *klass = PHOSH_STATUS_ICON_GET_CLASS (self);
+ PhoshStatusIconPrivate *priv = phosh_status_icon_get_instance_private (self);
+
+ if (klass->idle_init)
+ (*klass->idle_init) (self);
+
+ priv->idle_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+
+static void
+phosh_status_icon_constructed (GObject *object)
+{
+ PhoshStatusIcon *self = PHOSH_STATUS_ICON (object);
+ PhoshStatusIconPrivate *priv = phosh_status_icon_get_instance_private (self);
+ PhoshStatusIconClass *klass = PHOSH_STATUS_ICON_GET_CLASS (self);
+
+ G_OBJECT_CLASS (phosh_status_icon_parent_class)->constructed (object);
+
+ if (klass->idle_init)
+ priv->idle_id = g_idle_add ((GSourceFunc) on_idle, self);
+}
+
+
+static void
+phosh_status_icon_dispose (GObject *object)
+{
+ PhoshStatusIcon *self = PHOSH_STATUS_ICON (object);
+ PhoshStatusIconPrivate *priv = phosh_status_icon_get_instance_private (self);
+
+ g_clear_handle_id (&priv->idle_id, g_source_remove);
+
+ G_OBJECT_CLASS (phosh_status_icon_parent_class)->dispose (object);
+}
+
+
static void
phosh_status_icon_finalize (GObject *gobject)
{
@@ -108,11 +150,16 @@
phosh_status_icon_class_init (PhoshStatusIconClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->set_property = phosh_status_icon_set_property;
object_class->get_property = phosh_status_icon_get_property;
+ object_class->constructed = phosh_status_icon_constructed;
+ object_class->dispose = phosh_status_icon_dispose;
object_class->finalize = phosh_status_icon_finalize;
+ gtk_widget_class_set_css_name (widget_class, "phosh-status-icon");
+
props[PHOSH_STATUS_ICON_PROP_ICON_NAME] =
g_param_spec_string ("icon-name",
"icon name",
@@ -312,4 +359,3 @@
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_STATUS_ICON_PROP_INFO]);
}
-
diff -Nru phosh-0.8.0/src/status-icon.h phosh-0.13.1/src/status-icon.h
--- phosh-0.8.0/src/status-icon.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/status-icon.h 2021-08-31 09:15:52.000000000 +0000
@@ -14,9 +14,16 @@
G_DECLARE_DERIVABLE_TYPE (PhoshStatusIcon, phosh_status_icon, PHOSH, STATUS_ICON, GtkBin)
+/**
+ * PhoshStatusIconClass:
+ * @parent_class: The parent class
+ * @idle_init: a callback to be invoked once on idle
+ */
struct _PhoshStatusIconClass
{
GtkBinClass parent_class;
+
+ void (*idle_init) (PhoshStatusIcon *self);
};
GtkWidget * phosh_status_icon_new (void);
diff -Nru phosh-0.8.0/src/style.css phosh-0.13.1/src/style.css
--- phosh-0.8.0/src/style.css 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/style.css 1970-01-01 00:00:00.000000000 +0000
@@ -1,367 +0,0 @@
-/*
- * Top bar panel
- */
-.phosh-panel {
- font: 15px Cantarell;
-}
-
-.phosh-panel-btn {
- background-image: none;
- border-width: 0;
-}
-
-.phosh-topbar-clock {
- font-weight: bold;
-}
-
-.phosh-power-button {
- padding-top: 0;
- padding-bottom: 0;
-}
-
-/*
- * Home bar
- */
-.phosh-osk-button {
- border-radius: 50%;
- min-width: 0;
- min-height: 0;
- padding: 6px;
-}
-
-/*
- * Settings menu
- */
-.phosh-settings-menu {
- background-color: black;
- border-bottom-right-radius: 10px;
- border-bottom-left-radius: 10px;
-}
-
-.phosh-settings-listboxrow {
- padding: 0;
-}
-
-.phosh-settings-row {
- box-shadow: none;
- background-color: black;
-}
-
-.phosh-settings-menu button.circular:not(:hover):not(:active) {
- border: 2px solid @theme_bg_color;
-}
-
-.phosh-notification-tray, .phosh-notification-tray list {
- border-radius: 6px;
- background-color: #282828;
-}
-
-.phosh-quick-setting {
- font-size: 9px;
- padding: 9px;
- border: 0;
- box-shadow: 0 0;
-}
-
-.phosh-quick-setting:not(:hover):not(:active) {
- background: none;
-}
-
-/*
- * Overview (app grid with favories and, activities)
- */
-phosh-activity > widget > button {
- background: none;
- box-shadow: none;
- border: none;
- border-radius: 0;
- padding: 0;
- margin: 0;
-}
-
-phosh-activity box button {
- background: white;
- border: none;
- border-radius: 0;
- /* box-shadow: 0 2px 2px rgba(0,0,0,0.4), 0 3px 16px rgba(0,0,0,0.3); */
-}
-
-.phosh-activity-empty {
- background: url('resource:///sm/puri/phosh/fake-app.svg');
- background-size: cover;
-}
-
-phosh-activity box {
- background: rgba(0, 0, 0, 0.7);
- padding: 6px;
- color: white;
- font-weight: bold;
-}
-
-phosh-activity:focus box {
- background: rgba(38, 35, 83, 0.7);
-}
-
-phosh-home, .phosh-panel {
- background: black;
- color: white;
-}
-
-.phosh-activity-close-button {
- border-radius: 50%;
- min-width: 48px;
- min-height: 48px;
- padding: 0;
-}
-
-.phosh-overview {
- background: black;
-}
-
-.phosh-favorite {
- background: none;
- border: none;
- box-shadow: none;
- padding: 0;
-}
-
-.phosh-favorite:hover {
- -gtk-icon-effect: none;
-}
-
-.phosh-favorite:active {
- -gtk-icon-effect: highlight;
-}
-
-.phosh-search-bar {
- border-radius: 9999px;
- padding: 3px 18px 3px 14px;
- margin: 0 10px 6px;
-}
-
-phosh-app-grid {
- background: black;
-}
-
-phosh-app-grid separator {
- background: rgba(51, 51, 51, 1);
- min-height: 2px
-}
-
-phosh-app-grid-button {
- font-size: 0.8rem;
-}
-
-phosh-app-grid-button button, phosh-app-grid-button button:hover {
- background: none;
- padding: 0;
- margin: 0;
- border: 1px solid transparent;
-}
-
-phosh-app-grid-button button:hover,
-phosh-app-grid-button button:focus,
-.search-active phosh-app-grid-button:first-child button {
- background: rgba(46, 45, 45, 0.6);
- border-radius: 5px;
-}
-
-phosh-app-grid-button button:focus {
- border-color: @theme_selected_bg_color;
-}
-
-phosh-app-grid-button image {
- /* -gtk-icon-shadow: 0 1px 2px rgba(0,0,0,0.4), 0 1px 8px rgba(0,0,0,0.2); */
-}
-
-/*
- * Lock screen
- */
-phosh-lockscreen, .phosh-lockshield {
- background-color: black;
-}
-
-.phosh-lockscreen-clock {
- font-size: 72px;
- font-weight: 100;
-}
-
-.phosh-lockscreen-arrow {
- transition: 400ms linear;
- animation: pulsate 1.8s ease-out;
- animation-iteration-count: 15;
-}
-
-.phosh-lockscreen-pin {
- font-size: 20px;
-}
-
-@keyframes pulsate {
- 0% {-gtk-icon-transform: translateY(0); opacity: 0.7}
- 35% {-gtk-icon-transform: translateY(-14px); opacity: 1}
- 100% {-gtk-icon-transform: translateY(0); opacity: 0.7}
-}
-
-/* Lockscreen keypad */
-keypad > grid > button {
- border-radius: 9999px;
- -gtk-outline-radius: 9999px;
- background-origin: padding-box, border-box;
- background-clip: padding-box, border-box;
- font-size: 16px;
- font-weight: bold;
- padding: 16px;
- border: 0;
- box-shadow: none;
- background: 0;
- border: 0;
-}
-
-keypad > grid > button:active {
- background: rgba(255, 255, 255, 0.3);
-}
-
-.text-only-button:active {
- background: rgba(255, 255, 255, 0.5);
-}
-
-keypad > grid > button:focus, .text-only-button:focus {
- outline-style: none;
-}
-
-.text-only-button {
- font-size: 16px;
- font-weight: bold;
- padding: 16px 36px;
- border: 0;
- box-shadow: none;
- background: rgba(255, 255, 255, 0.3);
- border: 0;
-}
-
-phosh-lockscreen phosh-media-player {
- background: none;
- border: solid 1px;
- border-color: rgb(51,51,51);
- border-radius: 0;
-}
-
-phosh-lockscreen phosh-media-player button {
- background: rgba(255, 255, 255, 0.3);
- border: none;
-}
-
-phosh-lockscreen phosh-media-player button:not(:hover):not(:active) {
- background: none;
-}
-
-/*
- * System modal dialogs (polkit, gcr)
- */
-.phosh-system-modal {
- background-color: alpha(@theme_bg_color, 0.7);
-}
-
-.phosh-system-modal-dialog {
- background-color: black;
- border: solid 2px;
- border-color: white;
- border-radius: 10px;
- padding: 18px;
-}
-
-/*
- * Notifications
- */
-phosh-notification-content {
- background: transparent;
-}
-
-phosh-notification-content .message-area {
- padding: 12px;
-}
-
-phosh-notification-content .message-area image {
- border-radius: 50%;
-}
-
-phosh-notification-content .actions-area button {
- border-radius: 0;
- box-shadow: none;
- border-left: none;
- border-right: none;
-}
-
-phosh-notification-content:last-child .actions-area button:last-child {
- border-radius: 0 0 6px 6px;
- border-bottom: none;
-}
-
-phosh-notification-frame {
- border-radius: 6px;
- background-color: #282828;
- margin: 12px;
-}
-
-phosh-notification-banner > phosh-notification-frame {
- box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.33),
- 0px 5px 6px 0px rgba(0, 0, 0, 0.07),
- 0px 0px 0px 1px rgba(0, 0, 0, 0.2);
-}
-
-phosh-notification-frame list {
- background: transparent;
-}
-
-phosh-notification-frame .header-area {
- padding: 12px 12px 0 12px;
-}
-
-phosh-notification-frame .header-area image {
- -gtk-icon-style: symbolic;
-}
-
-phosh-notification-banner {
- border: none;
- background: transparent;
- padding: 12px;
-}
-
-/*
- * Output fader
- */
-@keyframes phosh-fade-in {
- from {background:rgba(0, 0, 0, 0);}
- to {background:rgba(0, 0, 0, 1);}
-}
-
-.phosh-fader-fade-in {
- animation-name: phosh-fade-in;
- animation-duration: 2s;
- animation-timing-function: linear;
- animation-iteration-count: 1;
- animation-fill-mode: forwards;
-}
-
-/*
- * Media player
- */
-phosh-media-player {
- background: rgb(51,51,51);
- border-radius: 5%;
- padding: 9px;
- border: 0;
- box-shadow: 0 0;
-}
-
-phosh-media-player > button {
- border-radius: 0;
- box-shadow: none;
- outline-style: none;
-}
-
-/* The details button should not look inactive even when disabled */
-phosh-media-player box *:disabled {
- color: white;
- -gtk-icon-effect: none;
-}
diff -Nru phosh-0.8.0/src/stylesheet/adwaita-dark.css phosh-0.13.1/src/stylesheet/adwaita-dark.css
--- phosh-0.8.0/src/stylesheet/adwaita-dark.css 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/stylesheet/adwaita-dark.css 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,7 @@
+/* Adwaita dark them variant */
+
+@define-color phosh_fg_color white;
+@define-color phosh_bg_color black;
+@define-color phosh_notification_bg_color #282828;
+
+@import url("resource:///sm/puri/phosh/stylesheet/common.css");
diff -Nru phosh-0.8.0/src/stylesheet/adwaita-hc-light.css phosh-0.13.1/src/stylesheet/adwaita-hc-light.css
--- phosh-0.8.0/src/stylesheet/adwaita-hc-light.css 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/stylesheet/adwaita-hc-light.css 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,12 @@
+/* HighContrast theme variant */
+
+@define-color phosh_fg_color black;
+@define-color phosh_bg_color white;
+@define-color phosh_notification_bg_color #e0e0e0;
+
+@import url("resource:///sm/puri/phosh/stylesheet/common.css");
+
+.phosh-panel-btn {
+ border-width: 1px;
+ border-radius: 0;
+}
diff -Nru phosh-0.8.0/src/stylesheet/common.css phosh-0.13.1/src/stylesheet/common.css
--- phosh-0.8.0/src/stylesheet/common.css 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/stylesheet/common.css 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,535 @@
+/*
+ * Top panel bar
+ */
+phosh-top-panel {
+ font: 15px Cantarell;
+}
+
+.phosh-panel-btn {
+ background-image: none;
+ border-width: 0;
+}
+
+phosh-top-panel .indicators {
+ font-weight: bold;
+ font-feature-settings: "tnum";
+}
+
+.phosh-topbar-clock {
+ font-weight: bold;
+ font-feature-settings: "tnum";
+}
+
+.phosh-power-button {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+/*
+ * Home bar
+ */
+.phosh-osk-button {
+ border-radius: 50%;
+ min-width: 0;
+ min-height: 0;
+ padding: 6px;
+}
+
+/*
+ * Settings menu
+ */
+.phosh-settings-menu {
+ background-color: @phosh_bg_color;
+ border-bottom-right-radius: 10px;
+ border-bottom-left-radius: 10px;
+}
+
+.phosh-settings-menu button.circular:not(:hover):not(:active) {
+ border: 2px solid @theme_bg_color;
+}
+
+.phosh-notification-tray, .phosh-notification-tray list {
+ border-radius: 6px;
+ background-color: @phosh_notification_bg_color;
+}
+
+.phosh-quick-setting {
+ font-size: 9px;
+ padding: 9px;
+ border: 0;
+ box-shadow: 0 0;
+}
+
+.phosh-quick-setting:not(:hover):not(:active) {
+ background: none;
+}
+
+/*
+ * Overview (app grid with favories and, activities)
+ */
+phosh-activity > widget > button {
+ background: none;
+ box-shadow: none;
+ border: none;
+ border-radius: 0;
+ padding: 0;
+ margin: 0;
+ transition: none;
+}
+
+phosh-activity box button {
+ background: white;
+ border: none;
+ border-radius: 0;
+ /* box-shadow: 0 2px 2px rgba(0,0,0,0.4), 0 3px 16px rgba(0,0,0,0.3); */
+}
+
+.phosh-activity-empty {
+ background: url('resource:///sm/puri/phosh/fake-app.svg');
+ background-size: cover;
+}
+
+phosh-activity box {
+ background: rgba(0, 0, 0, 0.7);
+ padding: 6px;
+ color: white;
+ font-weight: bold;
+}
+
+phosh-activity:focus box {
+ background: rgba(38, 35, 83, 0.7);
+}
+
+phosh-home, phosh-top-panel {
+ background: @phosh_bg_color;
+ color: @phosh_fg_color;
+}
+
+.phosh-activity-close-button {
+ border-radius: 50%;
+ min-width: 48px;
+ min-height: 48px;
+ padding: 0;
+}
+
+.phosh-overview {
+ background: @phosh_bg_color;
+}
+
+.phosh-favorite {
+ background: none;
+ border: none;
+ box-shadow: none;
+ padding: 0;
+}
+
+.phosh-favorite:hover {
+ -gtk-icon-effect: none;
+}
+
+.phosh-favorite:active {
+ -gtk-icon-effect: highlight;
+}
+
+.phosh-search-bar-box {
+ margin: 6px 16px;
+}
+
+.phosh-search-bar {
+ border-radius: 9999px;
+ padding: 3px 18px 3px 14px;
+}
+
+.phosh-menu-button {
+ margin: 3px 0px 3px 10px;
+}
+
+phosh-app-grid {
+ background: @phosh_bg_color;
+}
+
+phosh-app-grid separator {
+ background: rgba(51, 51, 51, 1);
+ min-height: 2px
+}
+
+phosh-app-grid-button {
+ font-size: 0.8rem;
+}
+
+phosh-app-grid-button button, phosh-app-grid-button button:hover {
+ background: none;
+ padding: 0;
+ margin: 0;
+ border: 1px solid transparent;
+}
+
+phosh-app-grid-button button:hover,
+phosh-app-grid-button button:focus,
+.search-active phosh-app-grid-button:first-child button {
+ background: rgba(46, 45, 45, 0.6);
+ border-radius: 5px;
+}
+
+phosh-app-grid-button button:focus {
+ border-color: @theme_selected_bg_color;
+}
+
+phosh-app-grid-button image {
+ /* -gtk-icon-shadow: 0 1px 2px rgba(0,0,0,0.4), 0 1px 8px rgba(0,0,0,0.2); */
+}
+
+/*
+ * Lock screen
+ */
+phosh-lockscreen, .phosh-lockshield {
+ background-color: @phosh_bg_color;
+}
+
+.phosh-lockscreen-clock {
+ font-size: 72px;
+ font-weight: 100;
+ font-feature-settings: "tnum";
+}
+
+.phosh-lockscreen-arrow {
+ transition: 400ms linear;
+ animation: pulsate 1.8s ease-out;
+ animation-iteration-count: 15;
+}
+
+.phosh-lockscreen-pin {
+ font-size: 20px;
+}
+
+@keyframes pulsate {
+ 0% {-gtk-icon-transform: translateY(0); opacity: 0.7}
+ 35% {-gtk-icon-transform: translateY(-14px); opacity: 1}
+ 100% {-gtk-icon-transform: translateY(0); opacity: 0.7}
+}
+
+/* Lockscreen keypad */
+keypad > grid > button {
+ border-radius: 9999px;
+ -gtk-outline-radius: 9999px;
+ background-origin: padding-box, border-box;
+ background-clip: padding-box, border-box;
+ font-size: 16px;
+ font-weight: bold;
+ padding: 16px;
+ border: 0;
+ box-shadow: none;
+ background: 0;
+}
+
+keypad > grid > button:active {
+ background: rgba(255, 255, 255, 0.3);
+}
+
+.text-only-button:active {
+ background: rgba(255, 255, 255, 0.5);
+}
+
+keypad > grid > button:focus, .text-only-button:focus {
+ outline-style: none;
+}
+
+.text-only-button {
+ font-size: 16px;
+ font-weight: bold;
+ padding: 16px 36px;
+ border: 0;
+ box-shadow: none;
+ background: rgba(255, 255, 255, 0.3);
+}
+
+phosh-lockscreen phosh-media-player {
+ margin-left: 12px;
+ margin-right: 12px;
+}
+
+phosh-lockscreen .phosh-notification-tray list {
+ background-color: @phosh_bg_color;
+}
+
+phosh-lockscreen .phosh-notification-tray row {
+ background-color: @phosh_bg_color;
+ margin-left: 12px;
+ margin-right: 12px;
+}
+
+phosh-lockscreen .phosh-notification-tray phosh-notification-frame {
+ background-color: @phosh_notification_bg_color;
+ margin: 3px 0px 0px 0px;
+}
+
+phosh-lockscreen .phosh-notification-tray phosh-notification-content {
+ background-color: @phosh_notification_bg_color;
+}
+
+phosh-lockscreen .phosh-notification-tray phosh-notification-content:last-child {
+ margin-bottom: 3px;
+ border-radius: 0px 0px 6px 6px;
+}
+
+/*
+ * System modal dialogs (polkit, gcr, ...)
+ */
+.phosh-system-modal {
+ background-color: alpha(@theme_bg_color, 0.7);
+}
+
+.phosh-system-modal-dialog {
+ background-color: @theme_bg_color;
+ border: none;
+ border-radius: 10px;
+ box-shadow: 0 0 0 1px alpha(black, .75);
+ padding: 0px;
+}
+
+.phosh-system-modal-dialog-buttons label {
+ margin: 12px;
+}
+
+.phosh-system-modal-dialog-buttons button {
+ padding: 0;
+ margin: 0;
+ border-top: 1px solid @borders;
+ border-right: 1px solid @borders;
+ border-left-width: 0;
+ border-bottom-width: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ box-shadow: none;
+ text-shadow: none;
+}
+
+.phosh-system-modal-dialog-buttons button:first-child {
+ border-bottom-left-radius: 11px;
+ border-bottom-right-radius: 0;
+}
+
+.phosh-system-modal-dialog-buttons button:last-child {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 11px;
+ border-right: none;
+}
+
+.phosh-system-modal-dialog-content {
+ padding-left: 18px;
+ padding-right: 18px;
+}
+
+.phosh-system-modal-dialog-title {
+ padding-top: 18px;
+ font-weight: 800;
+ font-size: 120%;
+}
+
+.phosh-end-session-dialog .phosh-end-session-subtitle {
+ font-feature-settings: "tnum";
+}
+
+.phosh-end-session-dialog .phosh-end-session-warning {
+ color: #ba5645;
+ font-weight: bold;
+}
+
+.phosh-end-session-dialog list {
+ border-radius: 12px;
+}
+
+.phosh-end-session-dialog list row {
+ margin-left: 6px;
+ margin-right: 6px;
+}
+
+.phosh-end-session-dialog list row:first-child {
+ margin-top: 6px;
+}
+
+.phosh-end-session-dialog list row:last-child {
+ margin-bottom: 6px;
+}
+
+.phosh-end-session-dialog list row box box.vertical label:first-child {
+ font-weight: bold;
+}
+
+/* Don't dim list of inhibited applications */
+.phosh-end-session-dialog list * {
+ color: @theme_text_color;
+ -gtk-icon-effect: none;
+}
+
+phosh-gtk-mount-prompt .phosh-system-modal-dialog-content > image {
+ -gtk-icon-style: symbolic;
+}
+
+/*
+ * Notifications
+ */
+phosh-notification-content {
+ background: transparent;
+}
+
+phosh-notification-content .message-area {
+ padding: 12px;
+}
+
+phosh-notification-content .message-area image {
+ border-radius: 50%;
+}
+
+phosh-notification-content .actions-area button {
+ border-radius: 0;
+ box-shadow: none;
+ border-left: none;
+ border-right: none;
+}
+
+phosh-notification-content:last-child .actions-area button:last-child {
+ border-radius: 0 0 6px 6px;
+ border-bottom: none;
+}
+
+phosh-notification-frame {
+ border-radius: 6px;
+ background-color: @phosh_notification_bg_color;
+ margin: 12px;
+}
+
+phosh-notification-banner > phosh-notification-frame {
+ box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.33),
+ 0px 5px 6px 0px rgba(0, 0, 0, 0.07),
+ 0px 0px 0px 1px rgba(0, 0, 0, 0.2);
+}
+
+phosh-notification-frame list {
+ background: transparent;
+}
+
+phosh-notification-frame .header-area {
+ padding: 12px 12px 0 12px;
+}
+
+phosh-notification-frame .header-area image {
+ -gtk-icon-style: symbolic;
+}
+
+phosh-notification-banner {
+ border: none;
+ background: transparent;
+ padding: 12px;
+}
+
+/*
+ * Output fader
+ */
+@keyframes phosh-fader-default-keyframe {
+ from {background:rgba(0, 0, 0, 0);}
+ to {background:rgba(0, 0, 0, 1);}
+}
+
+.phosh-fader-default-fade {
+ animation-name: phosh-fader-default-keyframe;
+ animation-duration: 2s;
+ animation-timing-function: linear;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+}
+
+/* Fader used for proximity dimming */
+.phosh-fader-proximity-fade {
+ animation-name: phosh-fader-default-keyframe;
+ animation-duration: 200ms;
+ animation-timing-function: linear;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+}
+
+/* Fader used for screenshot flash */
+@keyframes phosh-fader-flash-keyframe {
+ from {background:rgba(255, 255, 255, 1);}
+ to {background:rgba(255, 255, 255, 0);}
+}
+
+.phosh-fader-flash-fade {
+ animation-name: phosh-fader-flash-keyframe;
+ animation-duration: 500ms;
+ animation-timing-function: linear;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+}
+
+.phosh-fader-screenshot-opaque {
+ background: rgba(255, 255, 255, 0);
+}
+
+/*
+ * Media player
+ */
+phosh-media-player {
+ background: @phosh_notification_bg_color;
+ border-radius: 6px;
+ box-shadow: none;
+}
+
+phosh-media-player button {
+ background: @phosh_notification_bg_color;
+ border-radius: 0;
+ box-shadow: none;
+ border: 0;
+ outline-style: none;
+}
+
+phosh-media-player button:hover,
+phosh-media-player button:active {
+ background-color: rgba(255, 255, 255, 0.3);
+}
+
+phosh-media-player > box > button:first-child {
+ border-radius: 0 0 0 6px;
+}
+
+phosh-media-player > box > button:last-child {
+ border-radius: 0 0 6px 0;
+}
+
+phosh-media-player .media-player-details {
+ border-radius: 6px 6px 0 0;
+}
+
+/* The details button should not look inactive even when disabled */
+phosh-media-player .media-player-details *:disabled {
+ color: @theme_fg_color;
+ -gtk-icon-effect: none;
+}
+
+/*
+ * OSD
+ */
+phosh-osd-window levelbar block {
+ min-height: 16px;
+ box-shadow: none;
+ border-color: white;
+ border-radius: 5px;
+}
+
+phosh-osd-window levelbar block.low {
+ background-color: white;
+}
+
+phosh-osd-window levelbar block.high {
+ background-color: white;
+}
+
+phosh-osd-window levelbar block.full {
+ background-color: white;
+}
+
+phosh-osd-window levelbar trough {
+ box-shadow: none;
+ border-width: 0px;
+ padding: 0px;
+}
diff -Nru phosh-0.8.0/src/system-modal.c phosh-0.13.1/src/system-modal.c
--- phosh-0.8.0/src/system-modal.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/system-modal.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-system-modal"
+
+#include "config.h"
+
+#include "shell.h"
+#include "system-modal.h"
+
+/**
+ * SECTION:system-modal
+ * @short_description: A modal system component
+ * @Title: PhoshSystemModal
+ *
+ * The #PhoshSystemModal is used as a base class for other
+ * system components such as dialogs like #PhoshSystemPrompt or
+ * the OSD display.
+ */
+
+enum {
+ PROP_0,
+ PROP_MONITOR,
+ PROP_LAST_PROP,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+typedef struct {
+ PhoshMonitor *monitor;
+
+} PhoshSystemModalPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (PhoshSystemModal, phosh_system_modal, PHOSH_TYPE_LAYER_SURFACE);
+
+/*
+ * Keep track of opened modals
+ * Only reset PHOSH_STATE_MODAL_SYSTEM_PROMPT when there are no more modals
+ * see phosh_system_modal_map/unmap
+ */
+static int modal_count = 0;
+
+
+static void
+phosh_system_modal_map (GtkWidget *widget)
+{
+ g_return_if_fail (PHOSH_IS_SYSTEM_MODAL (widget));
+
+ modal_count++;
+ phosh_shell_set_state (phosh_shell_get_default (), PHOSH_STATE_MODAL_SYSTEM_PROMPT, TRUE);
+
+ GTK_WIDGET_CLASS (phosh_system_modal_parent_class)->map (widget);
+}
+
+
+static void
+phosh_system_modal_unmap (GtkWidget *widget)
+{
+ g_return_if_fail (PHOSH_IS_SYSTEM_MODAL (widget));
+
+ modal_count--;
+
+ if (modal_count == 0)
+ phosh_shell_set_state (phosh_shell_get_default (), PHOSH_STATE_MODAL_SYSTEM_PROMPT, FALSE);
+ else if (modal_count < 0)
+ g_warning ("The modal counter is negative %d. This should never happen",
+ modal_count);
+
+ GTK_WIDGET_CLASS (phosh_system_modal_parent_class)->unmap (widget);
+}
+
+static void
+phosh_system_modal_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshSystemModal *self = PHOSH_SYSTEM_MODAL (obj);
+ PhoshSystemModalPrivate *priv = phosh_system_modal_get_instance_private (self);
+
+ switch (prop_id) {
+ case PROP_MONITOR:
+ g_set_object (&priv->monitor, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_system_modal_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshSystemModal *self = PHOSH_SYSTEM_MODAL (obj);
+ PhoshSystemModalPrivate *priv = phosh_system_modal_get_instance_private (self);
+
+ switch (prop_id) {
+ case PROP_MONITOR:
+ g_value_set_object (value, priv->monitor);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_system_modal_dispose (GObject *obj)
+{
+ PhoshSystemModal *self = PHOSH_SYSTEM_MODAL (obj);
+ PhoshSystemModalPrivate *priv = phosh_system_modal_get_instance_private (self);
+
+ g_clear_object (&priv->monitor);
+
+ G_OBJECT_CLASS (phosh_system_modal_parent_class)->dispose (obj);
+}
+
+
+static void
+phosh_system_modal_constructed (GObject *object)
+{
+ PhoshSystemModal *self = PHOSH_SYSTEM_MODAL (object);
+ PhoshSystemModalPrivate *priv = phosh_system_modal_get_instance_private (self);
+ PhoshWayland *wl = phosh_wayland_get_default ();
+
+ if (priv->monitor == NULL)
+ priv->monitor = g_object_ref (phosh_shell_get_primary_monitor (phosh_shell_get_default ()));
+
+ g_object_set (PHOSH_LAYER_SURFACE (self),
+ "layer-shell", phosh_wayland_get_zwlr_layer_shell_v1 (wl),
+ "wl-output", phosh_monitor_get_wl_output (priv->monitor),
+ "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
+ "layer", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
+ "kbd-interactivity", TRUE,
+ "exclusive-zone", -1,
+ "namespace", "phosh system-modal",
+ NULL);
+
+ gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self)),
+ "phosh-system-modal");
+
+ G_OBJECT_CLASS (phosh_system_modal_parent_class)->constructed (object);
+}
+
+
+static void
+phosh_system_modal_class_init (PhoshSystemModalClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->map = phosh_system_modal_map;
+ widget_class->unmap = phosh_system_modal_unmap;
+
+ object_class->get_property = phosh_system_modal_get_property;
+ object_class->set_property = phosh_system_modal_set_property;
+ object_class->constructed = phosh_system_modal_constructed;
+ object_class->dispose = phosh_system_modal_dispose;
+
+ props[PROP_MONITOR] = g_param_spec_object ("monitor",
+ "Monitor",
+ "Monitor to put modal on",
+ PHOSH_TYPE_MONITOR,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+}
+
+
+static void
+phosh_system_modal_init (PhoshSystemModal *self)
+{
+}
+
+/**
+ * phosh_system_modal_new:
+ * @monitor: The #PhoshMonitor to put the modal surface on. If %NULL the primary monitor is used.
+ *
+ * Create a new system-modal surface.
+ */
+GtkWidget *
+phosh_system_modal_new (PhoshMonitor *monitor)
+{
+ g_return_val_if_fail (PHOSH_IS_MONITOR (monitor) || monitor == NULL, NULL);
+
+ return g_object_new (PHOSH_TYPE_SYSTEM_MODAL, "monitor", monitor, NULL);
+}
diff -Nru phosh-0.8.0/src/system-modal-dialog.c phosh-0.13.1/src/system-modal-dialog.c
--- phosh-0.8.0/src/system-modal-dialog.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/system-modal-dialog.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ */
+
+#define G_LOG_DOMAIN "phosh-system-modal-dialog"
+
+#include "config.h"
+
+#include "shell.h"
+#include "system-modal-dialog.h"
+#include "swipe-away-bin.h"
+
+/**
+ * SECTION:system-modal-dialog
+ * @short_description: A modal system dialog
+ * @Title: PhoshSystemModalDialog
+ *
+ * The #PhoshSystemModalDialog is used as a base class for system modal dialogs
+ * such as #PhoshSystemPrompt or #PhoshNetworkAuthPrompt. It consists of a title
+ * at the top, a content widget below that and button are at the bottom.
+ * The content widget can be set via #phosh_system_modal_dialog_set_content() and buttons
+ * to the button area added via #phosh_system_modal_dialog_add_button().
+ *
+ * # CSS Style classes
+ *
+ * A system modal dialog uses several style classes for consistent layout:
+ * ".phosh-system-modal-dialog" for the whole dialog area,
+ * ".phosh-system-modal-dialog-title" for the dialog title,
+ * ".phosh-system-modal-dialog-content" for the content area and
+ * ".phosh-system-modal-dialog-buttons" for the button area.
+ *
+ * # PhoshSystemModalDialog as #GtkBuildable
+ *
+ * The content widget and buttons can be specified using type
+ * <phosh-dialog-content> and <phosh-dialog-button> type attributes:
+ *
+ * |[
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ]|
+ */
+
+enum {
+ PROP_0,
+ PROP_TITLE,
+ PROP_LAST_PROP,
+};
+static GParamSpec *props[PROP_LAST_PROP];
+
+enum {
+ DIALOG_CANCELED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+typedef struct {
+ gchar *title;
+
+ GtkWidget *lbl_title;
+ GtkWidget *box_dialog;
+ GtkWidget *box_buttons;
+} PhoshSystemModalDialogPrivate;
+
+static void phosh_system_modal_dialog_buildable_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (PhoshSystemModalDialog, phosh_system_modal_dialog,
+ PHOSH_TYPE_SYSTEM_MODAL,
+ G_ADD_PRIVATE (PhoshSystemModalDialog)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ phosh_system_modal_dialog_buildable_init))
+
+static void
+phosh_system_modal_dialog_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshSystemModalDialog *self = PHOSH_SYSTEM_MODAL_DIALOG (obj);
+
+ switch (prop_id) {
+ case PROP_TITLE:
+ phosh_system_modal_dialog_set_title (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+phosh_system_modal_dialog_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PhoshSystemModalDialog *self = PHOSH_SYSTEM_MODAL_DIALOG (obj);
+ PhoshSystemModalDialogPrivate *priv = phosh_system_modal_dialog_get_instance_private (self);
+
+ switch (prop_id) {
+ case PROP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+on_removed_by_swipe (PhoshSystemModalDialog *self)
+{
+ g_signal_emit (self, signals[DIALOG_CANCELED], 0);
+}
+
+
+static gboolean
+on_key_press_event (PhoshSystemModalDialog *self, GdkEventKey *event, gpointer data)
+{
+ gboolean handled = FALSE;
+
+ g_return_val_if_fail (PHOSH_IS_SYSTEM_MODAL_DIALOG (self), FALSE);
+
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ g_signal_emit (self, signals[DIALOG_CANCELED], 0);
+ handled = TRUE;
+ break;
+ default:
+ /* nothing to do */
+ break;
+ }
+
+ return handled;
+}
+
+
+static void
+phosh_system_modal_dialog_finalize (GObject *obj)
+{
+ PhoshSystemModalDialog *self = PHOSH_SYSTEM_MODAL_DIALOG (obj);
+ PhoshSystemModalDialogPrivate *priv = phosh_system_modal_dialog_get_instance_private (self);
+
+ g_clear_pointer (&priv->title, g_free);
+
+ G_OBJECT_CLASS (phosh_system_modal_dialog_parent_class)->finalize (obj);
+}
+
+
+static void
+phosh_system_modal_dialog_constructed (GObject *object)
+{
+ PhoshSystemModalDialog *self = PHOSH_SYSTEM_MODAL_DIALOG (object);
+ PhoshSystemModalDialogPrivate *priv = phosh_system_modal_dialog_get_instance_private (self);
+
+ G_OBJECT_CLASS (phosh_system_modal_dialog_parent_class)->constructed (object);
+
+ g_object_bind_property (self, "title", priv->lbl_title, "label", G_BINDING_DEFAULT);
+
+ gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
+ g_signal_connect (G_OBJECT (self),
+ "key_press_event",
+ G_CALLBACK (on_key_press_event),
+ NULL);
+}
+
+
+static void
+phosh_system_modal_dialog_class_init (PhoshSystemModalDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = phosh_system_modal_dialog_get_property;
+ object_class->set_property = phosh_system_modal_dialog_set_property;
+ object_class->constructed = phosh_system_modal_dialog_constructed;
+ object_class->finalize = phosh_system_modal_dialog_finalize;
+
+ props[PROP_TITLE] = g_param_spec_string ("title",
+ "Title",
+ "The dialogs title",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_EXPLICIT_NOTIFY);
+ g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
+
+ /**
+ * PhoshSystemModalDialog::dialog-canceled:
+ *
+ * The ::dialog-done signal is emitted when the dialog was canceled and should be
+ * hidden or destroyed.
+ */
+ signals[DIALOG_CANCELED] = g_signal_new ("dialog-canceled",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
+
+ g_type_ensure (PHOSH_TYPE_SWIPE_AWAY_BIN);
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/sm/puri/phosh/ui/system-modal-dialog.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemModalDialog, lbl_title);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemModalDialog, box_dialog);
+ gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemModalDialog, box_buttons);
+ gtk_widget_class_bind_template_callback (widget_class, on_removed_by_swipe);
+}
+
+
+static GtkBuildableIface *parent_buildable_iface;
+
+
+static void
+phosh_system_modal_dialog_buildable_add_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *type)
+{
+ PhoshSystemModalDialog *self = PHOSH_SYSTEM_MODAL_DIALOG (buildable);
+
+ if (g_strcmp0 (type, "phosh-dialog-content") == 0) {
+ phosh_system_modal_dialog_set_content (self, GTK_WIDGET (child));
+ return;
+ }
+
+ if (g_strcmp0 (type, "phosh-dialog-button") == 0) {
+ phosh_system_modal_dialog_add_button (self, GTK_WIDGET (child), -1);
+ return;
+ }
+
+ /* The parent is a container itself so chain up */
+ parent_buildable_iface->add_child (buildable, builder, child, type);
+}
+
+
+static void
+phosh_system_modal_dialog_buildable_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->add_child = phosh_system_modal_dialog_buildable_add_child;
+}
+
+
+
+static void
+phosh_system_modal_dialog_init (PhoshSystemModalDialog *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+/**
+ * phosh_system_modal_dialog_new:
+ *
+ * Create a new system-modal dialog.
+ *
+ * Returns: A new system modal dialog
+ */
+GtkWidget *
+phosh_system_modal_dialog_new (void)
+{
+ return g_object_new (PHOSH_TYPE_SYSTEM_MODAL_DIALOG, NULL);
+}
+
+
+/**
+ * phosh_system_modal_dialog_set_content:
+ * @self: The #PhoshSystemModalDialog
+ * @content: The widget for the dialog's content area
+ *
+ * Adds the given widget as the dialog's content area. It is a programming error
+ * to set the content more than once.
+ */
+void
+phosh_system_modal_dialog_set_content (PhoshSystemModalDialog *self, GtkWidget *content)
+{
+ PhoshSystemModalDialogPrivate *priv;
+
+ g_return_if_fail (PHOSH_IS_SYSTEM_MODAL_DIALOG (self));
+ g_return_if_fail (GTK_IS_WIDGET (content));
+
+ priv = phosh_system_modal_dialog_get_instance_private (PHOSH_SYSTEM_MODAL_DIALOG (self));
+
+ gtk_box_pack_start (GTK_BOX (priv->box_dialog), GTK_WIDGET (content), FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (priv->box_dialog), GTK_WIDGET (content), 1);
+ gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (content)),
+ "phosh-system-modal-dialog-content");
+}
+
+
+/**
+ * phosh_system_modal_dialog_add_button:
+ * @self: The #PhoshSystemModalDialog
+ * @button: The button for the dialog's button area
+ * @position: The buttons position in the box or -1
+ *
+ * Adds the given button to the dialog's content area at the given position. If
+ * the posiion is `-1` the button is appended at the end.
+ */
+void
+phosh_system_modal_dialog_add_button (PhoshSystemModalDialog *self, GtkWidget *button, gint position)
+{
+ PhoshSystemModalDialogPrivate *priv;
+
+ g_return_if_fail (PHOSH_IS_SYSTEM_MODAL_DIALOG (self));
+ g_return_if_fail (GTK_IS_BUTTON (button));
+
+ priv = phosh_system_modal_dialog_get_instance_private (PHOSH_SYSTEM_MODAL_DIALOG (self));
+
+ gtk_box_pack_start (GTK_BOX (priv->box_buttons), GTK_WIDGET (button), TRUE, TRUE, 0);
+ if (position >= 0)
+ gtk_box_reorder_child (GTK_BOX (priv->box_dialog), GTK_WIDGET (button), position);
+}
+
+
+void
+phosh_system_modal_dialog_remove_button (PhoshSystemModalDialog *self, GtkWidget *button)
+{
+ PhoshSystemModalDialogPrivate *priv;
+
+ g_return_if_fail (PHOSH_IS_SYSTEM_MODAL_DIALOG (self));
+ g_return_if_fail (GTK_IS_BUTTON (button));
+ priv = phosh_system_modal_dialog_get_instance_private (PHOSH_SYSTEM_MODAL_DIALOG (self));
+
+ gtk_container_remove (GTK_CONTAINER (priv->box_buttons), button);
+}
+
+
+GList *
+phosh_system_modal_dialog_get_buttons (PhoshSystemModalDialog *self)
+{
+ PhoshSystemModalDialogPrivate *priv;
+
+ g_return_val_if_fail (PHOSH_IS_SYSTEM_MODAL_DIALOG (self), NULL);
+ priv = phosh_system_modal_dialog_get_instance_private (PHOSH_SYSTEM_MODAL_DIALOG (self));
+
+ return gtk_container_get_children (GTK_CONTAINER (priv->box_buttons));
+}
+
+
+void
+phosh_system_modal_dialog_set_title (PhoshSystemModalDialog *self, const gchar *title)
+{
+ PhoshSystemModalDialogPrivate *priv;
+
+ g_return_if_fail (PHOSH_IS_SYSTEM_MODAL_DIALOG (self));
+
+ priv = phosh_system_modal_dialog_get_instance_private (PHOSH_SYSTEM_MODAL_DIALOG (self));
+ g_free (priv->title);
+ priv->title = g_strdup (title);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TITLE]);
+}
diff -Nru phosh-0.8.0/src/system-modal-dialog.h phosh-0.13.1/src/system-modal-dialog.h
--- phosh-0.8.0/src/system-modal-dialog.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/system-modal-dialog.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "system-modal.h"
+
+#include
+
+#define PHOSH_TYPE_SYSTEM_MODAL_DIALOG (phosh_system_modal_dialog_get_type ())
+
+G_DECLARE_DERIVABLE_TYPE (PhoshSystemModalDialog, phosh_system_modal_dialog, PHOSH, SYSTEM_MODAL_DIALOG, PhoshSystemModal)
+
+/**
+ * PhoshSystemModalDialogClass
+ * @parent_class: The parent class
+ */
+struct _PhoshSystemModalDialogClass {
+ PhoshSystemModalClass parent_class;
+};
+
+
+GtkWidget *phosh_system_modal_dialog_new (void);
+void phosh_system_modal_dialog_set_content (PhoshSystemModalDialog *self, GtkWidget *content);
+void phosh_system_modal_dialog_add_button (PhoshSystemModalDialog *self, GtkWidget *button, gint position);
+void phosh_system_modal_dialog_set_title (PhoshSystemModalDialog *self, const gchar *title);
+void phosh_system_modal_dialog_remove_button (PhoshSystemModalDialog *self, GtkWidget *button);
+GList *phosh_system_modal_dialog_get_buttons (PhoshSystemModalDialog *self);
diff -Nru phosh-0.8.0/src/system-modal.h phosh-0.13.1/src/system-modal.h
--- phosh-0.8.0/src/system-modal.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/system-modal.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include
+#include "layersurface.h"
+#include "monitor/monitor.h"
+
+#define PHOSH_TYPE_SYSTEM_MODAL (phosh_system_modal_get_type ())
+
+G_DECLARE_DERIVABLE_TYPE (PhoshSystemModal, phosh_system_modal, PHOSH, SYSTEM_MODAL, PhoshLayerSurface)
+
+/**
+ * PhoshSystemModalClass
+ * @parent_class: The parent class
+ */
+struct _PhoshSystemModalClass {
+ PhoshLayerSurfaceClass parent_class;
+};
+
+
+GtkWidget *phosh_system_modal_new (PhoshMonitor *monitor);
diff -Nru phosh-0.8.0/src/system-prompt.c phosh-0.13.1/src/system-prompt.c
--- phosh-0.8.0/src/system-prompt.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/system-prompt.c 2021-08-31 09:15:52.000000000 +0000
@@ -32,7 +32,6 @@
PROP_0,
/* GcrPromptIface */
- PROP_TITLE,
PROP_MESSAGE,
PROP_DESCRIPTION,
PROP_WARNING,
@@ -62,7 +61,6 @@
typedef struct
{
- char *title;
char *message;
char *description;
char *warning;
@@ -81,7 +79,6 @@
GtkWidget *grid;
GtkWidget *lbl_confirm;
GtkWidget *lbl_description;
- GtkWidget *lbl_message;
GtkWidget *lbl_password;
GtkWidget *lbl_warning;
GtkWidget *pbar_quality;
@@ -98,12 +95,12 @@
struct _PhoshSystemPrompt
{
- PhoshLayerSurface parent;
+ PhoshSystemModalDialog parent;
};
static void phosh_system_prompt_iface_init (GcrPromptIface *iface);
-G_DEFINE_TYPE_WITH_CODE(PhoshSystemPrompt, phosh_system_prompt, PHOSH_TYPE_LAYER_SURFACE,
+G_DEFINE_TYPE_WITH_CODE(PhoshSystemPrompt, phosh_system_prompt, PHOSH_TYPE_SYSTEM_MODAL_DIALOG,
G_IMPLEMENT_INTERFACE (GCR_TYPE_PROMPT,
phosh_system_prompt_iface_init)
G_ADD_PRIVATE (PhoshSystemPrompt));
@@ -119,11 +116,6 @@
PhoshSystemPromptPrivate *priv = phosh_system_prompt_get_instance_private (self);
switch (prop_id) {
- case PROP_TITLE:
- g_free (priv->title);
- priv->title = g_value_dup_string (value);
- g_object_notify (obj, "title");
- break;
case PROP_MESSAGE:
g_free (priv->message);
priv->message = g_value_dup_string (value);
@@ -185,9 +177,6 @@
PhoshSystemPromptPrivate *priv = phosh_system_prompt_get_instance_private (self);
switch (prop_id) {
- case PROP_TITLE:
- g_value_set_string (value, priv->title ? priv->title : "");
- break;
case PROP_MESSAGE:
g_value_set_string (value, priv->message ? priv->message : "");
break;
@@ -506,14 +495,14 @@
static void
-btn_continue_clicked_cb (PhoshSystemPrompt *self, GtkButton *btn)
+on_btn_continue_clicked (PhoshSystemPrompt *self, GtkButton *btn)
{
prompt_complete (self);
}
static void
-btn_cancel_clicked_cb (PhoshSystemPrompt *self, GtkButton *btn)
+on_dialog_canceled (PhoshSystemPrompt *self)
{
prompt_cancel (self);
}
@@ -529,26 +518,6 @@
}
-static gboolean
-on_key_press_event (PhoshSystemPrompt *self, GdkEventKey *event, gpointer data)
-{
- gboolean handled = FALSE;
- g_return_val_if_fail (PHOSH_IS_SYSTEM_PROMPT (self), FALSE);
-
- switch (event->keyval) {
- case GDK_KEY_Escape:
- prompt_cancel (self);
- handled = TRUE;
- break;
- default:
- /* nothing to do */
- break;
- }
-
- return handled;
-}
-
-
static void
phosh_system_prompt_dispose (GObject *obj)
{
@@ -572,7 +541,6 @@
PhoshSystemPrompt *self = PHOSH_SYSTEM_PROMPT (obj);
PhoshSystemPromptPrivate *priv = phosh_system_prompt_get_instance_private (self);
- g_free (priv->title);
g_free (priv->message);
g_free (priv->description);
g_free (priv->warning);
@@ -592,7 +560,7 @@
G_OBJECT_CLASS (phosh_system_prompt_parent_class)->constructed (object);
- g_object_bind_property (self, "message", priv->lbl_message, "label", G_BINDING_DEFAULT);
+ g_object_bind_property (self, "message", self, "title", G_BINDING_DEFAULT);
g_object_bind_property (self, "description", priv->lbl_description, "label", G_BINDING_DEFAULT);
g_object_bind_property (self, "password-visible", priv->lbl_password, "visible", G_BINDING_DEFAULT);
@@ -622,25 +590,9 @@
"active", G_BINDING_BIDIRECTIONAL);
g_object_bind_property (self, "cancel-label", priv->btn_cancel, "label", G_BINDING_DEFAULT);
- g_signal_connect_object (priv->btn_cancel,
- "clicked",
- G_CALLBACK (btn_cancel_clicked_cb),
- self,
- G_CONNECT_SWAPPED);
-
g_object_bind_property (self, "continue-label", priv->btn_continue, "label", G_BINDING_DEFAULT);
- g_signal_connect_object (priv->btn_continue,
- "clicked",
- G_CALLBACK (btn_continue_clicked_cb),
- self,
- G_CONNECT_SWAPPED);
- gtk_widget_grab_default (priv->btn_continue);
- gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
- g_signal_connect (G_OBJECT (self),
- "key_press_event",
- G_CALLBACK (on_key_press_event),
- NULL);
+ gtk_widget_grab_default (priv->btn_continue);
}
@@ -656,7 +608,6 @@
object_class->dispose = phosh_system_prompt_dispose;
object_class->finalize = phosh_system_prompt_finalize;
- g_object_class_override_property (object_class, PROP_TITLE, "title");
g_object_class_override_property (object_class, PROP_MESSAGE, "message");
g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
g_object_class_override_property (object_class, PROP_WARNING, "warning");
@@ -674,7 +625,7 @@
* Whether the password entry is visible or not.
*/
g_object_class_install_property (object_class, PROP_PASSWORD_VISIBLE,
- g_param_spec_boolean ("password-visible", "Password visible", "Password field is visible",
+ g_param_spec_boolean ("password-visible", "", "",
FALSE, G_PARAM_READABLE));
/**
@@ -683,7 +634,7 @@
* Whether the password confirm entry is visible or not.
*/
g_object_class_install_property (object_class, PROP_CONFIRM_VISIBLE,
- g_param_spec_boolean ("confirm-visible", "Confirm visible", "Confirm field is visible",
+ g_param_spec_boolean ("confirm-visible", "", "",
FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
@@ -692,7 +643,7 @@
* Whether the warning label is visible or not.
*/
g_object_class_install_property (object_class, PROP_WARNING_VISIBLE,
- g_param_spec_boolean ("warning-visible", "Warning visible", "Warning is visible",
+ g_param_spec_boolean ("warning-visible", "", "",
FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
@@ -701,13 +652,12 @@
* Whether the choice check box is visible or not.
*/
g_object_class_install_property (object_class, PROP_CHOICE_VISIBLE,
- g_param_spec_boolean ("choice-visible", "Choice visible", "Choice is visible",
+ g_param_spec_boolean ("choice-visible", "", "",
FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
gtk_widget_class_set_template_from_resource (widget_class,
"/sm/puri/phosh/ui/system-prompt.ui");
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, grid);
- gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, lbl_message);
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, lbl_description);
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, lbl_password);
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, entry_password);
@@ -718,7 +668,8 @@
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, checkbtn_choice);
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, btn_cancel);
gtk_widget_class_bind_template_child_private (widget_class, PhoshSystemPrompt, btn_continue);
-
+ gtk_widget_class_bind_template_callback (widget_class, on_dialog_canceled);
+ gtk_widget_class_bind_template_callback (widget_class, on_btn_continue_clicked);
}
@@ -738,19 +689,7 @@
GtkWidget *
-phosh_system_prompt_new (gpointer layer_shell,
- gpointer wl_output)
+phosh_system_prompt_new (void)
{
- return g_object_new (PHOSH_TYPE_SYSTEM_PROMPT,
- "layer-shell", layer_shell,
- "wl-output", wl_output,
- "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
- "layer", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
- "kbd-interactivity", TRUE,
- "exclusive-zone", -1,
- "namespace", "phosh prompter",
- NULL);
+ return g_object_new (PHOSH_TYPE_SYSTEM_PROMPT, NULL);
}
diff -Nru phosh-0.8.0/src/system-prompter.c phosh-0.13.1/src/system-prompter.c
--- phosh-0.8.0/src/system-prompter.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/system-prompter.c 2021-08-31 09:15:52.000000000 +0000
@@ -33,15 +33,12 @@
new_prompt_cb (GcrSystemPrompter *prompter,
gpointer user_data)
{
- PhoshWayland *wl = phosh_wayland_get_default ();
- PhoshShell *shell = phosh_shell_get_default ();
GtkWidget *prompt;
g_debug ("Building new system prompt");
g_return_val_if_fail (GCR_IS_SYSTEM_PROMPTER (prompter), NULL);
- prompt = phosh_system_prompt_new (phosh_wayland_get_zwlr_layer_shell_v1 (wl),
- phosh_shell_get_primary_monitor (shell)->wl_output);
+ prompt = phosh_system_prompt_new ();
/* Show widget when not locked and keep that in sync */
g_object_bind_property (phosh_shell_get_default (), "locked",
@@ -78,6 +75,7 @@
if (connection == NULL) {
g_warning ("couldn't connect to session bus");
phosh_system_prompter_unregister ();
+ registered_prompter = FALSE;
}
}
@@ -116,13 +114,17 @@
phosh_system_prompter_unregister(void)
{
if (_prompter) {
- gcr_system_prompter_unregister (_prompter, TRUE);
- _prompter = NULL;
+ if (registered_prompter) {
+ gcr_system_prompter_unregister (_prompter, TRUE);
+ registered_prompter = FALSE;
+ }
+ g_clear_object (&_prompter);
}
- if (acquired_prompter) {
+ if (owner_id) {
g_bus_unown_name (owner_id);
owner_id = 0;
- acquired_prompter = FALSE;
}
+
+ acquired_prompter = FALSE;
}
diff -Nru phosh-0.8.0/src/system-prompt.h phosh-0.13.1/src/system-prompt.h
--- phosh-0.8.0/src/system-prompt.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/system-prompt.h 2021-08-31 09:15:52.000000000 +0000
@@ -7,11 +7,14 @@
#pragma once
#include
-#include "layersurface.h"
+#include "system-modal-dialog.h"
+
+G_BEGIN_DECLS
#define PHOSH_TYPE_SYSTEM_PROMPT (phosh_system_prompt_get_type())
-G_DECLARE_FINAL_TYPE (PhoshSystemPrompt, phosh_system_prompt, PHOSH, SYSTEM_PROMPT, PhoshLayerSurface)
+G_DECLARE_FINAL_TYPE (PhoshSystemPrompt, phosh_system_prompt, PHOSH, SYSTEM_PROMPT, PhoshSystemModalDialog)
+
+GtkWidget *phosh_system_prompt_new (void);
-GtkWidget *phosh_system_prompt_new (gpointer layer_shell,
- gpointer wl_output);
+G_END_DECLS
diff -Nru phosh-0.8.0/src/toplevel-manager.c phosh-0.13.1/src/toplevel-manager.c
--- phosh-0.8.0/src/toplevel-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/toplevel-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -41,6 +41,7 @@
struct _PhoshToplevelManager {
GObject parent;
GPtrArray *toplevels;
+ GPtrArray *toplevels_pending;
};
G_DEFINE_TYPE (PhoshToplevelManager, phosh_toplevel_manager, G_TYPE_OBJECT);
@@ -79,6 +80,16 @@
g_return_if_fail (PHOSH_IS_TOPLEVEL_MANAGER (self));
g_return_if_fail (PHOSH_IS_TOPLEVEL (toplevel));
g_return_if_fail (self->toplevels);
+ g_return_if_fail (self->toplevels_pending);
+
+ /* Check if toplevel exists in toplevels_pending, in that case it is
+ * not yet configured and we just remove it from toplevels_pending
+ * without touching the regular toplevels array. */
+ if (g_ptr_array_find (self->toplevels_pending, toplevel, NULL)) {
+ g_assert_true (g_ptr_array_remove (self->toplevels_pending, toplevel));
+ g_object_unref (toplevel);
+ return;
+ }
g_assert_true(g_ptr_array_remove (self->toplevels, toplevel));
@@ -93,6 +104,7 @@
g_return_if_fail (PHOSH_IS_TOPLEVEL_MANAGER (self));
g_return_if_fail (PHOSH_IS_TOPLEVEL (toplevel));
g_return_if_fail (self->toplevels);
+ g_return_if_fail (self->toplevels_pending);
configured = phosh_toplevel_is_configured (toplevel);
@@ -102,6 +114,7 @@
if (g_ptr_array_find (self->toplevels, toplevel, NULL)) {
g_signal_emit (self, signals[SIGNAL_TOPLEVEL_CHANGED], 0, toplevel);
} else {
+ g_assert_true (g_ptr_array_remove (self->toplevels_pending, toplevel));
g_ptr_array_add (self->toplevels, toplevel);
g_signal_emit (self, signals[SIGNAL_TOPLEVEL_ADDED], 0, toplevel);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_NUM_TOPLEVELS]);
@@ -120,6 +133,8 @@
g_return_if_fail (PHOSH_IS_TOPLEVEL_MANAGER (self));
toplevel = phosh_toplevel_new_from_handle (handle);
+ g_ptr_array_add (self->toplevels_pending, toplevel);
+
g_signal_connect_swapped (toplevel, "closed", G_CALLBACK (on_toplevel_closed), self);
g_signal_connect_swapped (toplevel, "notify::configured", G_CALLBACK (on_toplevel_configured), self);
@@ -150,6 +165,10 @@
g_ptr_array_free(self->toplevels, TRUE);
self->toplevels = NULL;
}
+ if (self->toplevels_pending) {
+ g_ptr_array_free (self->toplevels_pending, TRUE);
+ self->toplevels_pending = NULL;
+ }
G_OBJECT_CLASS (phosh_toplevel_manager_parent_class)->dispose (object);
}
@@ -208,6 +227,7 @@
phosh_wayland_get_default ());
self->toplevels = g_ptr_array_new_with_free_func ((GDestroyNotify) (g_object_unref));
+ self->toplevels_pending = g_ptr_array_new ();
if (!toplevel_manager) {
g_warning ("Skipping app list due to missing wlr-foreign-toplevel-management protocol extension");
diff -Nru phosh-0.8.0/src/top-panel.c phosh-0.13.1/src/top-panel.c
--- phosh-0.8.0/src/top-panel.c 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/top-panel.c 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) 2018 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Author: Guido Günther
+ *
+ * Somewhat based on maynard's panel which is
+ * Copyright (C) 2014 Collabora Ltd. *
+ * Author: Jonny Lamb
+ */
+
+#define G_LOG_DOMAIN "phosh-top-panel"
+
+#include "config.h"
+
+#include "shell.h"
+#include "session-manager.h"
+#include "settings.h"
+#include "top-panel.h"
+#include "util.h"
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include
+#include
+
+#include
+
+/**
+ * SECTION:top-panel
+ * @short_description: The top panel
+ * @Title: PhoshTopPanel
+ *
+ * The top panel containing the clock and status indicators. When activated
+ * int unfolds the #PhoshSettings.
+ */
+
+enum {
+ SETTINGS_ACTIVATED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = { 0 };
+
+typedef struct _PhoshTopPanel {
+ PhoshLayerSurface parent;
+
+ PhoshTopPanelState state;
+
+ GtkWidget *btn_power;
+ GtkWidget *menu_power;
+ GtkWidget *stack;
+ GtkWidget *box; /* main content box */
+ GtkWidget *btn_top_panel;
+ GtkWidget *lbl_clock;
+ GtkWidget *lbl_lang;
+ GtkWidget *settings; /* settings menu */
+ GtkWidget *batteryinfo;
+
+ GnomeWallClock *wall_clock;
+ GnomeXkbInfo *xkbinfo;
+ GSettings *input_settings;
+ GSettings *interface_settings;
+ GdkSeat *seat;
+
+ GSimpleActionGroup *actions;
+} PhoshTopPanel;
+
+G_DEFINE_TYPE (PhoshTopPanel, phosh_top_panel, PHOSH_TYPE_LAYER_SURFACE)
+
+
+static void
+on_shutdown_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ PhoshTopPanel *self = PHOSH_TOP_PANEL(data);
+ PhoshSessionManager *sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ phosh_session_manager_shutdown (sm);
+ phosh_top_panel_fold (self);
+}
+
+
+static void
+on_restart_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ PhoshTopPanel *self = PHOSH_TOP_PANEL(data);
+ PhoshSessionManager *sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ g_return_if_fail (PHOSH_IS_SESSION_MANAGER (sm));
+
+ phosh_session_manager_reboot (sm);
+ phosh_top_panel_fold (self);
+}
+
+
+static void
+on_lockscreen_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ PhoshTopPanel *self = PHOSH_TOP_PANEL(data);
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ phosh_shell_lock (phosh_shell_get_default ());
+ phosh_top_panel_fold (self);
+}
+
+
+static void
+on_logout_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ PhoshTopPanel *self = PHOSH_TOP_PANEL(data);
+ PhoshSessionManager *sm = phosh_shell_get_session_manager (phosh_shell_get_default ());
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ g_return_if_fail (PHOSH_IS_SESSION_MANAGER (sm));
+ phosh_session_manager_logout (sm);
+ phosh_top_panel_fold (self);
+}
+
+
+static void
+top_panel_clicked_cb (PhoshTopPanel *self, GtkButton *btn)
+{
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ g_return_if_fail (GTK_IS_BUTTON (btn));
+ g_signal_emit(self, signals[SETTINGS_ACTIVATED], 0);
+}
+
+
+static void
+wall_clock_notify_cb (PhoshTopPanel *self,
+ GParamSpec *pspec,
+ GnomeWallClock *wall_clock)
+{
+ const char *str;
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ g_return_if_fail (GNOME_IS_WALL_CLOCK (wall_clock));
+
+ str = gnome_wall_clock_get_clock(wall_clock);
+ gtk_label_set_text (GTK_LABEL (self->lbl_clock), str);
+}
+
+
+static gboolean
+needs_keyboard_label (PhoshTopPanel *self)
+{
+ GList *slaves;
+ g_autoptr(GVariant) sources = NULL;
+
+ g_return_val_if_fail (GDK_IS_SEAT (self->seat), FALSE);
+ g_return_val_if_fail (G_IS_SETTINGS (self->input_settings), FALSE);
+
+ sources = g_settings_get_value(self->input_settings, "sources");
+ if (g_variant_n_children (sources) < 2)
+ return FALSE;
+
+ slaves = gdk_seat_get_slaves (self->seat, GDK_SEAT_CAPABILITY_KEYBOARD);
+ if (!slaves)
+ return FALSE;
+
+ g_list_free (slaves);
+ return TRUE;
+}
+
+
+static void
+on_seat_device_changed (PhoshTopPanel *self, GdkDevice *device, GdkSeat *seat)
+{
+ gboolean visible;
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+ g_return_if_fail (GDK_IS_SEAT (seat));
+
+ visible = needs_keyboard_label (self);
+ gtk_widget_set_visible (self->lbl_lang, visible);
+}
+
+
+static void
+on_input_setting_changed (PhoshTopPanel *self,
+ const char *key,
+ GSettings *settings)
+{
+ g_autoptr(GVariant) sources = NULL;
+ GVariantIter iter;
+ g_autofree char *id = NULL;
+ g_autofree char *type = NULL;
+ const char *name;
+
+ if (!needs_keyboard_label (self)) {
+ gtk_widget_hide (self->lbl_lang);
+ return;
+ }
+
+ sources = g_settings_get_value(settings, "sources");
+ g_variant_iter_init (&iter, sources);
+ g_variant_iter_next (&iter, "(ss)", &type, &id);
+
+ if (g_strcmp0 (type, "xkb")) {
+ g_debug ("Not a xkb layout: '%s' - ignoring", id);
+ return;
+ }
+
+ if (!gnome_xkb_info_get_layout_info (self->xkbinfo, id,
+ NULL, &name, NULL, NULL)) {
+ g_debug ("Failed to get layout info for %s", id);
+ name = id;
+ }
+ g_debug ("Layout is %s", name);
+ gtk_label_set_text (GTK_LABEL (self->lbl_lang), name);
+ gtk_widget_show (self->lbl_lang);
+}
+
+
+static gboolean
+on_key_press_event (PhoshTopPanel *self, GdkEventKey *event, gpointer data)
+{
+ gboolean handled = FALSE;
+
+ g_return_val_if_fail (PHOSH_IS_TOP_PANEL (self), FALSE);
+
+ if (!self->settings)
+ return handled;
+
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ phosh_top_panel_fold (self);
+ handled = TRUE;
+ break;
+ default:
+ /* nothing to do */
+ break;
+ }
+ return handled;
+}
+
+
+static gboolean
+on_button_press_event (PhoshTopPanel *self, GdkEventButton *event, gpointer data)
+{
+ phosh_trigger_feedback ("button-pressed");
+
+ /*
+ * The popover has to be popdown manually as it doesn't happen
+ * automatically when the power button is tapped with touch
+ */
+ if (gtk_widget_is_visible (self->menu_power))
+ gtk_popover_popdown (GTK_POPOVER (self->menu_power));
+ else
+ phosh_top_panel_fold (self);
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+
+static GActionEntry entries[] = {
+ { "poweroff", on_shutdown_action, NULL, NULL, NULL },
+ { "restart", on_restart_action, NULL, NULL, NULL },
+ { "lockscreen", on_lockscreen_action, NULL, NULL, NULL },
+ { "logout", on_logout_action, NULL, NULL, NULL },
+};
+
+
+static void
+phosh_top_panel_constructed (GObject *object)
+{
+ PhoshTopPanel *self = PHOSH_TOP_PANEL (object);
+ GdkDisplay *display = gdk_display_get_default ();
+
+ G_OBJECT_CLASS (phosh_top_panel_parent_class)->constructed (object);
+
+ self->state = PHOSH_TOP_PANEL_STATE_FOLDED;
+ self->wall_clock = gnome_wall_clock_new ();
+
+ g_signal_connect_object (self->wall_clock,
+ "notify::clock",
+ G_CALLBACK (wall_clock_notify_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->btn_top_panel,
+ "clicked",
+ G_CALLBACK (top_panel_clicked_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ phosh_connect_feedback (self->btn_top_panel);
+
+ gtk_window_set_title (GTK_WINDOW (self), "phosh panel");
+
+ /* Button properites */
+ gtk_style_context_remove_class (gtk_widget_get_style_context (self->btn_top_panel),
+ "button");
+ gtk_style_context_remove_class (gtk_widget_get_style_context (self->btn_top_panel),
+ "image-button");
+
+ wall_clock_notify_cb (self, NULL, self->wall_clock);
+
+ /* language indicator */
+ if (display) {
+ self->input_settings = g_settings_new ("org.gnome.desktop.input-sources");
+ self->xkbinfo = gnome_xkb_info_new ();
+ self->seat = gdk_display_get_default_seat (display);
+ g_object_connect (self->seat,
+ "swapped_signal::device-added", G_CALLBACK (on_seat_device_changed), self,
+ "swapped_signal::device-removed", G_CALLBACK (on_seat_device_changed), self,
+ NULL);
+ g_signal_connect_swapped (self->input_settings,
+ "changed::sources", G_CALLBACK (on_input_setting_changed),
+ self);
+ on_input_setting_changed (self, NULL, self->input_settings);
+ }
+
+ /* Settings menu and it's top-bar / menu */
+ gtk_widget_add_events (GTK_WIDGET (self), GDK_KEY_PRESS_MASK);
+ g_signal_connect (G_OBJECT (self),
+ "key-press-event",
+ G_CALLBACK (on_key_press_event),
+ NULL);
+ g_signal_connect (G_OBJECT (self),
+ "button-press-event",
+ G_CALLBACK (on_button_press_event),
+ NULL);
+ g_signal_connect_swapped (self->settings,
+ "setting-done",
+ G_CALLBACK (phosh_top_panel_fold),
+ self);
+
+ self->actions = g_simple_action_group_new ();
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "panel",
+ G_ACTION_GROUP (self->actions));
+ g_action_map_add_action_entries (G_ACTION_MAP (self->actions),
+ entries, G_N_ELEMENTS (entries),
+ self);
+ if (!phosh_shell_started_by_display_manager (phosh_shell_get_default ())) {
+ GAction *action = g_action_map_lookup_action (G_ACTION_MAP (self->actions),
+ "logout");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
+ }
+
+ self->interface_settings = g_settings_new ("org.gnome.desktop.interface");
+ g_settings_bind (self->interface_settings,
+ "show-battery-percentage",
+ self->batteryinfo,
+ "show-detail",
+ G_SETTINGS_BIND_GET);
+}
+
+
+static void
+phosh_top_panel_dispose (GObject *object)
+{
+ PhoshTopPanel *self = PHOSH_TOP_PANEL (object);
+
+ g_clear_object (&self->wall_clock);
+ g_clear_object (&self->xkbinfo);
+ g_clear_object (&self->input_settings);
+ g_clear_object (&self->interface_settings);
+ g_clear_object (&self->actions);
+ self->seat = NULL;
+
+ G_OBJECT_CLASS (phosh_top_panel_parent_class)->dispose (object);
+}
+
+
+static void
+phosh_top_panel_class_init (PhoshTopPanelClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *)klass;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = phosh_top_panel_constructed;
+ object_class->dispose = phosh_top_panel_dispose;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-top-panel");
+
+ signals[SETTINGS_ACTIVATED] = g_signal_new ("settings-activated",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ NULL, G_TYPE_NONE, 0);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/sm/puri/phosh/ui/top-panel.ui");
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, btn_power);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, menu_power);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, btn_top_panel);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, batteryinfo);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, lbl_clock);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, lbl_lang);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, box);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, stack);
+ gtk_widget_class_bind_template_child (widget_class, PhoshTopPanel, settings);
+}
+
+
+static void
+phosh_top_panel_init (PhoshTopPanel *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+
+GtkWidget *
+phosh_top_panel_new (struct zwlr_layer_shell_v1 *layer_shell,
+ struct wl_output *wl_output)
+{
+ return g_object_new (PHOSH_TYPE_TOP_PANEL,
+ "layer-shell", layer_shell,
+ "wl-output", wl_output,
+ "height", PHOSH_TOP_PANEL_HEIGHT,
+ "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
+ "layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
+ "kbd-interactivity", FALSE,
+ "exclusive-zone", PHOSH_TOP_PANEL_HEIGHT,
+ "namespace", "phosh",
+ NULL);
+}
+
+
+void
+phosh_top_panel_fold (PhoshTopPanel *self)
+{
+ int width;
+
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+
+ if (self->state == PHOSH_TOP_PANEL_STATE_FOLDED)
+ return;
+
+ gtk_widget_hide (self->menu_power);
+ gtk_stack_set_transition_type (GTK_STACK (self->stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP);
+ gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "topbar");
+ gtk_widget_hide (self->settings);
+ phosh_layer_surface_set_kbd_interactivity (PHOSH_LAYER_SURFACE (self), FALSE);
+ gtk_window_get_size (GTK_WINDOW (self), &width, NULL);
+ gtk_window_resize (GTK_WINDOW (self), width, PHOSH_TOP_PANEL_HEIGHT);
+ self->state = PHOSH_TOP_PANEL_STATE_FOLDED;
+}
+
+
+void
+phosh_top_panel_unfold (PhoshTopPanel *self)
+{
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+
+ if (self->state == PHOSH_TOP_PANEL_STATE_UNFOLDED)
+ return;
+
+ phosh_layer_surface_set_kbd_interactivity (PHOSH_LAYER_SURFACE (self), TRUE);
+ gtk_widget_show (self->settings);
+ gtk_stack_set_transition_type (GTK_STACK (self->stack), GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN);
+ gtk_stack_set_visible_child_name(GTK_STACK (self->stack), "settings");
+ self->state =PHOSH_TOP_PANEL_STATE_UNFOLDED;
+}
+
+
+void
+phosh_top_panel_toggle_fold (PhoshTopPanel *self)
+{
+ g_return_if_fail (PHOSH_IS_TOP_PANEL (self));
+
+ if (self->state == PHOSH_TOP_PANEL_STATE_UNFOLDED) {
+ phosh_top_panel_fold (self);
+ } else {
+ phosh_top_panel_unfold (self);
+ }
+}
+
+
+PhoshTopPanelState
+phosh_top_panel_get_state (PhoshTopPanel *self)
+{
+ g_return_val_if_fail (PHOSH_IS_TOP_PANEL (self), PHOSH_TOP_PANEL_STATE_FOLDED);
+
+ return self->state;
+}
diff -Nru phosh-0.8.0/src/top-panel.h phosh-0.13.1/src/top-panel.h
--- phosh-0.8.0/src/top-panel.h 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/top-panel.h 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 Purism SPC
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "layersurface.h"
+
+#define PHOSH_TYPE_TOP_PANEL (phosh_top_panel_get_type ())
+
+G_DECLARE_FINAL_TYPE (PhoshTopPanel, phosh_top_panel, PHOSH, TOP_PANEL, PhoshLayerSurface)
+
+#define PHOSH_TOP_PANEL_HEIGHT 32
+
+/**
+ * PhoshTopPanelState:
+ * @PHOSH_TOP_PANEL_STATE_FOLDED: Only top-bar is visible
+ * @PHOSH_TOP_PANEL_STATE_UNFOLDED: Settings menu is unfolded
+ */
+typedef enum {
+ PHOSH_TOP_PANEL_STATE_FOLDED,
+ PHOSH_TOP_PANEL_STATE_UNFOLDED,
+} PhoshTopPanelState;
+
+GtkWidget *phosh_top_panel_new (struct zwlr_layer_shell_v1 *layer_shell,
+ struct wl_output *wl_output);
+void phosh_top_panel_toggle_fold (PhoshTopPanel *self);
+void phosh_top_panel_fold (PhoshTopPanel *self);
+void phosh_top_panel_unfold (PhoshTopPanel *self);
+PhoshTopPanelState phosh_top_panel_get_state (PhoshTopPanel *self);
diff -Nru phosh-0.8.0/src/torch-info.c phosh-0.13.1/src/torch-info.c
--- phosh-0.8.0/src/torch-info.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/torch-info.c 2021-08-31 09:15:52.000000000 +0000
@@ -87,7 +87,6 @@
{
gboolean enabled;
- g_debug ("Updating torch status");
g_return_if_fail (PHOSH_IS_TORCH_INFO (self));
g_return_if_fail (PHOSH_IS_TORCH_MANAGER (torch));
@@ -96,6 +95,8 @@
return;
self->enabled = enabled;
+ g_debug ("Updating torch enabled: %d", enabled);
+
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ENABLED]);
}
@@ -117,9 +118,11 @@
}
-static gboolean
-on_idle (PhoshTorchInfo *self)
+static void
+phosh_torch_info_idle_init (PhoshStatusIcon *icon)
{
+ PhoshTorchInfo *self = PHOSH_TORCH_INFO (icon);
+
g_object_bind_property (self->torch, "icon-name", self, "icon-name",
G_BINDING_SYNC_CREATE);
@@ -142,8 +145,6 @@
G_CALLBACK (on_torch_present),
self);
on_torch_present (self, NULL, self->torch);
-
- return FALSE;
}
@@ -162,8 +163,6 @@
g_warning ("Failed to get torch manager");
return;
}
-
- g_idle_add ((GSourceFunc) on_idle, self);
}
@@ -185,11 +184,17 @@
phosh_torch_info_class_init (PhoshTorchInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshStatusIconClass *status_icon_class = PHOSH_STATUS_ICON_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_torch_info_constructed;
object_class->dispose = phosh_torch_info_dispose;
object_class->get_property = phosh_torch_info_get_property;
+ status_icon_class->idle_init = phosh_torch_info_idle_init;
+
+ gtk_widget_class_set_css_name (widget_class, "phosh-torch-info");
+
props[PROP_ENABLED] =
g_param_spec_boolean ("enabled",
"enabled",
diff -Nru phosh-0.8.0/src/torch-manager.c phosh-0.13.1/src/torch-manager.c
--- phosh-0.8.0/src/torch-manager.c 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/torch-manager.c 2021-08-31 09:15:52.000000000 +0000
@@ -10,12 +10,17 @@
#include "config.h"
+#include
+
#include "torch-manager.h"
#include "shell.h"
-#include "dbus/upower-torch-dbus.h"
+#include "util.h"
+#include "dbus/login1-session-dbus.h"
+
+#define BUS_NAME "org.freedesktop.login1"
+#define OBJECT_PATH "/org/freedesktop/login1/session/auto"
-#define BUS_NAME "org.freedesktop.UPower"
-#define OBJECT_PATH "/org/freedesktop/UPower/Torch"
+#define TORCH_SUBSYSTEM "leds"
#define TORCH_DISABLED_ICON "torch-disabled-symbolic"
#define TORCH_ENABLED_ICON "torch-enabled-symbolic"
@@ -40,41 +45,84 @@
static GParamSpec *props[PROP_LAST_PROP];
struct _PhoshTorchManager {
- GObject parent;
+ PhoshManager parent;
+
+ /* Whether we found a torch device */
+ gboolean present;
+ const char *icon_name;
+ int brightness;
+ int max_brightness;
+ int last_brightness;
- /* Whether upower sees a torch device */
- gboolean present;
- const char *icon_name;
- int brightness;
- int max_brightness;
- int last_brightness;
+ GUdevClient *udev_client;
+ GUdevDevice *udev_device;
- PhoshUPowerDBusTorch *proxy;
+ PhoshLogin1SessionDBusLoginSession *proxy;
+ GCancellable *cancel;
};
-G_DEFINE_TYPE (PhoshTorchManager, phosh_torch_manager, G_TYPE_OBJECT);
+G_DEFINE_TYPE (PhoshTorchManager, phosh_torch_manager, PHOSH_TYPE_MANAGER);
static void
-on_brightness_set (PhoshUPowerDBusTorch *proxy,
- GAsyncResult *res,
- PhoshTorchManager *self)
+apply_brightness (PhoshTorchManager *self)
+{
+ const char *icon_name;
+
+ g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
+ g_return_if_fail (G_UDEV_IS_DEVICE (self->udev_device));
+
+ g_object_freeze_notify (G_OBJECT (self));
+
+ self->brightness = g_udev_device_get_sysfs_attr_as_int_uncached (self->udev_device,
+ "brightness");
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_BRIGHTNESS]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ENABLED]);
+
+ icon_name = self->brightness ? TORCH_ENABLED_ICON : TORCH_DISABLED_ICON;
+ if (icon_name != self->icon_name) {
+ self->icon_name = icon_name;
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
+ }
+
+ g_object_thaw_notify (G_OBJECT (self));
+}
+
+static void
+on_brightness_set (PhoshLogin1SessionDBusLoginSession *proxy,
+ GAsyncResult *res,
+ PhoshTorchManager *self)
{
g_autoptr (GError) err = NULL;
- if (!phosh_upower_dbus_torch_call_set_brightness_finish (proxy, res, &err)) {
- g_warning ("Failed to set torch brighness: %s", err->message);
+ g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
+ g_return_if_fail (PHOSH_LOGIN1_SESSION_DBUS_IS_LOGIN_SESSION (proxy));
+
+ if (!phosh_login1_session_dbus_login_session_call_set_brightness_finish (proxy, res, &err)) {
+ g_warning ("Failed to set torch brigthness: %s", err->message);
+ return;
}
- g_object_unref (self);
+
+ apply_brightness (self);
}
static void
set_brightness (PhoshTorchManager *self, int brightness)
{
- phosh_upower_dbus_torch_call_set_brightness (self->proxy, brightness,
- NULL,
- (GAsyncReadyCallback) on_brightness_set,
- g_object_ref (self));
+ g_return_if_fail (G_UDEV_IS_DEVICE (self->udev_device));
+
+ if (self->brightness == brightness)
+ return;
+
+ g_debug("Setting brightness to %d", brightness);
+
+ phosh_login1_session_dbus_login_session_call_set_brightness (self->proxy,
+ TORCH_SUBSYSTEM,
+ g_udev_device_get_name (self->udev_device),
+ (guint) brightness,
+ NULL,
+ (GAsyncReadyCallback) on_brightness_set,
+ self);
}
static void
@@ -106,92 +154,96 @@
static void
-on_torch_brightness_changed (PhoshTorchManager *self,
- GParamSpec *pspec,
- PhoshUPowerDBusTorch *proxy)
+get_first_torch_device (gpointer data, gpointer manager)
{
- int brightness;
- const char *icon_name;
+ PhoshTorchManager *self = PHOSH_TORCH_MANAGER (manager);
+ GUdevDevice *device = G_UDEV_DEVICE (data);
- g_autoptr (GError) err = NULL;
-
- g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
- g_return_if_fail (PHOSH_UPOWER_DBUS_IS_TORCH (proxy));
+ /* Keep only the first torch device found */
+ if (!self->udev_device)
+ self->udev_device = g_object_ref (device);
+}
- brightness = phosh_upower_dbus_torch_get_brightness (proxy);
- if (brightness == self->brightness)
- return;
+static gboolean
+find_torch_device (PhoshTorchManager *self)
+{
+ g_autoptr (GUdevEnumerator) udev_enumerator = NULL;
+ g_autolist (GUdevDevice) device_list = NULL;
- g_debug ("Torch brightness: %d", brightness);
+ self->udev_device = NULL;
- g_object_freeze_notify (G_OBJECT (self));
- g_object_notify_by_pspec (G_OBJECT (self), props[PROP_BRIGHTNESS]);
+ udev_enumerator = g_udev_enumerator_new (self->udev_client);
+ g_udev_enumerator_add_match_subsystem (udev_enumerator, TORCH_SUBSYSTEM);
+ g_udev_enumerator_add_match_name (udev_enumerator, "*:torch");
+ g_udev_enumerator_add_match_name (udev_enumerator, "*:flash");
+
+ device_list = g_udev_enumerator_execute (udev_enumerator);
+ if (!device_list) {
+ g_warning ("Failed to find a torch device");
+ return FALSE;
+ }
- if (!!self->brightness != !!brightness)
- g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ENABLED]);
- self->brightness = brightness;
+ g_list_foreach (device_list, get_first_torch_device, self);
- icon_name = self->brightness ? TORCH_ENABLED_ICON : TORCH_DISABLED_ICON;
- if (icon_name != self->icon_name) {
- self->icon_name = icon_name;
- g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
+ if (!self->udev_device) {
+ g_warning ("Failed to find a usable torch device");
+ return FALSE;
}
- g_object_thaw_notify (G_OBJECT (self));
+ self->max_brightness = g_udev_device_get_sysfs_attr_as_int (self->udev_device,
+ "max_brightness");
+ g_debug("Found torch device '%s' with max brightness %d",
+ g_udev_device_get_name (self->udev_device), self->max_brightness);
+ return TRUE;
}
static void
-on_get_max_brightness_finished (PhoshUPowerDBusTorch *proxy,
- GAsyncResult *res,
- PhoshTorchManager *self)
+on_proxy_new_for_bus_finish (GObject *source_object,
+ GAsyncResult *res,
+ PhoshTorchManager *self)
{
g_autoptr (GError) err = NULL;
- gboolean present = TRUE;
- int value;
+ PhoshLogin1SessionDBusLoginSession *proxy;
- if (phosh_upower_dbus_torch_call_get_max_brightness_finish (proxy, &value, res, &err)) {
- self->max_brightness = value;
- } else {
- g_debug ("Failed to get torch brightness: %s", err->message);
- present = FALSE;
+ proxy = phosh_login1_session_dbus_login_session_proxy_new_for_bus_finish (res, &err);
+ if (!proxy) {
+ phosh_async_error_warn (err, "Failed to get login1 session proxy");
+ return;
}
- if (self->present != present) {
- self->present = present;
+ g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
+ self->proxy = proxy;
+
+ self->present = find_torch_device (self);
+ if (self->present) {
+ g_object_freeze_notify (G_OBJECT (self));
+
+ apply_brightness (self);
+
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PRESENT]);
+ g_object_thaw_notify (G_OBJECT (self));
}
-
- g_debug ("Torch present: %d", self->present);
- g_object_unref (self);
}
static void
-on_name_owner_changed (PhoshTorchManager *self,
- GParamSpec *pspec,
- PhoshUPowerDBusTorch *proxy)
+phosh_torch_manager_idle_init (PhoshManager *manager)
{
- g_autofree char *owner = NULL;
- gboolean present;
-
- g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
- g_return_if_fail (G_IS_DBUS_PROXY (proxy));
+ PhoshTorchManager *self = PHOSH_TORCH_MANAGER (manager);
+ const char * const subsystems[] = { TORCH_SUBSYSTEM, NULL };
- owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
- present = owner ? TRUE : FALSE;
- /* Name owner went away */
- if (!present && self->present) {
- self->present = present;
- g_debug ("Torch present: %d", self->present);
- g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PRESENT]);
- return;
- }
+ self->udev_client = g_udev_client_new (subsystems);
+ g_return_if_fail (self->udev_client != NULL);
- /* Check max brightness as indicator if we can drive that DBus interface */
- phosh_upower_dbus_torch_call_get_max_brightness (
- proxy, NULL, (GAsyncReadyCallback)on_get_max_brightness_finished,
- g_object_ref (self));
+ self->cancel = g_cancellable_new ();
+ phosh_login1_session_dbus_login_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ BUS_NAME,
+ OBJECT_PATH,
+ self->cancel,
+ (GAsyncReadyCallback) on_proxy_new_for_bus_finish,
+ self);
}
@@ -200,8 +252,14 @@
{
PhoshTorchManager *self = PHOSH_TORCH_MANAGER(object);
+ g_cancellable_cancel (self->cancel);
+ g_clear_object (&self->cancel);
+
g_clear_object (&self->proxy);
+ g_clear_object (&self->udev_client);
+ g_clear_object (&self->udev_device);
+
G_OBJECT_CLASS (phosh_torch_manager_parent_class)->dispose (object);
}
@@ -210,10 +268,13 @@
phosh_torch_manager_class_init (PhoshTorchManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PhoshManagerClass *manager_class = PHOSH_MANAGER_CLASS (klass);
object_class->get_property = phosh_torch_manager_get_property;
object_class->dispose = phosh_torch_manager_dispose;
+ manager_class->idle_init = phosh_torch_manager_idle_init;
+
props[PROP_ICON_NAME] =
g_param_spec_string ("icon-name",
"icon name",
@@ -255,61 +316,10 @@
static void
-on_proxy_new_for_bus_finish (GObject *source_object,
- GAsyncResult *res,
- PhoshTorchManager *self)
-{
- g_autoptr (GError) err = NULL;
-
- g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
-
- self->proxy = phosh_upower_dbus_torch_proxy_new_for_bus_finish (res, &err);
-
- if (!self->proxy) {
- g_warning ("Failed to get upower torch proxy: %s", err->message);
- goto out;
- }
-
- g_signal_connect_object (self->proxy,
- "notify::g-name-owner",
- G_CALLBACK (on_name_owner_changed),
- self,
- G_CONNECT_SWAPPED);
- on_name_owner_changed (self, NULL, self->proxy);
- g_signal_connect_object (self->proxy,
- "notify::brightness",
- G_CALLBACK (on_torch_brightness_changed),
- self,
- G_CONNECT_SWAPPED);
- on_torch_brightness_changed (self, NULL, self->proxy);
-
- g_debug ("Torch manager initialized");
-out:
- g_object_unref (self);
-}
-
-
-static gboolean
-on_idle (PhoshTorchManager *self)
-{
- phosh_upower_dbus_torch_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- BUS_NAME,
- OBJECT_PATH,
- NULL,
- (GAsyncReadyCallback) on_proxy_new_for_bus_finish,
- g_object_ref (self));
- return G_SOURCE_REMOVE;
-}
-
-
-static void
phosh_torch_manager_init (PhoshTorchManager *self)
{
self->icon_name = TORCH_DISABLED_ICON;
self->max_brightness = 1;
- /* Perform DBus setup when idle */
- g_idle_add ((GSourceFunc)on_idle, self);
}
@@ -405,7 +415,7 @@
phosh_torch_manager_toggle (PhoshTorchManager *self)
{
g_return_if_fail (PHOSH_IS_TORCH_MANAGER (self));
- g_return_if_fail (PHOSH_UPOWER_DBUS_IS_TORCH (self->proxy));
+ g_return_if_fail (PHOSH_LOGIN1_SESSION_DBUS_IS_LOGIN_SESSION (self->proxy));
if (self->brightness) {
g_debug ("Disabling torch");
diff -Nru phosh-0.8.0/src/torch-manager.h phosh-0.13.1/src/torch-manager.h
--- phosh-0.8.0/src/torch-manager.h 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/torch-manager.h 2021-08-31 09:15:52.000000000 +0000
@@ -6,13 +6,15 @@
#pragma once
+#include "manager.h"
+
#include
G_BEGIN_DECLS
#define PHOSH_TYPE_TORCH_MANAGER (phosh_torch_manager_get_type ())
-G_DECLARE_FINAL_TYPE (PhoshTorchManager, phosh_torch_manager, PHOSH, TORCH_MANAGER, GObject)
+G_DECLARE_FINAL_TYPE (PhoshTorchManager, phosh_torch_manager, PHOSH, TORCH_MANAGER, PhoshManager)
PhoshTorchManager *phosh_torch_manager_new (void);
const char *phosh_torch_manager_get_icon_name (PhoshTorchManager *self);
diff -Nru phosh-0.8.0/src/ui/app-auth-prompt.ui phosh-0.13.1/src/ui/app-auth-prompt.ui
--- phosh-0.8.0/src/ui/app-auth-prompt.ui 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/ui/app-auth-prompt.ui 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,79 @@
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+ Cancel
+ True
+ True
+ center
+
+
+
+
+
+ Ok
+ True
+ True
+ True
+ True
+ center
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/ui/app-grid.ui phosh-0.13.1/src/ui/app-grid.ui
--- phosh-0.8.0/src/ui/app-grid.ui 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/ui/app-grid.ui 2021-08-31 09:15:52.000000000 +0000
@@ -9,30 +9,60 @@
True
vertical
-
+
True
- True
- 6
- 6
- 6
- edit-find-symbolic
- False
- False
- Search apps…
-
-
-
-
-
+ False
+
+
+ True
+ True
+ edit-find-symbolic
+ False
+ False
+ Search apps…
+
+
+
+
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+
+ False
+ True
+ 1
+
+
-
- False
- True
- 0
-
@@ -125,4 +155,21 @@
+
diff -Nru phosh-0.8.0/src/ui/end-session-dialog.ui phosh-0.13.1/src/ui/end-session-dialog.ui
--- phosh-0.8.0/src/ui/end-session-dialog.ui 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/ui/end-session-dialog.ui 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,80 @@
+
+
+
+
+
+ False
+
+
+
+ True
+ False
+ 12
+ vertical
+
+
+ True
+ False
+ center
+ True
+
+
+
+
+
+
+ 12
+ False
+ center
+ True
+ Some applications are busy or have unsaved work
+
+
+
+
+
+ none
+ False
+ False
+ False
+
+
+
+
+
+
+
+
+ Cancel
+ True
+ True
+ center
+
+
+
+
+
+ Ok
+ True
+ True
+ True
+ True
+ True
+ center
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/ui/gtk-mount-prompt.ui phosh-0.13.1/src/ui/gtk-mount-prompt.ui
--- phosh-0.8.0/src/ui/gtk-mount-prompt.ui 1970-01-01 00:00:00.000000000 +0000
+++ phosh-0.13.1/src/ui/gtk-mount-prompt.ui 2021-08-31 09:15:52.000000000 +0000
@@ -0,0 +1,167 @@
+
+
+
+
+
+ False
+
+
+
+ True
+ False
+ center
+ center
+ 6
+ 12
+
+
+ True
+ False
+ end
+ Password:
+ right
+
+
+ 0
+ 5
+
+
+
+
+ True
+ password_buffer
+ True
+ True
+ center
+ True
+ False
+ ●
+ True
+ eye-not-looking-symbolic
+ False
+ password
+
+
+
+ 1
+ 5
+
+
+
+
+ True
+ False
+ center
+ dialog-password-symbolic
+ 6
+
+
+ 0
+ 0
+
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 12
+ center
+ True
+ word-char
+
+
+ False
+ True
+ 1
+
+
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ end
+ User:
+ right
+
+
+ 0
+ 3
+
+
+
+
+ True
+ True
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+ end
+ Domain:
+ right
+
+
+ 0
+ 4
+
+
+
+
+ True
+ True
+
+
+ 1
+ 4
+
+
+
+
+
+
+
+ gtk-cancel
+ True
+ True
+ True
+ center
+
+
+
+
+
+ Co_nnect
+ True
+ True
+ True
+ True
+ center
+ True
+
+
+
+
+
+
+
+
diff -Nru phosh-0.8.0/src/ui/home.ui phosh-0.13.1/src/ui/home.ui
--- phosh-0.8.0/src/ui/home.ui 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/ui/home.ui 2021-08-31 09:15:52.000000000 +0000
@@ -4,6 +4,7 @@
False
+
@@ -13,16 +14,16 @@
False
vertical
-
- 40
+
True
- False
-
-
+ True
+ slide-up
+
+
+ 40
True
- True
- crossfade
-
+ False
+
True
True
@@ -39,33 +40,33 @@
+
+ True
+ True
+ 0
+
+
+
+
+ False
+ True
+ end
+ center
+ 6
+ True
+
+
+
+
+ False
+ True
+ end
+ 1
+
-
- True
- True
- 0
-
-
-
-
- False
- True
- end
- center
- 6
- True
-
-
-
-
- False
- True
- end
- 1
-
diff -Nru phosh-0.8.0/src/ui/lockscreen.ui phosh-0.13.1/src/ui/lockscreen.ui
--- phosh-0.8.0/src/ui/lockscreen.ui 2021-01-17 16:49:25.000000000 +0000
+++ phosh-0.13.1/src/ui/lockscreen.ui 2021-08-31 09:15:52.000000000 +0000
@@ -9,310 +9,383 @@
-
+
True
- False
- vertical
- 400
- True
-
-
-
+ over
+ True
+ 400
+
+
True
- vertical
False
- True
+ vertical
+ 400
+ True
+
-
+
True
- False
vertical
+ False
+ True
-
+