From ef3b4ece6d22857f4b6d43d60f5ca95620edbea3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 19 Jan 2019 08:40:37 -0500 Subject: [PATCH 01/24] inhibit: Implement session state tracking Add the session-state member to the StateChanged signal. To track the session state, we register with org.gnome.SessionManager and emit StateChanged signals in response to changes from the session manager. We wait for 1 second for active sessions to call QueryEndResponse after receiving a StateChange signal. --- src/inhibit.c | 268 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 241 insertions(+), 27 deletions(-) diff --git a/src/inhibit.c b/src/inhibit.c index c4cb586..5202b93 100644 --- a/src/inhibit.c +++ b/src/inhibit.c @@ -24,6 +24,18 @@ enum { static GDBusInterfaceSkeleton *inhibit; static OrgGnomeSessionManager *sessionmanager; static OrgGnomeScreenSaver *screensaver; +static GDBusProxy *client; + +typedef enum { + UNKNOWN = 0, + RUNNING = 1, + QUERY_END = 2, + ENDING = 3 +} SessionState; + +static SessionState session_state = RUNNING; +static gboolean screensaver_active = FALSE; +static guint query_end_timeout; static void uninhibit_done_gnome (GObject *source, @@ -121,6 +133,130 @@ handle_inhibit_gnome (XdpImplInhibit *object, return TRUE; } +static void +send_quit_response (GDBusProxy *client, + gboolean will_quit, + const gchar *reason) +{ + g_debug ("Calling EndSessionResponse %d '%s'", will_quit, reason ? reason : ""); + + g_dbus_proxy_call (client, + "EndSessionResponse", + g_variant_new ("(bs)", will_quit, reason ? reason : ""), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, NULL, NULL); +} + +static void global_emit_state_changed (void); + +static void +set_session_state (SessionState state) +{ + const char *names[] = { + "Unknown", "Running", "Query-end", "Ending" + }; + + g_debug ("Session state now: %s", names[state]); + + session_state = state; + + global_emit_state_changed (); +} + +static void global_set_pending_query_end_response (gboolean pending); +static gboolean global_get_pending_query_end_response (void); + +static void +stop_waiting_for_query_end_response (gboolean send_response) +{ + g_debug ("Stop waiting for QueryEndResponse calls"); + + if (query_end_timeout != 0) + { + g_source_remove (query_end_timeout); + query_end_timeout = 0; + } + + global_set_pending_query_end_response (FALSE); + + if (send_response && client) + send_quit_response (client, TRUE, NULL); +} + +static gboolean +query_end_response (gpointer data) +{ + g_debug ("1 second wait is over"); + + stop_waiting_for_query_end_response (TRUE); + + return G_SOURCE_REMOVE; +} + +static void +wait_for_query_end_response (GDBusProxy *proxy) +{ + if (query_end_timeout != 0) + return; /* we're already waiting */ + + g_debug ("Waiting for up to 1 second for QueryEndResponse calls"); + + query_end_timeout = g_timeout_add (1000, query_end_response, proxy); + + global_set_pending_query_end_response (TRUE); +} + +static void +maybe_send_quit_response (void) +{ + if (query_end_timeout == 0) + return; + + if (!client) + return; + + if (global_get_pending_query_end_response ()) + return; + + g_debug ("No more pending QueryEndResponse calls"); + + stop_waiting_for_query_end_response (TRUE); +} + +static void +client_proxy_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + if (g_str_equal (signal_name, "QueryEndSession")) + { + g_debug ("Received QueryEndSession"); + wait_for_query_end_response (proxy); + set_session_state (QUERY_END); + maybe_send_quit_response (); + } + else if (g_str_equal (signal_name, "CancelEndSession")) + { + g_debug ("Received CancelEndSession"); + stop_waiting_for_query_end_response (FALSE); + set_session_state (RUNNING); + } + else if (g_str_equal (signal_name, "EndSession")) + { + g_debug ("Received EndSession"); + stop_waiting_for_query_end_response (FALSE); + set_session_state (ENDING); + send_quit_response (client, TRUE, NULL); + } + else if (g_str_equal (signal_name, "Stop")) + { + g_debug ("Received Stop"); + } +} + static OrgFreedesktopScreenSaver *fdo_screensaver; static void @@ -241,11 +377,32 @@ handle_inhibit_fdo (XdpImplInhibit *object, static GList *active_sessions = NULL; +static void +emit_state_changed (Session *session) +{ + GVariantBuilder state; + + g_debug ("Emitting StateChanged for session %s", session->id); + + g_variant_builder_init (&state, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&state, "{sv}", "screensaver-active", g_variant_new_boolean (screensaver_active)); + g_variant_builder_add (&state, "{sv}", "session-state", g_variant_new_uint32 (session_state)); + g_signal_emit_by_name (inhibit, "state-changed", session->id, g_variant_builder_end (&state)); +} + +static void +global_emit_state_changed (void) +{ + GList *l; + + for (l = active_sessions; l; l = l->next) + emit_state_changed ((Session *)l->data); +} + typedef struct { Session parent; - - gulong active_changed_handler_id; + gboolean pending_query_end_response; } InhibitSession; typedef struct _InhibitSessionClass @@ -256,6 +413,33 @@ typedef struct _InhibitSessionClass GType inhibit_session_get_type (void); G_DEFINE_TYPE (InhibitSession, inhibit_session, session_get_type ()) +static void +global_set_pending_query_end_response (gboolean pending) +{ + GList *l; + + for (l = active_sessions; l; l = l->next) + { + InhibitSession *session = (InhibitSession *)l->data; + session->pending_query_end_response = pending; + } +} + +static gboolean +global_get_pending_query_end_response (void) +{ + GList *l; + + for (l = active_sessions; l; l = l->next) + { + InhibitSession *session = (InhibitSession *)l->data; + if (session->pending_query_end_response) + return TRUE; + } + + return FALSE; +} + static void inhibit_session_close (Session *session) { @@ -290,26 +474,11 @@ inhibit_session_class_init (InhibitSessionClass *klass) session_class->close = inhibit_session_close; } -static void -active_changed_cb (Session *session, - gboolean active) -{ - GVariantBuilder state; - - g_debug ("Updating inhibit session %s", session->id); - - g_variant_builder_init (&state, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&state, "{sv}", - "screensaver-active", g_variant_new_boolean (active)); - g_signal_emit_by_name (inhibit, "state-changed", session->id, g_variant_builder_end (&state)); -} - static InhibitSession * inhibit_session_new (const char *app_id, const char *session_handle) { InhibitSession *inhibit_session; - gboolean active; g_debug ("Creating inhibit session %s", session_handle); @@ -319,9 +488,6 @@ inhibit_session_new (const char *app_id, active_sessions = g_list_prepend (active_sessions, inhibit_session); - active = GPOINTER_TO_INT (g_object_get_data (screensaver ? (GObject *)screensaver : (GObject *)fdo_screensaver, "active")); - active_changed_cb ((Session *)inhibit_session, active); - return inhibit_session; } @@ -351,6 +517,28 @@ handle_create_monitor (XdpImplInhibit *object, out: xdp_impl_inhibit_complete_create_monitor (object, invocation, response); + if (session) + emit_state_changed (session); + + return TRUE; +} + +static gboolean +handle_query_end_response (XdpImplInhibit *object, + GDBusMethodInvocation *invocation, + const char *arg_session_handle) +{ + InhibitSession *session = (InhibitSession *)lookup_session (arg_session_handle); + + g_debug ("Handle QueryEndSessionResponse for session %s", arg_session_handle); + + if (session) + { + session->pending_query_end_response = FALSE; + maybe_send_quit_response (); + } + + xdp_impl_inhibit_complete_query_end_response (object, invocation); return TRUE; } @@ -359,13 +547,11 @@ static void global_active_changed_cb (GObject *object, gboolean active) { - GList *l; - g_debug ("Screensaver %s", active ? "active" : "inactive"); - g_object_set_data (object, "active", GINT_TO_POINTER (active)); - for (l = active_sessions; l; l = l->next) - active_changed_cb ((Session *)l->data, active); + screensaver_active = active; + + global_emit_state_changed (); } gboolean @@ -396,15 +582,43 @@ inhibit_init (GDBusConnection *bus, if (owner && owner2) { + g_autofree char *client_path = NULL; + g_autofree char *owner3 = NULL; + g_signal_connect (inhibit, "handle-inhibit", G_CALLBACK (handle_inhibit_gnome), NULL); g_signal_connect (inhibit, "handle-create-monitor", G_CALLBACK (handle_create_monitor), NULL); + g_signal_connect (inhibit, "handle-query-end-response", G_CALLBACK (handle_query_end_response), NULL); g_signal_connect (screensaver, "active-changed", G_CALLBACK (global_active_changed_cb), NULL); org_gnome_screen_saver_call_get_active_sync (screensaver, &active, NULL, NULL); g_object_set_data (G_OBJECT (screensaver), "active", GINT_TO_POINTER (active)); g_debug ("Using org.gnome.SessionManager for inhibit"); - g_debug ("Using org.gnome.Screensaver for state changes"); + g_debug ("Using org.gnome.Screensaver for screensaver state"); + + if (org_gnome_session_manager_call_register_client_sync (sessionmanager, + "org.freedesktop.portal", + "", + &client_path, + NULL, + NULL)) + { + client = g_dbus_proxy_new_sync (bus, 0, + NULL, + "org.gnome.SessionManager", + client_path, + "org.gnome.SessionManager.ClientPrivate", + NULL, + NULL); + + owner3 = g_dbus_proxy_get_name_owner (client); + if (owner3) + { + g_signal_connect (client, "g-signal", G_CALLBACK (client_proxy_signal), NULL); + + g_debug ("Using org.gnome.SessionManager for session state"); + } + } } else { @@ -426,7 +640,7 @@ inhibit_init (GDBusConnection *bus, g_object_set_data (G_OBJECT (fdo_screensaver), "active", GINT_TO_POINTER (active)); g_debug ("Using org.freedesktop.ScreenSaver for inhibit"); - g_debug ("Using org.freedesktop.ScreenSaver for state changes"); + g_debug ("Using org.freedesktop.ScreenSaver for screensaver state"); } From 6e9724f9c5e2cac430ce2974848844bc1114588b Mon Sep 17 00:00:00 2001 From: Yuri Chornoivan Date: Fri, 25 Jan 2019 12:26:51 +0200 Subject: [PATCH 02/24] Update Ukrainian translation --- po/uk.po | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/po/uk.po b/po/uk.po index 05d273e..0849430 100644 --- a/po/uk.po +++ b/po/uk.po @@ -2,14 +2,14 @@ # Copyright (C) 2016 xdg-desktop-portal-gtk's COPYRIGHT HOLDER # This file is distributed under the same license as the xdg-desktop-portal-gtk package. # -# Yuri Chornoivan , 2016, 2017, 2018. +# Yuri Chornoivan , 2016, 2017, 2018, 2019. msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" -"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" -"issues\n" -"POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2018-10-29 13:20+0200\n" +"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/issues" +"\n" +"POT-Creation-Date: 2019-01-19 03:27+0000\n" +"PO-Revision-Date: 2019-01-25 12:26+0200\n" "Last-Translator: Yuri Chornoivan \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -37,32 +37,32 @@ msgstr "Заборонити доступ" msgid "Grant Access" msgstr "Надати доступ" -#: src/accountdialog.c:166 +#: src/accountdialog.c:176 msgid "Select an Image" msgstr "Виберіть образ" -#: src/accountdialog.c:169 +#: src/accountdialog.c:179 msgid "Cancel" msgstr "Скасувати" -#: src/accountdialog.c:170 +#: src/accountdialog.c:180 msgid "Select" msgstr "Вибрати" -#: src/accountdialog.c:171 +#: src/accountdialog.c:181 msgid "Clear" msgstr "Спорожнити" -#: src/accountdialog.c:185 +#: src/accountdialog.c:195 msgid "Images" msgstr "Образи" -#: src/accountdialog.c:260 +#: src/accountdialog.c:272 #, c-format msgid "Share your personal information with %s?" msgstr "Поділитися вашими особистими даними з %s?" -#: src/accountdialog.c:263 +#: src/accountdialog.c:275 msgid "Share your personal information with the requesting application?" msgstr "Поділитися вашими особистими даними з програмою, яка про це просить?" @@ -89,7 +89,7 @@ msgstr "Внести зміни до оприлюднення даних" msgid "Failed to start Software" msgstr "Не вдалося запустити Програмні засоби" -#: src/appchooserdialog.c:398 +#: src/appchooserdialog.c:408 #, c-format msgid "" "Select an application to open “%s”. More applications are available in Програмні засоби." -#: src/appchooserdialog.c:403 +#: src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." @@ -106,12 +106,12 @@ msgstr "" "Виберіть програму. Ширший список програм можна знайти у програмі Програмні засоби." -#: src/appchooserdialog.c:418 +#: src/appchooserdialog.c:428 #, c-format msgid "Unable to find an application that is able to open “%s”." msgstr "Не вдалося знайти програму, яка здатна відкривати «%s»." -#: src/appchooserdialog.c:423 +#: src/appchooserdialog.c:433 msgid "Unable to find a suitable application." msgstr "Не вдалося знайти відповідну програму." @@ -135,6 +135,10 @@ msgstr "_Зберегти" msgid "_Open" msgstr "_Відкрити" +#: src/filechooser.c:504 +msgid "Open files read-only" +msgstr "Відкрити файли лише для читання" + #: src/remotedesktopdialog.c:190 msgid "Pointer" msgstr "Координатний пристрій" @@ -176,12 +180,12 @@ msgstr "" "Виберіть монітор, дані з якого слід оприлюднити за допомогою відповідної " "програми" -#: src/screenshotdialog.c:422 +#: src/screenshotdialog.c:434 #, c-format msgid "Share this screenshot with %s?" msgstr "Оприлюднити цей знімок екрана за допомогою %s?" -#: src/screenshotdialog.c:426 +#: src/screenshotdialog.c:438 msgid "Share this screenshot with the requesting application?" msgstr "Оприлюднити цей знімок екрана за допомогою відповідної програми?" From c8effc4924fe35d30ff20645dec32e2748ee8e76 Mon Sep 17 00:00:00 2001 From: scootergrisen Date: Mon, 11 Feb 2019 06:25:58 +0100 Subject: [PATCH 03/24] Update da.po --- po/da.po | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/po/da.po b/po/da.po index b1bd86a..8df807c 100644 --- a/po/da.po +++ b/po/da.po @@ -1,14 +1,14 @@ # Danish translation for xdg-desktop-portal-gtk # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# scootergrisen, 2018. +# scootergrisen, 2018-2019. msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk\n" -"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-" -"gtk/issues\n" -"POT-Creation-Date: 2018-12-05 03:29+0000\n" -"PO-Revision-Date: 2018-12-06 03:20+0200\n" +"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" +"issues\n" +"POT-Creation-Date: 2019-02-11 03:27+0000\n" +"PO-Revision-Date: 2019-02-11 00:00+0200\n" "Last-Translator: scootergrisen\n" "Language-Team: Danish\n" "Language: da\n" @@ -67,7 +67,7 @@ msgstr "Del dine personlige informationer med det anmodede program?" msgid "Share Details" msgstr "Delingsdetaljer" -#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 +#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:397 #: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 #: src/screenshotdialog.ui:14 msgid "_Cancel" @@ -93,15 +93,15 @@ msgid "" "href='software'>Software." msgstr "" "Vælg et program til at åbne “%s”. Der findes flere programmer i Software." +"href='software'>Software." #: src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." msgstr "" -"Vælg et program. Der findes flere programmer i Software." +"Vælg et program. Der findes flere programmer i Software." #: src/appchooserdialog.c:428 #, c-format @@ -124,14 +124,18 @@ msgstr "Der blev ikke fundet nogen programmer" msgid "Find Compatible Applications in Software" msgstr "Find kompatible programmer i Software" -#: src/filechooser.c:390 +#: src/filechooser.c:392 msgid "_Save" msgstr "_Gem" -#: src/filechooser.c:392 +#: src/filechooser.c:394 msgid "_Open" msgstr "_Åbn" +#: src/filechooser.c:552 +msgid "Open files read-only" +msgstr "Åbn filer som skrivebeskyttet" + #: src/remotedesktopdialog.c:190 msgid "Pointer" msgstr "Markør" From a69ca78653dd0ef9e30d10b10279a1698e1d6f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20=C3=9Ar?= Date: Tue, 12 Feb 2019 21:11:24 +0100 Subject: [PATCH 04/24] Update Hungarian translation --- po/hu.po | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/po/hu.po b/po/hu.po index bb0d929..0e86fdb 100644 --- a/po/hu.po +++ b/po/hu.po @@ -1,16 +1,16 @@ # Hungarian translation for xdg-desktop-portal-gtk. -# Copyright (C) 2016, 2017, 2018 Free Software Foundation, Inc. +# Copyright (C) 2016, 2017, 2018, 2019 Free Software Foundation, Inc. # This file is distributed under the same license as the xdg-sesktop-portal-gtk package. # -# Balázs Úr , 2016, 2017, 2018. +# Balázs Úr , 2016, 2017, 2018, 2019. msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" -"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" -"issues\n" -"POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2018-03-03 08:15+0100\n" -"Last-Translator: Balázs Úr \n" +"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/issues" +"\n" +"POT-Creation-Date: 2019-01-19 03:27+0000\n" +"PO-Revision-Date: 2019-02-12 21:07+0100\n" +"Last-Translator: Balázs Úr \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" @@ -36,32 +36,32 @@ msgstr "Hozzáférés megtagadása" msgid "Grant Access" msgstr "Hozzáférés megadása" -#: src/accountdialog.c:166 +#: src/accountdialog.c:176 msgid "Select an Image" msgstr "Válasszon lemezképet" -#: src/accountdialog.c:169 +#: src/accountdialog.c:179 msgid "Cancel" msgstr "Mégse" -#: src/accountdialog.c:170 +#: src/accountdialog.c:180 msgid "Select" msgstr "Kiválasztás" -#: src/accountdialog.c:171 +#: src/accountdialog.c:181 msgid "Clear" msgstr "Törlés" -#: src/accountdialog.c:185 +#: src/accountdialog.c:195 msgid "Images" msgstr "Lemezképek" -#: src/accountdialog.c:260 +#: src/accountdialog.c:272 #, c-format msgid "Share your personal information with %s?" msgstr "Megosztja a személyes információit ezzel: %s?" -#: src/accountdialog.c:263 +#: src/accountdialog.c:275 msgid "Share your personal information with the requesting application?" msgstr "Megosztja a személyes információit a kérelmező alkalmazással?" @@ -88,7 +88,7 @@ msgstr "Megváltoztatás az információk megosztása előtt" msgid "Failed to start Software" msgstr "Nem sikerült elindítani a Szoftvereket" -#: src/appchooserdialog.c:398 +#: src/appchooserdialog.c:408 #, c-format msgid "" "Select an application to open “%s”. More applications are available in Szoftverekben." -#: src/appchooserdialog.c:403 +#: src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." @@ -105,13 +105,13 @@ msgstr "" "Válasszon egy alkalmazást. További alkalmazások érhetők el a Szoftverekben." -#: src/appchooserdialog.c:418 +#: src/appchooserdialog.c:428 #, c-format msgid "Unable to find an application that is able to open “%s”." msgstr "" "Nem sikerült olyan alkalmazást találni, amely képes a(z) „%s” megnyitására." -#: src/appchooserdialog.c:423 +#: src/appchooserdialog.c:433 msgid "Unable to find a suitable application." msgstr "Nem sikerült megfelelő alkalmazást találni." @@ -129,12 +129,16 @@ msgstr "Kompatibilis alkalmazások keresése a Szoftverekben" #: src/filechooser.c:390 msgid "_Save" -msgstr "" +msgstr "_Mentés" #: src/filechooser.c:392 msgid "_Open" msgstr "Meg_nyitás" +#: src/filechooser.c:504 +msgid "Open files read-only" +msgstr "Fájlok megnyitása csak olvasásra" + #: src/remotedesktopdialog.c:190 msgid "Pointer" msgstr "Mutató" @@ -148,14 +152,13 @@ msgid "Touch screen" msgstr "Érintőképernyő" #: src/remotedesktopdialog.c:303 -#, fuzzy, c-format +#, c-format msgid "Select devices to share with %s" -msgstr "Válassza ki, mit szeretne megosztani ezzel: %s" +msgstr "Válassza ki az ezzel megosztani kívánt eszközöket: %s" #: src/remotedesktopdialog.c:308 -#, fuzzy msgid "Select devices to share with the requesting application" -msgstr "Válassza ki, hogy mit szeretne megosztani a kérő alkalmazással" +msgstr "Válassza ki a kérelmező alkalmazással megosztani kívánt eszközöket" #: src/remotedesktopdialog.ui:12 msgid "Remote desktop" @@ -174,12 +177,12 @@ msgstr "Válasszon monitort az ezzel történő megosztáshoz: %s" msgid "Select monitor to share with the requesting application" msgstr "Válasszon monitort a kérő alkalmazással történő megosztáshoz" -#: src/screenshotdialog.c:422 +#: src/screenshotdialog.c:434 #, c-format msgid "Share this screenshot with %s?" msgstr "Megosztja ezt a képernyőképet ezzel: %s?" -#: src/screenshotdialog.c:426 +#: src/screenshotdialog.c:438 msgid "Share this screenshot with the requesting application?" msgstr "Megosztja ezt a képernyőképet a kérő alkalmazással?" From ff59abb5ec7583fac8a3841ef300ca0872367ec5 Mon Sep 17 00:00:00 2001 From: welaq Date: Thu, 14 Feb 2019 00:32:45 +0200 Subject: [PATCH 05/24] Update Lithuanian translation --- po/lt.po | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/po/lt.po b/po/lt.po index 87fba8f..519ad21 100644 --- a/po/lt.po +++ b/po/lt.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" "Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" "issues\n" -"POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2018-10-15 15:09+0300\n" +"POT-Creation-Date: 2019-02-13 15:30+0000\n" +"PO-Revision-Date: 2019-02-14 00:32+0200\n" "Last-Translator: Moo\n" "Language-Team: Lithuanian \n" "Language: lt\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" "%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Poedit 2.2.1\n" #: data/xdg-desktop-portal-gtk.desktop.in.in:4 msgid "Portal" @@ -37,32 +37,32 @@ msgstr "Drausti prieigą" msgid "Grant Access" msgstr "Suteikti prieigą" -#: src/accountdialog.c:166 +#: src/accountdialog.c:176 msgid "Select an Image" msgstr "Pasirinkti paveikslą" -#: src/accountdialog.c:169 +#: src/accountdialog.c:179 msgid "Cancel" msgstr "Atsisakyti" -#: src/accountdialog.c:170 +#: src/accountdialog.c:180 msgid "Select" msgstr "Pasirinkti" -#: src/accountdialog.c:171 +#: src/accountdialog.c:181 msgid "Clear" msgstr "Išvalyti" -#: src/accountdialog.c:185 +#: src/accountdialog.c:195 msgid "Images" msgstr "Paveikslai" -#: src/accountdialog.c:260 +#: src/accountdialog.c:272 #, c-format msgid "Share your personal information with %s?" msgstr "Bendrinti jūsų asmeninę informaciją su %s?" -#: src/accountdialog.c:263 +#: src/accountdialog.c:275 msgid "Share your personal information with the requesting application?" msgstr "Bendrinti jūsų asmeninę informaciją su prašančia programa?" @@ -70,7 +70,7 @@ msgstr "Bendrinti jūsų asmeninę informaciją su prašančia programa?" msgid "Share Details" msgstr "Bendrinti išsamesnę informaciją" -#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 +#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:397 #: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 #: src/screenshotdialog.ui:14 msgid "_Cancel" @@ -89,7 +89,7 @@ msgstr "Prieš bendrinant informaciją, atlikti pakeitimus" msgid "Failed to start Software" msgstr "Nepavyko paleisti Programinės įrangos" -#: src/appchooserdialog.c:398 +#: src/appchooserdialog.c:408 #, c-format msgid "" "Select an application to open “%s”. More applications are available in Programinėje įrangoje." -#: src/appchooserdialog.c:403 +#: src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." @@ -106,12 +106,12 @@ msgstr "" "Pasirinkite programą. Daugiau programų yra prieinama Programinėje įrangoje." -#: src/appchooserdialog.c:418 +#: src/appchooserdialog.c:428 #, c-format msgid "Unable to find an application that is able to open “%s”." msgstr "Nepavyko rasti programos, kuri galėtų atverti \"%s\"." -#: src/appchooserdialog.c:423 +#: src/appchooserdialog.c:433 msgid "Unable to find a suitable application." msgstr "Nepavyko rasti tinkamos programos." @@ -127,14 +127,18 @@ msgstr "Nerasta jokių programų" msgid "Find Compatible Applications in Software" msgstr "Rasti suderinamas programas Programinėje įrangoje" -#: src/filechooser.c:390 +#: src/filechooser.c:392 msgid "_Save" msgstr "Į_rašyti" -#: src/filechooser.c:392 +#: src/filechooser.c:394 msgid "_Open" msgstr "_Atverti" +#: src/filechooser.c:552 +msgid "Open files read-only" +msgstr "Atverti failus tik skaitymui" + #: src/remotedesktopdialog.c:190 msgid "Pointer" msgstr "Rodyklė" @@ -173,12 +177,12 @@ msgstr "Pasirinkti vaizduoklį, kurį bendrinti su %s" msgid "Select monitor to share with the requesting application" msgstr "Pasirinkti vaizduoklį, kurį bendrinti su prašančia programa" -#: src/screenshotdialog.c:422 +#: src/screenshotdialog.c:434 #, c-format msgid "Share this screenshot with %s?" msgstr "Bendrinti šią ekrano kopiją su %s?" -#: src/screenshotdialog.c:426 +#: src/screenshotdialog.c:438 msgid "Share this screenshot with the requesting application?" msgstr "Bendrinti šią ekrano kopiją su prašančia programa?" From 90456b5d1f97cce36b951df352e46de21280dfe2 Mon Sep 17 00:00:00 2001 From: Kukuh Syafaat Date: Mon, 18 Feb 2019 18:14:58 +0700 Subject: [PATCH 06/24] Update Indonesian translation --- po/id.po | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/po/id.po b/po/id.po index e0bab9e..f96bd38 100644 --- a/po/id.po +++ b/po/id.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" "Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" "issues\n" -"POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2018-11-14 23:36+0700\n" +"POT-Creation-Date: 2019-01-19 03:27+0000\n" +"PO-Revision-Date: 2019-02-18 18:13+0700\n" "Last-Translator: Kukuh Syafaat \n" "Language-Team: Indonesian \n" "Language: id\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" +"X-Generator: Poedit 2.2.1\n" #: data/xdg-desktop-portal-gtk.desktop.in.in:4 msgid "Portal" @@ -35,32 +35,32 @@ msgstr "Tolak Akses" msgid "Grant Access" msgstr "Beri Akses" -#: src/accountdialog.c:166 +#: src/accountdialog.c:176 msgid "Select an Image" msgstr "Pilih Gambar" -#: src/accountdialog.c:169 +#: src/accountdialog.c:179 msgid "Cancel" msgstr "Batal" -#: src/accountdialog.c:170 +#: src/accountdialog.c:180 msgid "Select" msgstr "Pilih" -#: src/accountdialog.c:171 +#: src/accountdialog.c:181 msgid "Clear" msgstr "Bersihkan" -#: src/accountdialog.c:185 +#: src/accountdialog.c:195 msgid "Images" msgstr "Gambar" -#: src/accountdialog.c:260 +#: src/accountdialog.c:272 #, c-format msgid "Share your personal information with %s?" msgstr "Bagikan informasi pribadi Anda dengan %s?" -#: src/accountdialog.c:263 +#: src/accountdialog.c:275 msgid "Share your personal information with the requesting application?" msgstr "Bagikan informasi pribadi Anda dengan aplikasi yang meminta?" @@ -87,7 +87,7 @@ msgstr "Buat perubahan sebelum membagikan informasi" msgid "Failed to start Software" msgstr "Gagal memulai Perangkat Lunak" -#: src/appchooserdialog.c:398 +#: src/appchooserdialog.c:408 #, c-format msgid "" "Select an application to open “%s”. More applications are available in Perangkat Lunak." -#: src/appchooserdialog.c:403 +#: src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." @@ -104,12 +104,12 @@ msgstr "" "Pilih sebuah aplikasi. Aplikasi lainnya tersedia di Perangkat Lunak." -#: src/appchooserdialog.c:418 +#: src/appchooserdialog.c:428 #, c-format msgid "Unable to find an application that is able to open “%s”." msgstr "Tidak dapat menemukan aplikasi yang dapat membuka \"%s\"." -#: src/appchooserdialog.c:423 +#: src/appchooserdialog.c:433 msgid "Unable to find a suitable application." msgstr "Tidak dapat menemukan aplikasi yang sesuai." @@ -133,6 +133,10 @@ msgstr "_Simpan" msgid "_Open" msgstr "B_uka" +#: src/filechooser.c:504 +msgid "Open files read-only" +msgstr "Buka berkas hanya-baca" + #: src/remotedesktopdialog.c:190 msgid "Pointer" msgstr "Penunjuk" @@ -171,12 +175,12 @@ msgstr "Pilih monitor untuk berbagi dengan %s" msgid "Select monitor to share with the requesting application" msgstr "Pilih monitor untuk berbagi dengan aplikasi yang meminta" -#: src/screenshotdialog.c:422 +#: src/screenshotdialog.c:434 #, c-format msgid "Share this screenshot with %s?" msgstr "Bagikan cuplikan layar ini dengan %s?" -#: src/screenshotdialog.c:426 +#: src/screenshotdialog.c:438 msgid "Share this screenshot with the requesting application?" msgstr "Bagikan cuplikan layar ini dengan aplikasi yang meminta?" From e0dad438532d237b44b72c88a969ac86b6b06c0b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 19 Feb 2019 01:04:30 -0500 Subject: [PATCH 07/24] Bump version to 1.3.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1b47033..1ba48db 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.63]) -AC_INIT([xdg-desktop-portal-gtk],[1.2.0]) +AC_INIT([xdg-desktop-portal-gtk],[1.3.0]) AC_PROG_CC AM_PROG_CC_C_O From b5edd6b8a79d83e9ae4c44298ad8b69e4c7b22b1 Mon Sep 17 00:00:00 2001 From: Fran Dieguez Date: Wed, 20 Feb 2019 01:48:08 +0100 Subject: [PATCH 08/24] Update Galician translations --- po/gl.po | 196 ++++++++++++++++++++----------------------------------- 1 file changed, 71 insertions(+), 125 deletions(-) diff --git a/po/gl.po b/po/gl.po index e52a23f..165ad5b 100644 --- a/po/gl.po +++ b/po/gl.po @@ -1,14 +1,14 @@ # Galician translation for xdg-desktop-portal-gtk. # Copyright (C) 2017 xdg-desktop-portal-gtk's COPYRIGHT HOLDER # This file is distributed under the same license as the xdg-desktop-portal-gtk package. -# Fran Dieguez , 2017. +# Fran Dieguez , 2017, 2019. msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" "Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" "issues\n" -"POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2017-09-26 09:46+0200\n" +"POT-Creation-Date: 2019-02-20 01:46+0100\n" +"PO-Revision-Date: 2019-02-20 01:47+0200\n" "Last-Translator: Fran Dieguez \n" "Language-Team: Galician\n" "Language: gl\n" @@ -18,76 +18,48 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Virtaal 0.7.1\n" -#: data/xdg-desktop-portal-gtk.desktop.in.in:4 -msgid "Portal" -msgstr "Portal" - -#. TRANSLATORS: Don't translate this text (this is icon name) -#: data/xdg-desktop-portal-gtk.desktop.in.in:6 -msgid "applications-system-symbolic" -msgstr "applications-system-symbolic" - -#: src/access.c:271 +#: ../src/access.c:271 msgid "Deny Access" msgstr "Denegar acceso" -#: src/access.c:274 +#: ../src/access.c:274 msgid "Grant Access" msgstr "Conceder acceso" -#: src/accountdialog.c:166 +#: ../src/accountdialog.c:176 msgid "Select an Image" msgstr "Seleccione unha imaxe" -#: src/accountdialog.c:169 +#: ../src/accountdialog.c:179 msgid "Cancel" msgstr "Cancelar" -#: src/accountdialog.c:170 +#: ../src/accountdialog.c:180 msgid "Select" msgstr "Seleccionar" -#: src/accountdialog.c:171 +#: ../src/accountdialog.c:181 msgid "Clear" msgstr "Limpar" -#: src/accountdialog.c:185 +#: ../src/accountdialog.c:195 msgid "Images" msgstr "Imaxes" -#: src/accountdialog.c:260 +#: ../src/accountdialog.c:272 #, c-format msgid "Share your personal information with %s?" msgstr "Compartir a súa información persoal con %s?" -#: src/accountdialog.c:263 +#: ../src/accountdialog.c:275 msgid "Share your personal information with the requesting application?" msgstr "Compartir a súa información persoal co aplicativo que o solicita?" -#: src/accountdialog.ui:10 -msgid "Share Details" -msgstr "Compartir detalles" - -#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 -#: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 -#: src/screenshotdialog.ui:14 -msgid "_Cancel" -msgstr "_Cancelar" - -#: src/accountdialog.ui:22 src/remotedesktopdialog.ui:28 -#: src/screencastdialog.ui:28 src/screenshotdialog.ui:38 -msgid "_Share" -msgstr "_Compartir" - -#: src/accountdialog.ui:148 -msgid "Make changes before sharing the information" -msgstr "Facer cambios antes de compartir a información" - -#: src/appchooserdialog.c:159 +#: ../src/appchooserdialog.c:159 msgid "Failed to start Software" msgstr "Produciuse un fallo ao iniciar o Software" -#: src/appchooserdialog.c:398 +#: ../src/appchooserdialog.c:408 #, c-format msgid "" "Select an application to open “%s”. More applications are available in Software." -#: src/appchooserdialog.c:403 +#: ../src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." @@ -104,131 +76,105 @@ msgstr "" "Seleccione un aplicativo. Hai máis aplicativos dispoñíbeis en Software." -#: src/appchooserdialog.c:418 +#: ../src/appchooserdialog.c:428 #, c-format msgid "Unable to find an application that is able to open “%s”." msgstr "Non foi posíbel atopar un aplicativo que poida abrir «%s»." -#: src/appchooserdialog.c:423 +#: ../src/appchooserdialog.c:433 msgid "Unable to find a suitable application." msgstr "Non foi posíbel atopar un aplicativo axeitado." -#: src/appchooserdialog.ui:13 -msgid "Open With" -msgstr "Abrir con" - -#: src/appchooserdialog.ui:166 -msgid "No Applications Found" -msgstr "Non se atoparon aplicativos" - -#: src/appchooserdialog.ui:182 -msgid "Find Compatible Applications in Software" -msgstr "Bucar aplicativos compatíbeis en Software" - -#: src/filechooser.c:390 +#: ../src/filechooser.c:392 msgid "_Save" -msgstr "" +msgstr "_Gardar" -#: src/filechooser.c:392 +#: ../src/filechooser.c:394 msgid "_Open" msgstr "_Abrir" -#: src/remotedesktopdialog.c:190 +#: ../src/filechooser.c:397 +msgid "_Cancel" +msgstr "_Cancelar" + +#: ../src/filechooser.c:552 +msgid "Open files read-only" +msgstr "Abrir ficheiros en modo só lectura" + +#: ../src/remotedesktopdialog.c:190 msgid "Pointer" -msgstr "" +msgstr "Punteiro" -#: src/remotedesktopdialog.c:193 +#: ../src/remotedesktopdialog.c:193 msgid "Keyboard" -msgstr "" +msgstr "Teclado" -#: src/remotedesktopdialog.c:196 +#: ../src/remotedesktopdialog.c:196 msgid "Touch screen" -msgstr "" +msgstr "Pantalla táctil" -#: src/remotedesktopdialog.c:303 +#: ../src/remotedesktopdialog.c:303 #, c-format msgid "Select devices to share with %s" -msgstr "" +msgstr "Seleccione os dispositivos a compartir con %s" -#: src/remotedesktopdialog.c:308 -#, fuzzy +#: ../src/remotedesktopdialog.c:308 msgid "Select devices to share with the requesting application" -msgstr "Compartir esta captura de pantalla co aplicativo que o solicita?" +msgstr "Seleccione os dispositivos a compartir co aplicativo que o solicita" -#: src/remotedesktopdialog.ui:12 -msgid "Remote desktop" -msgstr "" - -#: src/screencastdialog.ui:12 -#, fuzzy -msgid "Screen casting" -msgstr "Captura de pantalla" - -#: src/screencastwidget.c:243 +#: ../src/screencastwidget.c:243 #, c-format msgid "Select monitor to share with %s" -msgstr "" +msgstr "Seleccione o monitor a compartir con %s" -#: src/screencastwidget.c:248 -#, fuzzy +#: ../src/screencastwidget.c:248 msgid "Select monitor to share with the requesting application" -msgstr "Compartir esta captura de pantalla co aplicativo que o solicita?" +msgstr "Compartir o monitor para compartir co aplicativo que o solicita" -#: src/screenshotdialog.c:422 +#: ../src/screenshotdialog.c:434 #, c-format msgid "Share this screenshot with %s?" msgstr "Compartir esta captura de pantalla con %s?" -#: src/screenshotdialog.c:426 +#: ../src/screenshotdialog.c:438 msgid "Share this screenshot with the requesting application?" msgstr "Compartir esta captura de pantalla co aplicativo que o solicita?" -#: src/screenshotdialog.ui:10 -msgid "Screenshot" -msgstr "Captura de pantalla" +#~ msgid "Portal" +#~ msgstr "Portal" -#: src/screenshotdialog.ui:30 -msgid "_Options…" -msgstr "" +#~ msgid "applications-system-symbolic" +#~ msgstr "applications-system-symbolic" -#: src/screenshotdialog.ui:55 -#, fuzzy -msgid "Take _Screenshot" -msgstr "Captura de pantalla" +#~ msgid "Share Details" +#~ msgstr "Compartir detalles" -#: src/screenshotdialog.ui:111 -#, fuzzy -msgid "Take Screenshot" -msgstr "Captura de pantalla" +#~ msgid "_Share" +#~ msgstr "_Compartir" -#: src/screenshotdialog.ui:122 -msgid "Grab the whole sc_reen" -msgstr "" +#~ msgid "Make changes before sharing the information" +#~ msgstr "Facer cambios antes de compartir a información" -#: src/screenshotdialog.ui:133 -msgid "Grab the current _window" -msgstr "" +#~ msgid "Open With" +#~ msgstr "Abrir con" -#: src/screenshotdialog.ui:144 -msgid "Select _area to grab" -msgstr "" +#~ msgid "No Applications Found" +#~ msgstr "Non se atoparon aplicativos" -#: src/screenshotdialog.ui:158 -msgid "Grab after a _delay of" -msgstr "" +#~ msgid "Find Compatible Applications in Software" +#~ msgstr "Bucar aplicativos compatíbeis en Software" -#: src/screenshotdialog.ui:171 -msgid "seconds" -msgstr "" +#, fuzzy +#~ msgid "Screen casting" +#~ msgstr "Captura de pantalla" -#: src/screenshotdialog.ui:181 -msgid "Effects" -msgstr "" +#~ msgid "Screenshot" +#~ msgstr "Captura de pantalla" -#: src/screenshotdialog.ui:192 -msgid "Include _pointer" -msgstr "" +#, fuzzy +#~ msgid "Take _Screenshot" +#~ msgstr "Captura de pantalla" -#: src/screenshotdialog.ui:201 -msgid "Include the window _border" -msgstr "" +#, fuzzy +#~ msgid "Take Screenshot" +#~ msgstr "Captura de pantalla" From f559afd237ea9779461b19ed706dda79c4587d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Feb 2019 16:42:24 +0100 Subject: [PATCH 09/24] gnomescreencast: Make signals array static --- src/gnomescreencast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c index fa8548b..3b3e8e4 100644 --- a/src/gnomescreencast.c +++ b/src/gnomescreencast.c @@ -51,7 +51,7 @@ enum N_SIGNALS }; -guint signals[N_SIGNALS]; +static guint signals[N_SIGNALS]; typedef struct _GnomeScreenCastStream { From 7bee9d8d2b591773ed2d61d3087080f38f53330e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Feb 2019 16:47:21 +0100 Subject: [PATCH 10/24] gnomescreencast: Bump supported API version Mutter bumped the version when it added the window recording and cursor modes, so we need to bump the version we support to be compatible. --- src/gnomescreencast.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c index 3b3e8e4..f5ed486 100644 --- a/src/gnomescreencast.c +++ b/src/gnomescreencast.c @@ -22,7 +22,7 @@ #include -#define SUPPORTED_MUTTER_SCREEN_CAST_API_VERSION 1 +#define SUPPORTED_MUTTER_SCREEN_CAST_API_VERSION 2 enum { @@ -99,6 +99,8 @@ typedef struct _GnomeScreenCast { GObject parent; + int api_version; + guint screen_cast_name_watch; OrgGnomeMutterScreenCast *proxy; } GnomeScreenCast; @@ -487,7 +489,6 @@ gnome_screen_cast_name_appeared (GDBusConnection *connection, { GnomeScreenCast *gnome_screen_cast = user_data; g_autoptr(GError) error = NULL; - int api_version; gnome_screen_cast->proxy = org_gnome_mutter_screen_cast_proxy_new_sync (connection, @@ -503,9 +504,9 @@ gnome_screen_cast_name_appeared (GDBusConnection *connection, return; } - api_version = + gnome_screen_cast->api_version = org_gnome_mutter_screen_cast_get_version (gnome_screen_cast->proxy); - if (api_version != SUPPORTED_MUTTER_SCREEN_CAST_API_VERSION) + if (gnome_screen_cast->api_version > SUPPORTED_MUTTER_SCREEN_CAST_API_VERSION) { g_warning ("org.gnome.Mutter.ScreenCast API version not compatible"); g_clear_object (&gnome_screen_cast->proxy); From d0ce74be310d2ec5734c0cfe48f034118ecf8aa2 Mon Sep 17 00:00:00 2001 From: Milo Casagrande Date: Fri, 8 Mar 2019 15:47:01 +0100 Subject: [PATCH 11/24] [l10n] Update Italian translation Signed-off-by: Milo Casagrande --- po/it.po | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/po/it.po b/po/it.po index 6fd7337..5559bf1 100644 --- a/po/it.po +++ b/po/it.po @@ -1,15 +1,14 @@ # Italian translation for xdg-desktop-portal-gtk. -# Copyright (C) 2017, 2018 xdg-desktop-portal-gtk's COPYRIGHT HOLDER +# Copyright (C) 2017, 2018, 2019 xdg-desktop-portal-gtk's COPYRIGHT HOLDER # This file is distributed under the same license as the xdg-desktop-portal-gtk package. -# Milo Casagrande , 2017, 2018. +# Milo Casagrande , 2017, 2018, 2019. # msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" -"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" -"issues\n" -"POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2018-11-21 14:50+0100\n" +"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/issues\n" +"POT-Creation-Date: 2019-03-08 15:41+0100\n" +"PO-Revision-Date: 2019-03-08 15:43+0100\n" "Last-Translator: Milo Casagrande \n" "Language-Team: Italian \n" "Language: it\n" @@ -17,13 +16,12 @@ msgstr "" "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.1.1\n" +"X-Generator: Poedit 2.2.1\n" #: data/xdg-desktop-portal-gtk.desktop.in.in:4 msgid "Portal" msgstr "Portale" -#. TRANSLATORS: Don't translate this text (this is icon name) #: data/xdg-desktop-portal-gtk.desktop.in.in:6 msgid "applications-system-symbolic" msgstr "applications-system-symbolic" @@ -36,32 +34,32 @@ msgstr "Nega accesso" msgid "Grant Access" msgstr "Consenti accesso" -#: src/accountdialog.c:166 +#: src/accountdialog.c:176 msgid "Select an Image" msgstr "Seleziona una immagine" -#: src/accountdialog.c:169 +#: src/accountdialog.c:179 msgid "Cancel" msgstr "Annulla" -#: src/accountdialog.c:170 +#: src/accountdialog.c:180 msgid "Select" msgstr "Seleziona" -#: src/accountdialog.c:171 +#: src/accountdialog.c:181 msgid "Clear" msgstr "Azzera" -#: src/accountdialog.c:185 +#: src/accountdialog.c:195 msgid "Images" msgstr "Immagini" -#: src/accountdialog.c:260 +#: src/accountdialog.c:272 #, c-format msgid "Share your personal information with %s?" msgstr "Condividere le proprie informazioni personali con %s?" -#: src/accountdialog.c:263 +#: src/accountdialog.c:275 msgid "Share your personal information with the requesting application?" msgstr "" "Condividere le proprie informazioni personali con l'applicazione che le " @@ -71,7 +69,7 @@ msgstr "" msgid "Share Details" msgstr "Dettagli" -#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 +#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:397 #: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 #: src/screenshotdialog.ui:14 msgid "_Cancel" @@ -90,7 +88,7 @@ msgstr "Applica modifiche prima di condividere" msgid "Failed to start Software" msgstr "Avvio di «Software» non riuscito" -#: src/appchooserdialog.c:398 +#: src/appchooserdialog.c:408 #, c-format msgid "" "Select an application to open “%s”. More applications are available in Software»." -#: src/appchooserdialog.c:403 +#: src/appchooserdialog.c:413 msgid "" "Select an application. More applications are available in Software." @@ -107,12 +105,12 @@ msgstr "" "Selezionare un'applicazione. Ulteriori applicazioni sono disponibili in «Software»." -#: src/appchooserdialog.c:418 +#: src/appchooserdialog.c:428 #, c-format msgid "Unable to find an application that is able to open “%s”." msgstr "Impossibile trovare una applicazione che possa aprire «%s»." -#: src/appchooserdialog.c:423 +#: src/appchooserdialog.c:433 msgid "Unable to find a suitable application." msgstr "Impossibile trovare una applicazione adatta." @@ -128,14 +126,18 @@ msgstr "Nessuna applicazione trovata" msgid "Find Compatible Applications in Software" msgstr "Trova applicazione compatibile in «Software»" -#: src/filechooser.c:390 +#: src/filechooser.c:392 msgid "_Save" msgstr "_Salva" -#: src/filechooser.c:392 +#: src/filechooser.c:394 msgid "_Open" msgstr "A_pri" +#: src/filechooser.c:552 +msgid "Open files read-only" +msgstr "Apri file in sola-lettura" + #: src/remotedesktopdialog.c:190 msgid "Pointer" msgstr "Puntatore" @@ -176,12 +178,12 @@ msgid "Select monitor to share with the requesting application" msgstr "" "Selezionare la schermata da condividere con l'applicazione che la richiede" -#: src/screenshotdialog.c:422 +#: src/screenshotdialog.c:434 #, c-format msgid "Share this screenshot with %s?" msgstr "Condividere questa schermata con %s?" -#: src/screenshotdialog.c:426 +#: src/screenshotdialog.c:438 msgid "Share this screenshot with the requesting application?" msgstr "Condividere questa schermata con l'applicazione che la richiede?" From e4043c18cd0ee9210014fef23338c8f2c2687b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 25 Jan 2019 08:56:59 +0100 Subject: [PATCH 12/24] screencast: Use ScreenCastSourceType for selected source type No need to have a different enum with the same values. Also remove an unused 'any' enum value. --- src/gnomescreencast.c | 11 +++++++---- src/screencast.c | 7 ------- src/screencast.h | 6 ++++++ src/screencastwidget.c | 2 +- src/screencastwidget.h | 5 +---- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c index f5ed486..d900f4b 100644 --- a/src/gnomescreencast.c +++ b/src/gnomescreencast.c @@ -330,20 +330,23 @@ gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_scree g_variant_iter_init (&selections_iter, selections); while ((selection = g_variant_iter_next_value (&selections_iter))) { - ScreenCastSelection selection_type; + ScreenCastSourceType source_type; g_autofree char *key = NULL; g_variant_get (selection, "(us)", - &selection_type, + &source_type, &key); - switch (selection_type) + switch (source_type) { - case SCREEN_CAST_SELECTION_MONITOR: + case SCREEN_CAST_SOURCE_TYPE_MONITOR: if (!gnome_screen_cast_session_record_monitor (gnome_screen_cast_session, key, error)) return FALSE; break; + case SCREEN_CAST_SOURCE_TYPE_WINDOW: + g_assert_not_reached (); + return FALSE; } } diff --git a/src/screencast.c b/src/screencast.c index c07be25..3ce8227 100644 --- a/src/screencast.c +++ b/src/screencast.c @@ -37,13 +37,6 @@ typedef struct _ScreenCastDialogHandle ScreenCastDialogHandle; -typedef enum _ScreenCastSourceType -{ - SCREEN_CAST_SOURCE_TYPE_ANY, - SCREEN_CAST_SOURCE_TYPE_MONITOR, - SCREEN_CAST_SOURCE_TYPE_WINDOW, -} ScreenCastSourceType; - typedef struct _ScreenCastSession { Session parent; diff --git a/src/screencast.h b/src/screencast.h index c413f00..c839c1e 100644 --- a/src/screencast.h +++ b/src/screencast.h @@ -21,5 +21,11 @@ #include #include +typedef enum _ScreenCastSourceType +{ + SCREEN_CAST_SOURCE_TYPE_MONITOR = 1, + SCREEN_CAST_SOURCE_TYPE_WINDOW = 2, +} ScreenCastSourceType; + gboolean screen_cast_init (GDBusConnection *connection, GError **error); diff --git a/src/screencastwidget.c b/src/screencastwidget.c index 1cbb2b3..3dc78d6 100644 --- a/src/screencastwidget.c +++ b/src/screencastwidget.c @@ -200,7 +200,7 @@ add_selections (ScreenCastWidget *widget, quark_monitor_widget_data); g_variant_builder_add (source_selections_builder, "(us)", - SCREEN_CAST_SELECTION_MONITOR, + SCREEN_CAST_SOURCE_TYPE_MONITOR, monitor_get_connector (monitor)); } g_list_free (selected_rows); diff --git a/src/screencastwidget.h b/src/screencastwidget.h index d8baf96..0f06683 100644 --- a/src/screencastwidget.h +++ b/src/screencastwidget.h @@ -20,10 +20,7 @@ #include -typedef enum _ScreenCastSelection -{ - SCREEN_CAST_SELECTION_MONITOR -} ScreenCastSelection; +#include "screencast.h" typedef struct _ScreenCastWidget ScreenCastWidget; From b4720bb47b7b53e805b1db45757d1e0537354f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 25 Jan 2019 09:01:04 +0100 Subject: [PATCH 13/24] screencast: Pass screen cast selection as struct Currently it only contains a single parameter: multiple, used to tell whether the user can select multiple sources or not. --- src/remotedesktop.c | 16 +++++++--------- src/remotedesktop.h | 3 ++- src/remotedesktopdialog.c | 24 ++++++++++++++---------- src/remotedesktopdialog.h | 5 +++-- src/screencast.c | 14 +++++++------- src/screencast.h | 5 +++++ src/screencastdialog.c | 4 ++-- src/screencastdialog.h | 4 +++- 8 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/remotedesktop.c b/src/remotedesktop.c index 91fad5e..c022c00 100644 --- a/src/remotedesktop.c +++ b/src/remotedesktop.c @@ -65,10 +65,8 @@ typedef struct _RemoteDesktopSession struct { RemoteDesktopDeviceType device_types; - struct { - gboolean enable; - gboolean multiple; - } screen_cast; + gboolean screen_cast_enable; + ScreenCastSelection screen_cast; } select; struct { @@ -124,10 +122,10 @@ is_remote_desktop_session (Session *session) void remote_desktop_session_sources_selected (RemoteDesktopSession *session, - gboolean multiple) + ScreenCastSelection *selection) { - session->select.screen_cast.enable = TRUE; - session->select.screen_cast.multiple = multiple; + session->select.screen_cast_enable = TRUE; + session->select.screen_cast = *selection; } static void @@ -238,8 +236,8 @@ create_remote_desktop_dialog (RemoteDesktopSession *session, dialog = GTK_WIDGET (remote_desktop_dialog_new (request->app_id, session->select.device_types, - session->select.screen_cast.enable, - session->select.screen_cast.multiple)); + session->select.screen_cast_enable ? + &session->select.screen_cast : NULL)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); diff --git a/src/remotedesktop.h b/src/remotedesktop.h index a3ae316..ea8cfde 100644 --- a/src/remotedesktop.h +++ b/src/remotedesktop.h @@ -22,6 +22,7 @@ #include #include "session.h" +#include "screencast.h" typedef struct _RemoteDesktopSession RemoteDesktopSession; @@ -40,7 +41,7 @@ typedef enum _RemoteDesktopDeviceType gboolean is_remote_desktop_session (Session *session); void remote_desktop_session_sources_selected (RemoteDesktopSession *session, - gboolean multiple); + ScreenCastSelection *select); gboolean remote_desktop_init (GDBusConnection *connection, GError **error); diff --git a/src/remotedesktopdialog.c b/src/remotedesktopdialog.c index fcb9a01..3e964e8 100644 --- a/src/remotedesktopdialog.c +++ b/src/remotedesktopdialog.c @@ -36,10 +36,8 @@ struct _RemoteDesktopDialog RemoteDesktopDeviceType device_types; - struct { - gboolean enable; - gboolean multiple; - } screen_cast; + gboolean screen_cast_enable; + ScreenCastSelection screen_cast; gboolean is_device_types_selected; gboolean is_screen_cast_sources_selected; @@ -108,7 +106,7 @@ button_clicked (GtkWidget *button, g_variant_builder_init (&selections_builder, G_VARIANT_TYPE_VARDICT); add_device_type_selections (dialog, &selections_builder); - if (dialog->screen_cast.enable) + if (dialog->screen_cast_enable) screen_cast_widget_add_selections (screen_cast_widget, &selections_builder); selections = g_variant_builder_end (&selections_builder); @@ -282,16 +280,22 @@ on_has_selection_changed (ScreenCastWidget *screen_cast_widget, RemoteDesktopDialog * remote_desktop_dialog_new (const char *app_id, RemoteDesktopDeviceType device_types, - gboolean screen_cast_enable, - gboolean screen_cast_multiple) + ScreenCastSelection *screen_cast_select) { RemoteDesktopDialog *dialog; g_autofree char *heading = NULL; dialog = g_object_new (REMOTE_DESKTOP_TYPE_DIALOG, NULL); dialog->device_types = device_types; - dialog->screen_cast.enable = screen_cast_enable; - dialog->screen_cast.multiple = screen_cast_multiple; + if (screen_cast_select) + { + dialog->screen_cast_enable = TRUE; + dialog->screen_cast = *screen_cast_select; + } + else + { + dialog->screen_cast_enable = FALSE; + } if (g_strcmp0 (app_id, "") != 0) { @@ -308,7 +312,7 @@ remote_desktop_dialog_new (const char *app_id, heading = g_strdup (_("Select devices to share with the requesting application")); } - if (screen_cast_enable) + if (dialog->screen_cast_enable) { g_signal_connect (dialog->screen_cast_widget, "has-selection-changed", G_CALLBACK (on_has_selection_changed), dialog); diff --git a/src/remotedesktopdialog.h b/src/remotedesktopdialog.h index 426f629..5d795fd 100644 --- a/src/remotedesktopdialog.h +++ b/src/remotedesktopdialog.h @@ -20,11 +20,12 @@ #include +#include "screencast.h" + #define REMOTE_DESKTOP_TYPE_DIALOG (remote_desktop_dialog_get_type ()) G_DECLARE_FINAL_TYPE (RemoteDesktopDialog, remote_desktop_dialog, REMOTE_DESKTOP, DIALOG, GtkWindow) RemoteDesktopDialog * remote_desktop_dialog_new (const char *app_id, RemoteDesktopDeviceType device_types, - gboolean screen_cast_enable, - gboolean screen_cast_multiple); + ScreenCastSelection *screen_cast_select); diff --git a/src/screencast.c b/src/screencast.c index 3ce8227..dc67945 100644 --- a/src/screencast.c +++ b/src/screencast.c @@ -47,9 +47,7 @@ typedef struct _ScreenCastSession char *parent_window; - struct { - gboolean multiple; - } select; + ScreenCastSelection select; GDBusMethodInvocation *start_invocation; ScreenCastDialogHandle *dialog_handle; @@ -206,7 +204,7 @@ create_screen_cast_dialog (ScreenCastSession *session, g_object_ref_sink (fake_parent); dialog = GTK_WIDGET (screen_cast_dialog_new (request->app_id, - session->select.multiple)); + &session->select)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); @@ -295,6 +293,7 @@ handle_select_sources (XdpImplScreenCast *object, int response; uint32_t types; gboolean multiple; + ScreenCastSelection select; GVariantBuilder results_builder; GVariant *results; @@ -319,11 +318,13 @@ handle_select_sources (XdpImplScreenCast *object, goto out; } + select.multiple = multiple; + if (is_screen_cast_session (session)) { ScreenCastSession *screen_cast_session = (ScreenCastSession *)session; - screen_cast_session->select.multiple = multiple; + screen_cast_session->select = select; response = 0; } else if (is_remote_desktop_session (session)) @@ -331,8 +332,7 @@ handle_select_sources (XdpImplScreenCast *object, RemoteDesktopSession *remote_desktop_session = (RemoteDesktopSession *)session; - remote_desktop_session_sources_selected (remote_desktop_session, - multiple); + remote_desktop_session_sources_selected (remote_desktop_session, &select); response = 0; } else diff --git a/src/screencast.h b/src/screencast.h index c839c1e..3a89df6 100644 --- a/src/screencast.h +++ b/src/screencast.h @@ -27,5 +27,10 @@ typedef enum _ScreenCastSourceType SCREEN_CAST_SOURCE_TYPE_WINDOW = 2, } ScreenCastSourceType; +typedef struct _ScreenCastSelection +{ + gboolean multiple; +} ScreenCastSelection; + gboolean screen_cast_init (GDBusConnection *connection, GError **error); diff --git a/src/screencastdialog.c b/src/screencastdialog.c index afbbc04..b6a51b0 100644 --- a/src/screencastdialog.c +++ b/src/screencastdialog.c @@ -95,7 +95,7 @@ on_has_selection_changed (ScreenCastWidget *screen_cast_widget, ScreenCastDialog * screen_cast_dialog_new (const char *app_id, - gboolean multiple) + ScreenCastSelection *select) { ScreenCastDialog *dialog; ScreenCastWidget *screen_cast_widget; @@ -103,7 +103,7 @@ screen_cast_dialog_new (const char *app_id, dialog = g_object_new (SCREEN_CAST_TYPE_DIALOG, NULL); screen_cast_widget = SCREEN_CAST_WIDGET (dialog->screen_cast_widget); screen_cast_widget_set_app_id (screen_cast_widget, app_id); - screen_cast_widget_set_allow_multiple (screen_cast_widget, multiple); + screen_cast_widget_set_allow_multiple (screen_cast_widget, select->multiple); return dialog; } diff --git a/src/screencastdialog.h b/src/screencastdialog.h index cfe71be..247d93b 100644 --- a/src/screencastdialog.h +++ b/src/screencastdialog.h @@ -20,9 +20,11 @@ #include +#include "screencast.h" + #define SCREEN_CAST_TYPE_DIALOG (screen_cast_dialog_get_type ()) G_DECLARE_FINAL_TYPE (ScreenCastDialog, screen_cast_dialog, SCREEN_CAST, DIALOG, GtkWindow) ScreenCastDialog * screen_cast_dialog_new (const char *app_id, - gboolean multiple); + ScreenCastSelection *select); From 00769831c9452b67a39f959ce6b1e59fdf6dd470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 26 Apr 2019 16:37:59 +0200 Subject: [PATCH 14/24] screencast: Add support for cursor modes More or less a direct translation to the Mutter API. --- src/gnomescreencast.c | 40 +++++++++++++++++++++++++++++++++++++++- src/gnomescreencast.h | 5 +++++ src/remotedesktop.c | 1 + src/screencast.c | 39 +++++++++++++++++++++++++++++++++++++++ src/screencast.h | 9 +++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c index d900f4b..30183c4 100644 --- a/src/gnomescreencast.c +++ b/src/gnomescreencast.c @@ -250,9 +250,29 @@ gnome_screen_cast_session_add_stream_properties (GnomeScreenCastSession *gnome_s } } +static uint32_t +cursor_mode_to_gnome_cursor_mode (ScreenCastCursorMode cursor_mode) +{ + switch (cursor_mode) + { + case SCREEN_CAST_CURSOR_MODE_NONE: + g_assert_not_reached (); + return -1; + case SCREEN_CAST_CURSOR_MODE_HIDDEN: + return 0; + case SCREEN_CAST_CURSOR_MODE_EMBEDDED: + return 1; + case SCREEN_CAST_CURSOR_MODE_METADATA: + return 2; + } + + g_assert_not_reached (); +} + static gboolean gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_cast_session, const char *connector, + ScreenCastSelection *select, GError **error) { OrgGnomeMutterScreenCastSession *session_proxy = @@ -266,6 +286,15 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_c GVariant *parameters; g_variant_builder_init (&properties_builder, G_VARIANT_TYPE_VARDICT); + if (select->cursor_mode) + { + uint32_t gnome_cursor_mode; + + gnome_cursor_mode = cursor_mode_to_gnome_cursor_mode (select->cursor_mode); + g_variant_builder_add (&properties_builder, "{sv}", + "cursor-mode", + g_variant_new_uint32 (gnome_cursor_mode)); + } properties = g_variant_builder_end (&properties_builder); if (!org_gnome_mutter_screen_cast_session_call_record_monitor_sync (session_proxy, @@ -322,6 +351,7 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_c gboolean gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session, GVariant *selections, + ScreenCastSelection *select, GError **error) { GVariantIter selections_iter; @@ -341,7 +371,9 @@ gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_scree { case SCREEN_CAST_SOURCE_TYPE_MONITOR: if (!gnome_screen_cast_session_record_monitor (gnome_screen_cast_session, - key, error)) + key, + select, + error)) return FALSE; break; case SCREEN_CAST_SOURCE_TYPE_WINDOW: @@ -484,6 +516,12 @@ gnome_screen_cast_create_session (GnomeScreenCast *gnome_screen_cast, return gnome_screen_cast_session; } +int +gnome_screen_cast_get_api_version (GnomeScreenCast *gnome_screen_cast) +{ + return gnome_screen_cast->api_version; +} + static void gnome_screen_cast_name_appeared (GDBusConnection *connection, const char *name, diff --git a/src/gnomescreencast.h b/src/gnomescreencast.h index eee8d3b..06e4e1e 100644 --- a/src/gnomescreencast.h +++ b/src/gnomescreencast.h @@ -22,6 +22,8 @@ #include #include +#include "screencast.h" + typedef struct _GnomeScreenCast GnomeScreenCast; typedef struct _GnomeScreenCastSession GnomeScreenCastSession; typedef struct _GnomeScreenCastStream GnomeScreenCastStream; @@ -34,6 +36,7 @@ void gnome_screen_cast_session_add_stream_properties (GnomeScreenCastSession *gn gboolean gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session, GVariant *selections, + ScreenCastSelection *select, GError **error); gboolean gnome_screen_cast_session_stop (GnomeScreenCastSession *gnome_screen_cast_session, @@ -46,4 +49,6 @@ GnomeScreenCastSession *gnome_screen_cast_create_session (GnomeScreenCast *gnome const char *remote_desktop_session_id, GError **error); +int gnome_screen_cast_get_api_version (GnomeScreenCast *gnome_screen_cast); + GnomeScreenCast *gnome_screen_cast_new (GDBusConnection *connection); diff --git a/src/remotedesktop.c b/src/remotedesktop.c index c022c00..c2aefd5 100644 --- a/src/remotedesktop.c +++ b/src/remotedesktop.c @@ -482,6 +482,7 @@ open_screen_cast_session (RemoteDesktopSession *remote_desktop_session, if (!gnome_screen_cast_session_record_selections (gnome_screen_cast_session, source_selections, + &remote_desktop_session->select.screen_cast, error)) return FALSE; diff --git a/src/screencast.c b/src/screencast.c index dc67945..7c8e799 100644 --- a/src/screencast.c +++ b/src/screencast.c @@ -35,6 +35,8 @@ #include "session.h" #include "utils.h" +#define SUPPORTED_MUTTER_SCREEN_CAST_API_VERSION 2 + typedef struct _ScreenCastDialogHandle ScreenCastDialogHandle; typedef struct _ScreenCastSession @@ -293,6 +295,7 @@ handle_select_sources (XdpImplScreenCast *object, int response; uint32_t types; gboolean multiple; + ScreenCastCursorMode cursor_mode; ScreenCastSelection select; GVariantBuilder results_builder; GVariant *results; @@ -318,7 +321,23 @@ handle_select_sources (XdpImplScreenCast *object, goto out; } + if (!g_variant_lookup (arg_options, "cursor_mode", "u", &cursor_mode)) + cursor_mode = SCREEN_CAST_CURSOR_MODE_HIDDEN; + + switch (cursor_mode) + { + case SCREEN_CAST_CURSOR_MODE_HIDDEN: + case SCREEN_CAST_CURSOR_MODE_EMBEDDED: + case SCREEN_CAST_CURSOR_MODE_METADATA: + break; + default: + g_warning ("Unknown screen cast cursor mode"); + response = 2; + goto out; + } + select.multiple = multiple; + select.cursor_mode = cursor_mode; if (is_screen_cast_session (session)) { @@ -394,6 +413,7 @@ start_session (ScreenCastSession *screen_cast_session, GError **error) { GnomeScreenCastSession *gnome_screen_cast_session; + int gnome_api_version; g_autoptr(GVariant) source_selections = NULL; gnome_screen_cast_session = @@ -401,6 +421,14 @@ start_session (ScreenCastSession *screen_cast_session, if (!gnome_screen_cast_session) return FALSE; + gnome_api_version = gnome_screen_cast_get_api_version (gnome_screen_cast); + if (gnome_api_version < SUPPORTED_MUTTER_SCREEN_CAST_API_VERSION) + { + g_warning ("org.gnome.Mutter.ScreenCast API version not compatible"); + g_clear_object (&gnome_screen_cast); + return FALSE; + } + screen_cast_session->gnome_screen_cast_session = gnome_screen_cast_session; screen_cast_session->session_ready_handler_id = @@ -416,6 +444,7 @@ start_session (ScreenCastSession *screen_cast_session, &source_selections); if (!gnome_screen_cast_session_record_selections (gnome_screen_cast_session, source_selections, + &screen_cast_session->select, error)) return FALSE; @@ -495,6 +524,8 @@ handle_start (XdpImplScreenCast *object, static void on_gnome_screen_cast_enabled (GnomeScreenCast *gnome_screen_cast) { + int gnome_api_version; + ScreenCastCursorMode available_cursor_modes; g_autoptr(GError) error = NULL; impl = G_DBUS_INTERFACE_SKELETON (xdp_impl_screen_cast_skeleton_new ()); @@ -506,8 +537,16 @@ on_gnome_screen_cast_enabled (GnomeScreenCast *gnome_screen_cast) g_signal_connect (impl, "handle-start", G_CALLBACK (handle_start), NULL); + gnome_api_version = gnome_screen_cast_get_api_version (gnome_screen_cast); + + available_cursor_modes = SCREEN_CAST_CURSOR_MODE_NONE; + if (gnome_api_version >= 2) + available_cursor_modes |= (SCREEN_CAST_CURSOR_MODE_HIDDEN | + SCREEN_CAST_CURSOR_MODE_EMBEDDED | + SCREEN_CAST_CURSOR_MODE_METADATA); g_object_set (G_OBJECT (impl), "available-source-types", SCREEN_CAST_SOURCE_TYPE_MONITOR, + "available-cursor-modes", available_cursor_modes, NULL); if (!g_dbus_interface_skeleton_export (impl, diff --git a/src/screencast.h b/src/screencast.h index 3a89df6..ccc3633 100644 --- a/src/screencast.h +++ b/src/screencast.h @@ -27,9 +27,18 @@ typedef enum _ScreenCastSourceType SCREEN_CAST_SOURCE_TYPE_WINDOW = 2, } ScreenCastSourceType; +typedef enum _ScreenCastCursorMode +{ + SCREEN_CAST_CURSOR_MODE_NONE = 0, + SCREEN_CAST_CURSOR_MODE_HIDDEN = 1, + SCREEN_CAST_CURSOR_MODE_EMBEDDED = 2, + SCREEN_CAST_CURSOR_MODE_METADATA = 4, +} ScreenCastCursorMode; + typedef struct _ScreenCastSelection { gboolean multiple; + ScreenCastCursorMode cursor_mode; } ScreenCastSelection; gboolean screen_cast_init (GDBusConnection *connection, From 7dd8ee1045a924650e6f44569f4bcf4b7a553d52 Mon Sep 17 00:00:00 2001 From: Zephyr Waitzman Date: Fri, 3 May 2019 01:16:24 +0800 Subject: [PATCH 15/24] Update Chinese (Simplified, China) Translation --- po/zh_CN.po | 95 +++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/po/zh_CN.po b/po/zh_CN.po index 78f791b..b6041ad 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -2,6 +2,7 @@ # Copyright (C) 2016 xdg-desktop-portal-gtk's COPYRIGHT HOLDER # This file is distributed under the same license as the xdg-desktop-portal-gtk package. # Mingye Wang , 2016. +# 王滋涵 Zephyr Waitzman , 2019. # msgid "" msgstr "" @@ -9,23 +10,23 @@ msgstr "" "Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" "issues\n" "POT-Creation-Date: 2018-11-16 15:18-0500\n" -"PO-Revision-Date: 2016-10-28 18:05-0400\n" -"Last-Translator: Mingye Wang (Arthur2e5) \n" +"PO-Revision-Date: 2019-05-03 01:13+0800\n" +"Last-Translator: 王滋涵 Zephyr Waitzman \n" "Language-Team: Chinese (China) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.7\n" +"X-Generator: Poedit 2.2.1\n" #: data/xdg-desktop-portal-gtk.desktop.in.in:4 msgid "Portal" -msgstr "" +msgstr "门户" #. TRANSLATORS: Don't translate this text (this is icon name) #: data/xdg-desktop-portal-gtk.desktop.in.in:6 msgid "applications-system-symbolic" -msgstr "" +msgstr "applications-system-symbolic" #: src/access.c:271 msgid "Deny Access" @@ -33,43 +34,40 @@ msgstr "拒绝访问" #: src/access.c:274 msgid "Grant Access" -msgstr "允许访问" +msgstr "授权访问" #: src/accountdialog.c:166 msgid "Select an Image" -msgstr "" +msgstr "选择一张图像" #: src/accountdialog.c:169 -#, fuzzy msgid "Cancel" -msgstr "取消(_C)" +msgstr "取消" #: src/accountdialog.c:170 -#, fuzzy msgid "Select" -msgstr "选择(_S)" +msgstr "选择" #: src/accountdialog.c:171 msgid "Clear" -msgstr "" +msgstr "清除" #: src/accountdialog.c:185 msgid "Images" -msgstr "" +msgstr "图像" #: src/accountdialog.c:260 #, c-format msgid "Share your personal information with %s?" -msgstr "" +msgstr "与 %s 共享您的个人信息?" #: src/accountdialog.c:263 -#, fuzzy msgid "Share your personal information with the requesting application?" -msgstr "与正发出请求的应用程序共享此截图吗?" +msgstr "与请求应用申请共享您的个人信息?" #: src/accountdialog.ui:10 msgid "Share Details" -msgstr "" +msgstr "分享详情" #: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 #: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 @@ -84,11 +82,11 @@ msgstr "分享(_S)" #: src/accountdialog.ui:148 msgid "Make changes before sharing the information" -msgstr "" +msgstr "在共享信息之前进行更改" #: src/appchooserdialog.c:159 msgid "Failed to start Software" -msgstr "" +msgstr "无法启动软件" #: src/appchooserdialog.c:398 #, c-format @@ -96,38 +94,38 @@ msgid "" "Select an application to open “%s”. More applications are available in Software." msgstr "" +"选择一款打开 “%s” 的应用。软件中心有更多应用。" #: src/appchooserdialog.c:403 msgid "" "Select an application. More applications are available in Software." -msgstr "" +msgstr "选择一款应用。软件中心有更多应用。" #: src/appchooserdialog.c:418 #, c-format msgid "Unable to find an application that is able to open “%s”." -msgstr "" +msgstr "找不到可以打开 “%s” 的应用。" #: src/appchooserdialog.c:423 msgid "Unable to find a suitable application." -msgstr "" +msgstr "找不到适合的应用。" #: src/appchooserdialog.ui:13 msgid "Open With" msgstr "打开方式" #: src/appchooserdialog.ui:166 -#, fuzzy msgid "No Applications Found" -msgstr "选择应用程序" +msgstr "非找到应用" #: src/appchooserdialog.ui:182 msgid "Find Compatible Applications in Software" -msgstr "" +msgstr "在软件中查找兼容的应用程序" #: src/filechooser.c:390 msgid "_Save" -msgstr "" +msgstr "保存(_S)" #: src/filechooser.c:392 msgid "_Open" @@ -135,44 +133,41 @@ msgstr "打开(_O)" #: src/remotedesktopdialog.c:190 msgid "Pointer" -msgstr "" +msgstr "指针" #: src/remotedesktopdialog.c:193 msgid "Keyboard" -msgstr "" +msgstr "键盘" #: src/remotedesktopdialog.c:196 msgid "Touch screen" -msgstr "" +msgstr "触摸屏" #: src/remotedesktopdialog.c:303 #, c-format msgid "Select devices to share with %s" -msgstr "" +msgstr "选择要与 %s 共享的设备" #: src/remotedesktopdialog.c:308 -#, fuzzy msgid "Select devices to share with the requesting application" -msgstr "与正发出请求的应用程序共享此截图吗?" +msgstr "选择要与请求应用程序共享的设备" #: src/remotedesktopdialog.ui:12 msgid "Remote desktop" -msgstr "" +msgstr "远程桌面" #: src/screencastdialog.ui:12 -#, fuzzy msgid "Screen casting" -msgstr "截屏" +msgstr "录屏" #: src/screencastwidget.c:243 #, c-format msgid "Select monitor to share with %s" -msgstr "" +msgstr "选择与 %s 共享的监视器" #: src/screencastwidget.c:248 -#, fuzzy msgid "Select monitor to share with the requesting application" -msgstr "与正发出请求的应用程序共享此截图吗?" +msgstr "选择与请求应用共享的监视器" #: src/screenshotdialog.c:422 #, c-format @@ -189,49 +184,47 @@ msgstr "截屏" #: src/screenshotdialog.ui:30 msgid "_Options…" -msgstr "" +msgstr "选项(_O)" #: src/screenshotdialog.ui:55 -#, fuzzy msgid "Take _Screenshot" -msgstr "截屏" +msgstr "截图" #: src/screenshotdialog.ui:111 -#, fuzzy msgid "Take Screenshot" -msgstr "截屏" +msgstr "截图" #: src/screenshotdialog.ui:122 msgid "Grab the whole sc_reen" -msgstr "" +msgstr "抓取当前屏幕(_R)" #: src/screenshotdialog.ui:133 msgid "Grab the current _window" -msgstr "" +msgstr "抓取当前窗口(_W)" #: src/screenshotdialog.ui:144 msgid "Select _area to grab" -msgstr "" +msgstr "选择截取区域(_A)" #: src/screenshotdialog.ui:158 msgid "Grab after a _delay of" -msgstr "" +msgstr "在延迟后抓取(_D)" #: src/screenshotdialog.ui:171 msgid "seconds" -msgstr "" +msgstr "秒" #: src/screenshotdialog.ui:181 msgid "Effects" -msgstr "" +msgstr "效果" #: src/screenshotdialog.ui:192 msgid "Include _pointer" -msgstr "" +msgstr "包含指针(_P)" #: src/screenshotdialog.ui:201 msgid "Include the window _border" -msgstr "" +msgstr "包含窗口边框(_B)" #~ msgid "_Select" #~ msgstr "选择(_S)" From 3b6da7c16af1d15faaacf25357805314c8e107ec Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Fri, 3 May 2019 10:49:48 -0300 Subject: [PATCH 16/24] Update Brazilian Portuguese translation --- po/pt_BR.po | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/po/pt_BR.po b/po/pt_BR.po index 7384d94..de6db33 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -1,22 +1,23 @@ # Brazilian Portuguese translation for xdg-desktop-portal-gtk. -# Copyright (C) 2018 xdg-desktop-portal-gtk's COPYRIGHT HOLDER +# Copyright (C) 2019 xdg-desktop-portal-gtk's COPYRIGHT HOLDER # This file is distributed under the same license as the xdg-desktop-portal-gtk package. -# Rafael Fontenelle , 2016-2018. +# Rafael Fontenelle , 2016-2019. +# msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk master\n" "Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" "issues\n" -"POT-Creation-Date: 2018-12-07 03:29+0000\n" -"PO-Revision-Date: 2018-12-07 11:10-0200\n" +"POT-Creation-Date: 2019-05-03 03:29+0000\n" +"PO-Revision-Date: 2019-05-03 10:47-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" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Virtaal 1.0.0-beta1\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"X-Generator: Gtranslator 3.32.0\n" #: data/xdg-desktop-portal-gtk.desktop.in.in:4 msgid "Portal" @@ -68,7 +69,7 @@ msgstr "Compartilhar suas informações pessoais com o aplicativo requisitante?" msgid "Share Details" msgstr "Compartilhar detalhes" -#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 +#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:397 #: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 #: src/screenshotdialog.ui:14 msgid "_Cancel" @@ -125,32 +126,36 @@ msgstr "Nenhum aplicativo localizado" msgid "Find Compatible Applications in Software" msgstr "Localizar aplicativos compatíveis no Software" -#: src/filechooser.c:390 +#: src/filechooser.c:392 msgid "_Save" msgstr "_Salvar" -#: src/filechooser.c:392 +#: src/filechooser.c:394 msgid "_Open" msgstr "_Abrir" -#: src/remotedesktopdialog.c:190 +#: src/filechooser.c:552 +msgid "Open files read-only" +msgstr "Abrir arquivos em somente leitura" + +#: src/remotedesktopdialog.c:188 msgid "Pointer" msgstr "Cursor do mouse" -#: src/remotedesktopdialog.c:193 +#: src/remotedesktopdialog.c:191 msgid "Keyboard" msgstr "Teclado" -#: src/remotedesktopdialog.c:196 +#: src/remotedesktopdialog.c:194 msgid "Touch screen" msgstr "Tela sensível ao toque" -#: src/remotedesktopdialog.c:303 +#: src/remotedesktopdialog.c:307 #, c-format msgid "Select devices to share with %s" msgstr "Selecione os dispositivos para compartilhar com %s" -#: src/remotedesktopdialog.c:308 +#: src/remotedesktopdialog.c:312 msgid "Select devices to share with the requesting application" msgstr "" "Selecione os dispositivos para compartilhar com aplicativo requisitante" From a43fd8829b4c1a4b878a949f865021329aebb2e8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 9 May 2019 23:58:05 +0000 Subject: [PATCH 17/24] lockdown: Use the right property name The property was renamed to disable-sound-output. Follow along. --- src/lockdown.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lockdown.c b/src/lockdown.c index 25e738f..a3c0134 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -62,7 +62,7 @@ lockdown_init (GDBusConnection *bus, if (g_settings_schema_has_key (schema, "disable-microphone")) g_settings_bind (privacy, "disable-microphone", helper, "disable-sound-output", G_SETTINGS_BIND_DEFAULT); if (g_settings_schema_has_key (schema, "disable-sound-output")) - g_settings_bind (privacy, "disable-sound-output", helper, "disable-sound", G_SETTINGS_BIND_DEFAULT); + g_settings_bind (privacy, "disable-sound-output", helper, "disable-sound-output", G_SETTINGS_BIND_DEFAULT); g_settings_schema_unref (schema); From 7c9ec86bc92bfb1895cf32366cc9eabc200d4034 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 16 May 2019 10:28:09 -0400 Subject: [PATCH 18/24] Background monitor (#198) * Break out the fdo notification support Move the fdo support code behind an api. This is in preparation for using it from the background portal backend. * Initial background implementation Add a portal backend for getting the list of active applications, and for showing a notification about apps that are running in the background. * background: Support autostart Implement the EnableAutostart method by generating an autostart file for the application in XDG_CONFIG_HOME/autostart. * background: Work around gnome-shell The gnome-shell introspection api returns us desktop file names instead of proper app ids. Work around this by looking for X-Flatpak. * fixup! background: Support autostart Use flags for autostart * fixup! Initial background implementation More flexible NotifyBackground api * fixup! Initial background implementation Add an allow-once option * fixup! background: Support autostart quote commandline --- data/gtk.portal | 2 +- src/Makefile.am.inc | 6 + src/background.c | 449 +++++++++++++++++++++++++++++++++++ src/background.h | 25 ++ src/fdonotification.c | 433 +++++++++++++++++++++++++++++++++ src/fdonotification.h | 41 ++++ src/notification.c | 409 ++----------------------------- src/xdg-desktop-portal-gtk.c | 7 + 8 files changed, 981 insertions(+), 391 deletions(-) create mode 100644 src/background.c create mode 100644 src/background.h create mode 100644 src/fdonotification.c create mode 100644 src/fdonotification.h diff --git a/data/gtk.portal b/data/gtk.portal index 041cef4..fcef5b8 100644 --- a/data/gtk.portal +++ b/data/gtk.portal @@ -1,4 +1,4 @@ [portal] DBusName=org.freedesktop.impl.portal.desktop.gtk -Interfaces=org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.AppChooser;org.freedesktop.impl.portal.Print;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Notification;org.freedesktop.impl.portal.Inhibit;org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.Account;org.freedesktop.impl.portal.Email;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.RemoteDesktop;org.freedesktop.impl.portal.Lockdown; +Interfaces=org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.AppChooser;org.freedesktop.impl.portal.Print;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Notification;org.freedesktop.impl.portal.Inhibit;org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.Account;org.freedesktop.impl.portal.Email;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.RemoteDesktop;org.freedesktop.impl.portal.Lockdown;org.freedesktop.impl.portal.Background; UseIn=gnome diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index ee46885..62d0c2f 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -22,6 +22,7 @@ $(dbus_built_sources): src/Makefile.am.inc $(DESKTOP_PORTAL_INTERFACES_DIR)/org.freedesktop.impl.portal.ScreenCast.xml \ $(DESKTOP_PORTAL_INTERFACES_DIR)/org.freedesktop.impl.portal.RemoteDesktop.xml \ $(DESKTOP_PORTAL_INTERFACES_DIR)/org.freedesktop.impl.portal.Lockdown.xml \ + $(DESKTOP_PORTAL_INTERFACES_DIR)/org.freedesktop.impl.portal.Background.xml \ $(NULL) shell_built_sources = src/shell-dbus.c src/shell-dbus.h @@ -35,6 +36,7 @@ $(shell_built_sources): src/Makefile.am.inc $(top_srcdir)/data/org.gnome.Mutter.ScreenCast.xml \ $(top_srcdir)/data/org.gnome.Mutter.RemoteDesktop.xml \ $(top_srcdir)/data/org.gnome.Shell.Screenshot.xml \ + $(top_srcdir)/data/org.gnome.Shell.Introspect.xml \ $(top_srcdir)/data/org.gtk.Notifications.xml \ $(top_srcdir)/data/org.gnome.SessionManager.xml \ $(top_srcdir)/data/org.gnome.ScreenSaver.xml \ @@ -81,6 +83,8 @@ xdg_desktop_portal_gtk_SOURCES = \ src/appchooser.c \ src/notification.h \ src/notification.c \ + src/fdonotification.h \ + src/fdonotification.c \ src/inhibit.h \ src/inhibit.c \ src/appchooserrow.h \ @@ -121,6 +125,8 @@ xdg_desktop_portal_gtk_SOURCES = \ src/displaystatetracker.h \ src/lockdown.c \ src/lockdown.h \ + src/background.c \ + src/background.h \ $(NULL) nodist_xdg_desktop_portal_gtk_SOURCES = \ diff --git a/src/background.c b/src/background.c new file mode 100644 index 0000000..c4c7a1f --- /dev/null +++ b/src/background.c @@ -0,0 +1,449 @@ +#define _GNU_SOURCE 1 + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "xdg-desktop-portal-dbus.h" +#include "shell-dbus.h" + +#include "background.h" +#include "fdonotification.h" +#include "request.h" +#include "utils.h" + +static OrgGnomeShellIntrospect *shell; + +typedef enum { BACKGROUND, RUNNING, ACTIVE } AppState; + +static char * +get_actual_app_id (const char *app_id) +{ + g_autoptr(GDesktopAppInfo) info = g_desktop_app_info_new (app_id); + char *app = NULL; + + if (info) + app = g_desktop_app_info_get_string (info, "X-Flatpak"); + + g_debug ("looking up app id for %s: %s", app_id, app); + + return app; +} + +static gboolean +handle_get_app_state (XdpImplBackground *object, + GDBusMethodInvocation *invocation) +{ + g_autoptr(GVariant) windows = NULL; + g_autoptr(GHashTable) app_states = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_autoptr(GError) error = NULL; + GVariantBuilder builder; + GHashTableIter iter; + const char *key; + gpointer value; + + g_debug ("background: handle GetAppState"); + + if (!org_gnome_shell_introspect_call_get_windows_sync (shell, &windows, NULL, &error)) + { + g_dbus_method_invocation_return_error (invocation, + XDG_DESKTOP_PORTAL_ERROR, + XDG_DESKTOP_PORTAL_ERROR_FAILED, + "Could not get window list: %s", error->message); + return TRUE; + } + + if (windows) + { + g_autoptr(GVariantIter) iter = g_variant_iter_new (windows); + GVariant *dict; + + while (g_variant_iter_loop (iter, "{t@a{sv}}", NULL, &dict)) + { + const char *app_id = NULL; + char *app; + gboolean hidden = FALSE; + gboolean focus = FALSE; + AppState state = BACKGROUND; + + g_variant_lookup (dict, "app-id", "&s", &app_id); + g_variant_lookup (dict, "is-hidden", "b", &hidden); + g_variant_lookup (dict, "has-focus", "b", &focus); + + /* See https://gitlab.gnome.org/GNOME/gnome-shell/issues/1289 */ + app = get_actual_app_id (app_id); + if (app == NULL) + continue; + + state = GPOINTER_TO_INT (g_hash_table_lookup (app_states, app)); + if (!hidden) + state = MAX (state, RUNNING); + if (focus) + state = MAX (state, ACTIVE); + + g_hash_table_insert (app_states, app, GINT_TO_POINTER (state)); + } + } + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_hash_table_iter_init (&iter, app_states); + while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) + { + g_variant_builder_add (&builder, "{sv}", key, g_variant_new_uint32 (GPOINTER_TO_UINT (value))); + } + + xdp_impl_background_complete_get_app_state (object, + invocation, + g_variant_builder_end (&builder)); + + return TRUE; +} + +typedef enum { + FORBID = 0, + ALLOW = 1, + IGNORE = 2 +} NotifyResult; + +typedef struct { + XdpImplBackground *impl; + GDBusMethodInvocation *invocation; + Request *request; + char *id; + NotifyResult result; +} BackgroundHandle; + +static void +background_handle_free (gpointer data) +{ + BackgroundHandle *handle = data; + + g_object_unref (handle->request); + g_free (handle->id); + + g_free (handle); +} + +static void +background_handle_close (BackgroundHandle *handle) +{ + GDBusConnection *connection; + + connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (handle->impl)); + + fdo_remove_notification (connection, handle->request->app_id, handle->id); + background_handle_free (handle); +} + +static void +send_response (BackgroundHandle *handle) +{ + GVariantBuilder opt_builder; + int response = 0; + + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&opt_builder, "{sv}", "result", g_variant_new_uint32 (handle->result)); + + if (handle->request->exported) + request_unexport (handle->request); + + xdp_impl_background_complete_notify_background (handle->impl, + handle->invocation, + response, + g_variant_builder_end (&opt_builder)); + + background_handle_close (handle); +} + +static void +activate_action (GDBusConnection *connection, + const char *app_id, + const char *id, + const char *name, + GVariant *parameter, + gpointer data) +{ + BackgroundHandle *handle = data; + + if (g_str_equal (name, "allow")) + { + g_debug ("Allow app %s to run in background", handle->request->app_id); + handle->result = ALLOW; + } + else if (g_str_equal (name, "forbid")) + { + g_debug ("Forbid app %s to run in background", handle->request->app_id); + handle->result = FORBID; + } + else if (g_str_equal (name, "ignore")) + { + g_debug ("Allow this instance of app %s to run in background", handle->request->app_id); + handle->result = IGNORE; + } + else + { + g_debug ("Unexpected action for app %s", handle->request->app_id); + handle->result = FORBID; + } + + send_response (handle); +} + +static gboolean +handle_close (XdpImplRequest *object, + GDBusMethodInvocation *invocation, + BackgroundHandle *handle) +{ + GVariantBuilder opt_builder; + + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + + xdp_impl_background_complete_notify_background (handle->impl, + handle->invocation, + 2, + g_variant_builder_end (&opt_builder)); + + if (handle->request->exported) + request_unexport (handle->request); + + background_handle_close (handle); + + xdp_impl_request_complete_close (object, invocation); + + return TRUE; +} + +static int count; + +static gboolean +handle_notify_background (XdpImplBackground *object, + GDBusMethodInvocation *invocation, + const char *arg_handle, + const char *arg_app_id, + const char *arg_name) +{ + g_autofree char *body = NULL; + GVariantBuilder builder; + GVariantBuilder bbuilder; + GVariantBuilder button; + GDBusConnection *connection; + const char *sender; + g_autoptr (Request) request = NULL; + BackgroundHandle *handle; + + g_debug ("background: handle NotifyBackground"); + + sender = g_dbus_method_invocation_get_sender (invocation); + request = request_new (sender, arg_app_id, arg_handle); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&builder, "{sv}", "title", g_variant_new_string (_("Background activity"))); + + body = g_strdup_printf (_("%s is running in the background."), arg_name); + g_variant_builder_add (&builder, "{sv}", "body", g_variant_new_string (body)); + + g_variant_builder_init (&bbuilder, G_VARIANT_TYPE ("aa{sv}")); + g_variant_builder_init (&button, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&button, "{sv}", "label", g_variant_new_string (_("Allow"))); + g_variant_builder_add (&button, "{sv}", "action", g_variant_new_string ("allow")); + g_variant_builder_add (&button, "{sv}", "target", g_variant_new_string (arg_app_id)); + + g_variant_builder_add (&bbuilder, "@a{sv}", g_variant_builder_end (&button)); + + g_variant_builder_init (&button, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&button, "{sv}", "label", g_variant_new_string (_("Forbid"))); + g_variant_builder_add (&button, "{sv}", "action", g_variant_new_string ("forbid")); + g_variant_builder_add (&button, "{sv}", "target", g_variant_new_string (arg_app_id)); + + g_variant_builder_add (&bbuilder, "@a{sv}", g_variant_builder_end (&button)); + + g_variant_builder_init (&button, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&button, "{sv}", "label", g_variant_new_string (_("Ignore"))); + g_variant_builder_add (&button, "{sv}", "action", g_variant_new_string ("ignore")); + g_variant_builder_add (&button, "{sv}", "target", g_variant_new_string (arg_app_id)); + + g_variant_builder_add (&bbuilder, "@a{sv}", g_variant_builder_end (&button)); + + g_variant_builder_add (&builder, "{sv}", "buttons", g_variant_builder_end (&bbuilder)); + + handle = g_new0 (BackgroundHandle, 1); + handle->impl = object; + handle->invocation = invocation; + handle->request = g_object_ref (request); + handle->id = g_strdup_printf ("notify_background_%d", count++); + + g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); + + connection = g_dbus_method_invocation_get_connection (invocation); + + fdo_add_notification (connection, "", handle->id, g_variant_builder_end (&builder), activate_action, handle); + + request_export (request, connection); + + return TRUE; +} + +static gboolean +needs_quoting (const char *arg) +{ + while (*arg != 0) + { + char c = *arg; + if (!g_ascii_isalnum (c) && + !(c == '-' || c == '/' || c == '~' || + c == ':' || c == '.' || c == '_' || + c == '=' || c == '@')) + return TRUE; + arg++; + } + return FALSE; +} + +char * +flatpak_quote_argv (const char *argv[], + gssize len) +{ + GString *res = g_string_new (""); + int i; + + if (len == -1) + len = g_strv_length ((char **) argv); + + for (i = 0; i < len; i++) + { + if (i != 0) + g_string_append_c (res, ' '); + + if (needs_quoting (argv[i])) + { + g_autofree char *quoted = g_shell_quote (argv[i]); + g_string_append (res, quoted); + } + else + g_string_append (res, argv[i]); + } + + return g_string_free (res, FALSE); +} + +typedef enum { + AUTOSTART_FLAGS_NONE = 0, + AUTOSTART_FLAGS_ACTIVATABLE = 1 << 0, +} AutostartFlags; + +static gboolean +handle_enable_autostart (XdpImplBackground *object, + GDBusMethodInvocation *invocation, + const char *arg_app_id, + gboolean arg_enable, + const char * const *arg_commandline, + guint arg_flags) +{ + gboolean result = FALSE; + g_autofree char *dir = NULL; + g_autofree char *file = NULL; + g_autofree char *path = NULL; + g_autoptr(GError) error = NULL; + g_autofree char *commandline = NULL; + g_autoptr(GKeyFile) keyfile = NULL; + + g_debug ("background: handle EnableAutostart"); + + file = g_strconcat (arg_app_id, ".desktop", NULL); + dir = g_build_filename (g_get_user_config_dir (), "autostart", NULL); + path = g_build_filename (dir, file, NULL); + + if (!arg_enable) + { + unlink (path); + g_debug ("Removed %s", path); + goto out; + } + + if (g_mkdir_with_parents (dir, 0755) != 0) + { + g_warning ("Failed to create dirs %s", dir); + goto out; + } + + commandline = flatpak_quote_argv ((const char **)arg_commandline, -1); + + keyfile = g_key_file_new (); + + g_key_file_set_string (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TYPE, + "Application"); + g_key_file_set_string (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, + arg_app_id); // FIXME + g_key_file_set_string (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, + commandline); + if (arg_flags & AUTOSTART_FLAGS_ACTIVATABLE) + g_key_file_set_boolean (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE, + TRUE); + g_key_file_set_string (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + "X-Flatpak", + arg_app_id); + + if (!g_key_file_save_to_file (keyfile, path, &error)) + { + g_warning ("Failed to save %s: %s", path, error->message); + goto out; + } + + g_debug ("Wrote autostart file %s", path); + + result = TRUE; + +out: + xdp_impl_background_complete_enable_autostart (object, invocation, result); + + return TRUE; +} + +gboolean +background_init (GDBusConnection *bus, + GError **error) +{ + GDBusInterfaceSkeleton *helper; + + shell = org_gnome_shell_introspect_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "org.gnome.Shell", + "/org/gnome/Shell/Introspect", + NULL, + NULL); + + helper = G_DBUS_INTERFACE_SKELETON (xdp_impl_background_skeleton_new ()); + + g_signal_connect (helper, "handle-get-app-state", G_CALLBACK (handle_get_app_state), NULL); + g_signal_connect (helper, "handle-notify-background", G_CALLBACK (handle_notify_background), NULL); + g_signal_connect (helper, "handle-enable-autostart", G_CALLBACK (handle_enable_autostart), NULL); + + if (!g_dbus_interface_skeleton_export (helper, + bus, + DESKTOP_PORTAL_OBJECT_PATH, + error)) + return FALSE; + + g_debug ("providing %s", g_dbus_interface_skeleton_get_info (helper)->name); + + return TRUE; +} diff --git a/src/background.h b/src/background.h new file mode 100644 index 0000000..f24f603 --- /dev/null +++ b/src/background.h @@ -0,0 +1,25 @@ +/* + * Copyright © 2019 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Matthias Clasen + */ + +#pragma once + +#include + +gboolean background_init (GDBusConnection *bus, GError **error); diff --git a/src/fdonotification.c b/src/fdonotification.c new file mode 100644 index 0000000..08ea9d3 --- /dev/null +++ b/src/fdonotification.c @@ -0,0 +1,433 @@ +#define _GNU_SOURCE 1 + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "xdg-desktop-portal-dbus.h" +#include "shell-dbus.h" + +#include "notification.h" +#include "fdonotification.h" +#include "request.h" +#include "utils.h" + +/* org.freedesktop.Notifications support. + * This code is adapted from the GFdoNotificationBackend in GIO. + */ + +static guint fdo_notify_subscription; +static GSList *fdo_notifications; + +typedef struct +{ + char *app_id; + char *id; + guint32 notify_id; + char *default_action; + GVariant *default_action_target; + ActivateAction activate_action; + gpointer data; +} FdoNotification; + +static void +fdo_notification_free (gpointer data) +{ + FdoNotification *n = data; + + g_free (n->app_id); + g_free (n->id); + g_free (n->default_action); + if (n->default_action_target) + g_variant_unref (n->default_action_target); + + g_slice_free (FdoNotification, n); +} + +FdoNotification * +fdo_find_notification (const char *app_id, + const char *id) +{ + GSList *l; + + for (l = fdo_notifications; l != NULL; l = l->next) + { + FdoNotification *n = l->data; + if (g_str_equal (n->app_id, app_id) && + g_str_equal (n->id, id)) + return n; + } + + return NULL; +} + +FdoNotification * +fdo_find_notification_by_notify_id (guint32 id) +{ + GSList *l; + + for (l = fdo_notifications; l != NULL; l = l->next) + { + FdoNotification *n = l->data; + if (n->notify_id == id) + return n; + } + + return NULL; +} + +static void +notify_signal (GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + guint32 id = 0; + const char *action = NULL; + FdoNotification *n; + + if (g_str_equal (signal_name, "NotificationClosed") && + g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) + { + g_variant_get (parameters, "(uu)", &id, NULL); + } + else if (g_str_equal (signal_name, "ActionInvoked") && + g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) + { + g_variant_get (parameters, "(u&s)", &id, &action); + } + else + return; + + n = fdo_find_notification_by_notify_id (id); + if (n == NULL) + return; + + if (action) + { + if (g_str_equal (action, "default")) + { + n->activate_action (connection, + n->app_id, + n->id, + n->default_action, + n->default_action_target, + n->data); + } + else + { + gchar *name; + GVariant *target; + + if (g_action_parse_detailed_name (action, &name, &target, NULL)) + { + n->activate_action (connection, + n->app_id, + n->id, + name, + target, + n->data); + g_free (name); + if (target) + g_variant_unref (target); + } + else + g_debug ("Could not parse action name %s", action); + } + } + + fdo_notifications = g_slist_remove (fdo_notifications, n); + fdo_notification_free (n); +} + +static guchar +urgency_from_priority (const char *priority) +{ + if (strcmp (priority, "low") == 0) + return 0; + else if (strcmp (priority, "normal") == 0) + return 1; + else + return 2; +} + +static void +notification_sent (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + FdoNotification *n = user_data; + GVariant *val; + GError *error = NULL; + static gboolean warning_printed = FALSE; + + val = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), result, &error); + if (val) + { + g_variant_get (val, "(u)", &n->notify_id); + g_variant_unref (val); + } + else + { + if (!warning_printed) + { + g_warning ("Unable to send notifications through org.freedesktop.Notifications: %s", + error->message); + warning_printed = TRUE; + } + + fdo_notifications = g_slist_remove (fdo_notifications, n); + fdo_notification_free (n); + + g_error_free (error); + } +} + +static void +call_notify (GDBusConnection *connection, + FdoNotification *fdo, + GVariant *notification) +{ + GVariantBuilder action_builder; + guint i; + GVariantBuilder hints_builder; + GVariant *icon; + const char *body; + const char *title; + g_autofree char *icon_name = NULL; + guchar urgency; + const char *dummy; + g_autoptr(GVariant) buttons = NULL; + const char *priority; + + if (fdo_notify_subscription == 0) + { + fdo_notify_subscription = + g_dbus_connection_signal_subscribe (connection, + "org.freedesktop.Notifications", + "org.freedesktop.Notifications", NULL, + "/org/freedesktop/Notifications", NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + notify_signal, NULL, NULL); + } + + g_variant_builder_init (&action_builder, G_VARIANT_TYPE_STRING_ARRAY); + if (g_variant_lookup (notification, "default-action", "&s", &dummy)) + { + g_variant_builder_add (&action_builder, "s", "default"); + g_variant_builder_add (&action_builder, "s", ""); + } + + buttons = g_variant_lookup_value (notification, "buttons", G_VARIANT_TYPE("aa{sv}")); + if (buttons) + for (i = 0; i < g_variant_n_children (buttons); i++) + { + g_autoptr(GVariant) button = NULL; + const char *label; + const char *action; + g_autoptr(GVariant) target = NULL; + g_autofree char *detailed_name = NULL; + + button = g_variant_get_child_value (buttons, i); + g_variant_lookup (button, "label", "&s", &label); + g_variant_lookup (button, "action", "&s", &action); + target = g_variant_lookup_value (button, "target", G_VARIANT_TYPE_VARIANT); + detailed_name = g_action_print_detailed_name (action, target); + + /* Actions named 'default' collide with libnotify's naming of the + * default action. Rewriting them to something unique is enough, + * because those actions can never be activated (they aren't + * prefixed with 'app.'). + */ + if (g_str_equal (detailed_name, "default")) + { + g_free (detailed_name); + detailed_name = g_dbus_generate_guid (); + } + + g_variant_builder_add_value (&action_builder, g_variant_new_string (detailed_name)); + g_variant_builder_add_value (&action_builder, g_variant_new_string (label)); + } + + g_variant_builder_init (&hints_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&hints_builder, "{sv}", "desktop-entry", g_variant_new_string (fdo->app_id)); + if (g_variant_lookup (notification, "priority", "&s", &priority)) + urgency = urgency_from_priority (priority); + else + urgency = 1; + g_variant_builder_add (&hints_builder, "{sv}", "urgency", g_variant_new_byte (urgency)); + + icon = g_variant_lookup_value (notification, "icon", NULL); + if (icon != NULL) + { + g_autoptr(GIcon) gicon = g_icon_deserialize (icon); + if (G_IS_FILE_ICON (gicon)) + { + GFile *file; + + file = g_file_icon_get_file (G_FILE_ICON (gicon)); + icon_name = g_file_get_path (file); + } + else if (G_IS_THEMED_ICON (gicon)) + { + const gchar* const* icon_names = g_themed_icon_get_names (G_THEMED_ICON (gicon)); + icon_name = g_strdup (icon_names[0]); + } + else if (G_IS_BYTES_ICON (gicon)) + { + g_autoptr(GInputStream) istream = NULL; + g_autoptr(GdkPixbuf) pixbuf = NULL; + int width, height, rowstride, n_channels, bits_per_sample; + GVariant *image; + gsize image_len; + + istream = g_loadable_icon_load (G_LOADABLE_ICON (gicon), + -1 /* unused */, + NULL /* type */, + NULL, + NULL); + pixbuf = gdk_pixbuf_new_from_stream (istream, NULL, NULL); + g_input_stream_close (istream, NULL, NULL); + + g_object_get (pixbuf, + "width", &width, + "height", &height, + "rowstride", &rowstride, + "n-channels", &n_channels, + "bits-per-sample", &bits_per_sample, + NULL); + + image_len = (height - 1) * rowstride + width * + ((n_channels * bits_per_sample + 7) / 8); + + image = g_variant_new ("(iiibii@ay)", + width, + height, + rowstride, + gdk_pixbuf_get_has_alpha (pixbuf), + bits_per_sample, + n_channels, + g_variant_new_from_data (G_VARIANT_TYPE ("ay"), + gdk_pixbuf_get_pixels (pixbuf), + image_len, + TRUE, + (GDestroyNotify) g_object_unref, + g_object_ref (pixbuf))); + g_variant_builder_add (&hints_builder, "{sv}", "image-data", image); + } + } + + if (icon_name == NULL) + icon_name = g_strdup (""); + + if (!g_variant_lookup (notification, "body", "&s", &body)) + body = ""; + if (!g_variant_lookup (notification, "title", "&s", &title)) + title= ""; + + g_dbus_connection_call (connection, + "org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + "Notify", + g_variant_new ("(susssasa{sv}i)", + "", /* app name */ + fdo->notify_id, + icon_name, + title, + body, + &action_builder, + &hints_builder, + -1), /* expire_timeout */ + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + notification_sent, fdo); +} + +static void +call_close (GDBusConnection *connection, + guint32 id) +{ + g_dbus_connection_call (connection, + "org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + "CloseNotification", + g_variant_new ("(u)", id), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); +} + +gboolean +fdo_remove_notification (GDBusConnection *connection, + const char *app_id, + const char *id) +{ + FdoNotification *n; + + n = fdo_find_notification (app_id, id); + if (n) + { + if (n->notify_id > 0) + call_close (connection, n->notify_id); + + fdo_notifications = g_slist_remove (fdo_notifications, n); + fdo_notification_free (n); + + return TRUE; + } + + return FALSE; +} + +void +fdo_add_notification (GDBusConnection *connection, + const char *app_id, + const char *id, + GVariant *notification, + ActivateAction activate_action, + gpointer data) +{ + FdoNotification *n; + + n = fdo_find_notification (app_id, id); + if (n == NULL) + { + n = g_slice_new0 (FdoNotification); + n->app_id = g_strdup (app_id); + n->id = g_strdup (id); + n->notify_id = 0; + n->activate_action = activate_action; + n->data = data; + } + else + { + /* Only clear default action. All other fields are still valid */ + g_clear_pointer (&n->default_action, g_free); + g_clear_pointer (&n->default_action_target, g_variant_unref); + } + + g_variant_lookup (notification, "default-action", "s", &n->default_action); + n->default_action_target = g_variant_lookup_value (notification, "default-action-target", G_VARIANT_TYPE_VARIANT); + + fdo_notifications = g_slist_prepend (fdo_notifications, n); + + call_notify (connection, n, notification); +} + diff --git a/src/fdonotification.h b/src/fdonotification.h new file mode 100644 index 0000000..5bede28 --- /dev/null +++ b/src/fdonotification.h @@ -0,0 +1,41 @@ +/* + * Copyright © 2019 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Matthias Clasen + */ + +#pragma once + +#include + +typedef void (*ActivateAction) (GDBusConnection *connection, + const char *app_id, + const char *id, + const char *name, + GVariant *parameter, + gpointer data); + +void fdo_add_notification (GDBusConnection *connection, + const char *app_id, + const char *id, + GVariant *notification, + ActivateAction activate, + gpointer data); +gboolean fdo_remove_notification (GDBusConnection *connection, + const char *app_id, + const char *id); + diff --git a/src/notification.c b/src/notification.c index a5e11f7..1da8918 100644 --- a/src/notification.c +++ b/src/notification.c @@ -19,6 +19,7 @@ #include "shell-dbus.h" #include "notification.h" +#include "fdonotification.h" #include "request.h" #include "utils.h" @@ -47,8 +48,6 @@ handle_add_notification_gtk (XdpImplNotification *object, const char *arg_id, GVariant *arg_notification) { - g_debug ("handle add-notification from %s using the gtk implementation", arg_app_id); - if (gtk_notifications) org_gtk_notifications_call_add_notification (gtk_notifications, arg_app_id, @@ -58,6 +57,8 @@ handle_add_notification_gtk (XdpImplNotification *object, notification_added, NULL); + g_debug ("handle add-notification from %s using the gtk implementation", arg_app_id); + xdp_impl_notification_complete_add_notification (object, invocation); } @@ -67,8 +68,6 @@ handle_remove_notification_gtk (XdpImplNotification *object, const char *arg_app_id, const char *arg_id) { - g_debug ("handle remove-notification from %s using the gtk implementation", arg_app_id); - if (gtk_notifications) org_gtk_notifications_call_remove_notification (gtk_notifications, arg_app_id, @@ -77,69 +76,9 @@ handle_remove_notification_gtk (XdpImplNotification *object, NULL, NULL); - xdp_impl_notification_complete_remove_notification (object, invocation); -} - -/* org.freedesktop.Notifications support. - * This code is adapted from the GFdoNotificationBackend in GIO. - */ - -static guint fdo_notify_subscription; -static GSList *fdo_notifications; - -typedef struct -{ - char *app_id; - char *id; - guint32 notify_id; - char *default_action; - GVariant *default_action_target; -} FdoNotification; - -static void -fdo_notification_free (gpointer data) -{ - FdoNotification *n = data; - - g_free (n->app_id); - g_free (n->id); - g_free (n->default_action); - if (n->default_action_target) - g_variant_unref (n->default_action_target); - - g_slice_free (FdoNotification, n); -} - -static FdoNotification * -fdo_find_notification (const char *app_id, - const char *id) -{ - GSList *l; - - for (l = fdo_notifications; l != NULL; l = l->next) - { - FdoNotification *n = l->data; - if (g_str_equal (n->app_id, app_id) && - g_str_equal (n->id, id)) - return n; - } - - return NULL; -} - -static FdoNotification * -fdo_find_notification_by_notify_id (guint32 id) -{ - GSList *l; - - for (l = fdo_notifications; l != NULL; l = l->next) - { - FdoNotification *n = l->data; - if (n->notify_id == id) - return n; - } + g_debug ("handle remove-notification from %s using the gtk implementation", arg_app_id); - return NULL; + xdp_impl_notification_complete_remove_notification (object, invocation); } static char * @@ -165,7 +104,8 @@ activate_action (GDBusConnection *connection, const char *app_id, const char *id, const char *name, - GVariant *parameter) + GVariant *parameter, + gpointer data) { g_autofree char *object_path = NULL; GVariantBuilder pdata; @@ -220,266 +160,6 @@ activate_action (GDBusConnection *connection, } } -static void -notify_signal (GDBusConnection *connection, - const char *sender_name, - const char *object_path, - const char *interface_name, - const char *signal_name, - GVariant *parameters, - gpointer user_data) -{ - guint32 id = 0; - const char *action = NULL; - FdoNotification *n; - - if (g_str_equal (signal_name, "NotificationClosed") && - g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) - { - g_variant_get (parameters, "(uu)", &id, NULL); - } - else if (g_str_equal (signal_name, "ActionInvoked") && - g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) - { - g_variant_get (parameters, "(u&s)", &id, &action); - } - else - return; - - n = fdo_find_notification_by_notify_id (id); - if (n == NULL) - return; - - if (action) - { - if (g_str_equal (action, "default")) - { - activate_action (connection, - n->app_id, - n->id, - n->default_action, - n->default_action_target); - } - else - { - gchar *name; - GVariant *target; - - if (g_action_parse_detailed_name (action, &name, &target, NULL)) - { - activate_action (connection, - n->app_id, - n->id, - name, - target); - g_free (name); - if (target) - g_variant_unref (target); - } - } - } - - fdo_notifications = g_slist_remove (fdo_notifications, n); - fdo_notification_free (n); -} - -static guchar -urgency_from_priority (const char *priority) -{ - if (strcmp (priority, "low") == 0) - return 0; - else if (strcmp (priority, "normal") == 0) - return 1; - else - return 2; -} - -static void -call_notify (GDBusConnection *connection, - const char *app_id, - guint32 replace_id, - GVariant *notification, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GVariantBuilder action_builder; - guint i; - GVariantBuilder hints_builder; - GVariant *icon; - const char *body; - const char *title; - g_autofree char *icon_name = NULL; - guchar urgency; - const char *dummy; - g_autoptr(GVariant) buttons = NULL; - const char *priority; - - g_variant_builder_init (&action_builder, G_VARIANT_TYPE_STRING_ARRAY); - if (g_variant_lookup (notification, "default-action", "&s", &dummy)) - { - g_variant_builder_add (&action_builder, "s", "default"); - g_variant_builder_add (&action_builder, "s", ""); - } - - buttons = g_variant_lookup_value (notification, "buttons", G_VARIANT_TYPE("aa{sv}")); - if (buttons) - for (i = 0; i < g_variant_n_children (buttons); i++) - { - g_autoptr(GVariant) button = NULL; - const char *label; - const char *action; - g_autoptr(GVariant) target = NULL; - g_autofree char *detailed_name = NULL; - - button = g_variant_get_child_value (buttons, i); - g_variant_lookup (button, "label", "&s", &label); - g_variant_lookup (button, "action", "&s", &action); - target = g_variant_lookup_value (button, "target", G_VARIANT_TYPE_VARIANT); - detailed_name = g_action_print_detailed_name (action, target); - - /* Actions named 'default' collide with libnotify's naming of the - * default action. Rewriting them to something unique is enough, - * because those actions can never be activated (they aren't - * prefixed with 'app.'). - */ - if (g_str_equal (detailed_name, "default")) - { - g_free (detailed_name); - detailed_name = g_dbus_generate_guid (); - } - - g_variant_builder_add_value (&action_builder, g_variant_new_string (detailed_name)); - g_variant_builder_add_value (&action_builder, g_variant_new_string (label)); - } - - g_variant_builder_init (&hints_builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&hints_builder, "{sv}", "desktop-entry", g_variant_new_string (app_id)); - if (g_variant_lookup (notification, "priority", "&s", &priority)) - urgency = urgency_from_priority (priority); - else - urgency = 1; - g_variant_builder_add (&hints_builder, "{sv}", "urgency", g_variant_new_byte (urgency)); - - icon = g_variant_lookup_value (notification, "icon", NULL); - if (icon != NULL) - { - g_autoptr(GIcon) gicon = g_icon_deserialize (icon); - if (G_IS_FILE_ICON (gicon)) - { - GFile *file; - - file = g_file_icon_get_file (G_FILE_ICON (gicon)); - icon_name = g_file_get_path (file); - } - else if (G_IS_THEMED_ICON (gicon)) - { - const gchar* const* icon_names = g_themed_icon_get_names (G_THEMED_ICON (gicon)); - icon_name = g_strdup (icon_names[0]); - } - else if (G_IS_BYTES_ICON (gicon)) - { - g_autoptr(GInputStream) istream = NULL; - g_autoptr(GdkPixbuf) pixbuf = NULL; - int width, height, rowstride, n_channels, bits_per_sample; - GVariant *image; - gsize image_len; - - istream = g_loadable_icon_load (G_LOADABLE_ICON (gicon), - -1 /* unused */, - NULL /* type */, - NULL, - NULL); - pixbuf = gdk_pixbuf_new_from_stream (istream, NULL, NULL); - g_input_stream_close (istream, NULL, NULL); - - g_object_get (pixbuf, - "width", &width, - "height", &height, - "rowstride", &rowstride, - "n-channels", &n_channels, - "bits-per-sample", &bits_per_sample, - NULL); - - image_len = (height - 1) * rowstride + width * - ((n_channels * bits_per_sample + 7) / 8); - - image = g_variant_new ("(iiibii@ay)", - width, - height, - rowstride, - gdk_pixbuf_get_has_alpha (pixbuf), - bits_per_sample, - n_channels, - g_variant_new_from_data (G_VARIANT_TYPE ("ay"), - gdk_pixbuf_get_pixels (pixbuf), - image_len, - TRUE, - (GDestroyNotify) g_object_unref, - g_object_ref (pixbuf))); - g_variant_builder_add (&hints_builder, "{sv}", "image-data", image); - } - } - - if (icon_name == NULL) - icon_name = g_strdup (""); - - if (!g_variant_lookup (notification, "body", "&s", &body)) - body = ""; - if (!g_variant_lookup (notification, "title", "&s", &title)) - title= ""; - - g_dbus_connection_call (connection, - "org.freedesktop.Notifications", - "/org/freedesktop/Notifications", - "org.freedesktop.Notifications", - "Notify", - g_variant_new ("(susssasa{sv}i)", - "", /* app name */ - replace_id, - icon_name, - title, - body, - &action_builder, - &hints_builder, - -1), /* expire_timeout */ - G_VARIANT_TYPE ("(u)"), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, - callback, user_data); -} - -static void -notification_sent (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - FdoNotification *n = user_data; - GVariant *val; - GError *error = NULL; - static gboolean warning_printed = FALSE; - - val = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), result, &error); - if (val) - { - g_variant_get (val, "(u)", &n->notify_id); - g_variant_unref (val); - } - else - { - if (!warning_printed) - { - g_warning ("Unable to send notifications through org.freedesktop.Notifications: %s", - error->message); - warning_printed = TRUE; - } - - fdo_notifications = g_slist_remove (fdo_notifications, n); - fdo_notification_free (n); - - g_error_free (error); - } -} - static void handle_add_notification_fdo (XdpImplNotification *object, GDBusMethodInvocation *invocation, @@ -487,80 +167,33 @@ handle_add_notification_fdo (XdpImplNotification *object, const gchar *arg_id, GVariant *arg_notification) { - FdoNotification *n; GDBusConnection *connection; g_debug ("handle add-notification from %s using the freedesktop implementation", arg_app_id); connection = g_dbus_method_invocation_get_connection (invocation); - if (fdo_notify_subscription == 0) - { - fdo_notify_subscription = - g_dbus_connection_signal_subscribe (connection, - "org.freedesktop.Notifications", - "org.freedesktop.Notifications", NULL, - "/org/freedesktop/Notifications", NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - notify_signal, NULL, NULL); - } - - n = fdo_find_notification (arg_app_id, arg_id); - if (n == NULL) - { - n = g_slice_new0 (FdoNotification); - n->app_id = g_strdup (arg_app_id); - n->id = g_strdup (arg_id); - n->notify_id = 0; - - fdo_notifications = g_slist_prepend (fdo_notifications, n); - } - else - { - /* Only clear default action. All other fields are still valid */ - g_clear_pointer (&n->default_action, g_free); - g_clear_pointer (&n->default_action_target, g_variant_unref); - } - - g_variant_lookup (arg_notification, "default-action", "s", &n->default_action); - n->default_action_target = g_variant_lookup_value (arg_notification, "default-action-target", G_VARIANT_TYPE_VARIANT); + fdo_add_notification (connection, arg_app_id, arg_id, arg_notification, activate_action, NULL); - call_notify (connection, - arg_app_id, - n->notify_id, - arg_notification, - notification_sent, n); + xdp_impl_notification_complete_add_notification (object, invocation); } -static void +static gboolean handle_remove_notification_fdo (XdpImplNotification *object, GDBusMethodInvocation *invocation, const gchar *arg_app_id, const gchar *arg_id) { - FdoNotification *n; - - g_debug ("handle remove-notification from %s using the freedesktop implementation", arg_app_id); + GDBusConnection *connection; - n = fdo_find_notification (arg_app_id, arg_id); - if (n) + connection = g_dbus_method_invocation_get_connection (invocation); + if (fdo_remove_notification (connection, arg_app_id, arg_id)) { - if (n->notify_id > 0) - { - g_dbus_connection_call (g_dbus_method_invocation_get_connection (invocation), - "org.freedesktop.Notifications", - "/org/freedesktop/Notifications", - "org.freedesktop.Notifications", - "CloseNotification", - g_variant_new ("(u)", n->id), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, NULL, NULL); - } - - fdo_notifications = g_slist_remove (fdo_notifications, n); - fdo_notification_free (n); + g_debug ("handle remove-notification from %s using the freedesktop implementation", arg_app_id); + xdp_impl_notification_complete_remove_notification (object, invocation); + return TRUE; } + return FALSE; } static gboolean @@ -602,6 +235,7 @@ handle_add_notification (XdpImplNotification *object, handle_add_notification_fdo (object, invocation, arg_app_id, arg_id, arg_notification); else handle_add_notification_gtk (object, invocation, arg_app_id, arg_id, arg_notification); + return TRUE; } @@ -611,12 +245,7 @@ handle_remove_notification (XdpImplNotification *object, const gchar *arg_app_id, const gchar *arg_id) { - FdoNotification *n; - - n = fdo_find_notification (arg_app_id, arg_id); - if (n) - handle_remove_notification_fdo (object, invocation, arg_app_id, arg_id); - else + if (!handle_remove_notification_fdo (object, invocation, arg_app_id, arg_id)) handle_remove_notification_gtk (object, invocation, arg_app_id, arg_id); return TRUE; } diff --git a/src/xdg-desktop-portal-gtk.c b/src/xdg-desktop-portal-gtk.c index da839ef..9d06684 100644 --- a/src/xdg-desktop-portal-gtk.c +++ b/src/xdg-desktop-portal-gtk.c @@ -53,6 +53,7 @@ #include "screencast.h" #include "remotedesktop.h" #include "lockdown.h" +#include "background.h" static GMainLoop *loop = NULL; @@ -174,6 +175,12 @@ on_bus_acquired (GDBusConnection *connection, g_warning ("error: %s\n", error->message); g_clear_error (&error); } + + if (!background_init (connection, &error)) + { + g_warning ("error: %s\n", error->message); + g_clear_error (&error); + } } static void From 8d264763544c870f2d515923541efa8c1cbdaaeb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 16 May 2019 11:23:55 -0400 Subject: [PATCH 19/24] background: Use sandboxed-app-id The gnome-shell introspection api has been amended to include the sandboxed-app-id field so we don't have to guess the app id from the desktop file name. --- src/background.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/background.c b/src/background.c index c4c7a1f..ffb23d0 100644 --- a/src/background.c +++ b/src/background.c @@ -71,17 +71,22 @@ handle_get_app_state (XdpImplBackground *object, while (g_variant_iter_loop (iter, "{t@a{sv}}", NULL, &dict)) { const char *app_id = NULL; + const char *sandboxed_app_id = NULL; char *app; gboolean hidden = FALSE; gboolean focus = FALSE; AppState state = BACKGROUND; g_variant_lookup (dict, "app-id", "&s", &app_id); + g_variant_lookup (dict, "sandboxed-app-id", "&s", &sandboxed_app_id); g_variant_lookup (dict, "is-hidden", "b", &hidden); g_variant_lookup (dict, "has-focus", "b", &focus); /* See https://gitlab.gnome.org/GNOME/gnome-shell/issues/1289 */ - app = get_actual_app_id (app_id); + if (sandboxed_app_id) + app = g_strdup (sandboxed_app_id); + else + app = get_actual_app_id (app_id); if (app == NULL) continue; From 164cf93b1c42cc34a4e28eb7d758a6f749468e1c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 16 May 2019 11:51:30 -0400 Subject: [PATCH 20/24] Add the shell introspection interface Forgotten file -> broken build :( --- data/Makefile.am.inc | 1 + data/org.gnome.Shell.Introspect.xml | 61 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 data/org.gnome.Shell.Introspect.xml diff --git a/data/Makefile.am.inc b/data/Makefile.am.inc index f07fbd2..21b134e 100644 --- a/data/Makefile.am.inc +++ b/data/Makefile.am.inc @@ -40,6 +40,7 @@ EXTRA_DIST += \ data/org.gnome.Mutter.ScreenCast.xml \ data/org.gnome.Mutter.RemoteDesktop.xml \ data/org.gnome.SessionManager.xml \ + data/org.gnome.Shell.Introspect.xml \ data/org.gnome.Shell.Screenshot.xml \ data/org.gnome.ScreenSaver.xml \ data/org.freedesktop.ScreenSaver.xml \ diff --git a/data/org.gnome.Shell.Introspect.xml b/data/org.gnome.Shell.Introspect.xml new file mode 100644 index 0000000..9508681 --- /dev/null +++ b/data/org.gnome.Shell.Introspect.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + From f0ad8ac1f3c7ae2992a7a128957aac51ef11fa1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Thu, 16 May 2019 20:37:10 +0200 Subject: [PATCH 21/24] Update POTFILES.in (#200) --- po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 25f4c78..6759f7c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -5,6 +5,7 @@ src/accountdialog.c src/accountdialog.ui src/appchooserdialog.c src/appchooserdialog.ui +src/background.c src/filechooser.c src/remotedesktopdialog.c src/remotedesktopdialog.ui From 25488d8e8337402589021538ca5d5a23eeb58c3f Mon Sep 17 00:00:00 2001 From: scootergrisen Date: Tue, 21 May 2019 04:14:27 +0200 Subject: [PATCH 22/24] Update Danish translation (#202) --- po/da.po | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/po/da.po b/po/da.po index 8df807c..39891cc 100644 --- a/po/da.po +++ b/po/da.po @@ -5,10 +5,10 @@ msgid "" msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk\n" -"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" -"issues\n" -"POT-Creation-Date: 2019-02-11 03:27+0000\n" -"PO-Revision-Date: 2019-02-11 00:00+0200\n" +"Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-" +"gtk/issues\n" +"POT-Creation-Date: 2019-05-20 15:30+0000\n" +"PO-Revision-Date: 2019-05-21 00:00+0200\n" "Last-Translator: scootergrisen\n" "Language-Team: Danish\n" "Language: da\n" @@ -124,6 +124,27 @@ msgstr "Der blev ikke fundet nogen programmer" msgid "Find Compatible Applications in Software" msgstr "Find kompatible programmer i Software" +#: src/background.c:255 +msgid "Background activity" +msgstr "Baggrundsaktivitet" + +#: src/background.c:257 +#, c-format +msgid "%s is running in the background." +msgstr "%s kører i baggrunden." + +#: src/background.c:262 +msgid "Allow" +msgstr "Tillad" + +#: src/background.c:269 +msgid "Forbid" +msgstr "Forbyd" + +#: src/background.c:276 +msgid "Ignore" +msgstr "Ignorer" + #: src/filechooser.c:392 msgid "_Save" msgstr "_Gem" @@ -134,26 +155,26 @@ msgstr "_Åbn" #: src/filechooser.c:552 msgid "Open files read-only" -msgstr "Åbn filer som skrivebeskyttet" +msgstr "Åbn filer som skrivebeskyttede" -#: src/remotedesktopdialog.c:190 +#: src/remotedesktopdialog.c:188 msgid "Pointer" msgstr "Markør" -#: src/remotedesktopdialog.c:193 +#: src/remotedesktopdialog.c:191 msgid "Keyboard" msgstr "Tastatur" -#: src/remotedesktopdialog.c:196 +#: src/remotedesktopdialog.c:194 msgid "Touch screen" msgstr "Berøringsfølsom skærm" -#: src/remotedesktopdialog.c:303 +#: src/remotedesktopdialog.c:307 #, c-format msgid "Select devices to share with %s" msgstr "Vælg enheder som skal deles med %s" -#: src/remotedesktopdialog.c:308 +#: src/remotedesktopdialog.c:312 msgid "Select devices to share with the requesting application" msgstr "Vælg enheder som skal deles med det anmodede program" @@ -189,7 +210,7 @@ msgstr "Skærmbillede" #: src/screenshotdialog.ui:30 msgid "_Options…" -msgstr "_Valgmuligheder…" +msgstr "_Valgmuligheder …" #: src/screenshotdialog.ui:55 msgid "Take _Screenshot" @@ -205,7 +226,7 @@ msgstr "Indfang _hele skærmen" #: src/screenshotdialog.ui:133 msgid "Grab the current _window" -msgstr "Indgang det nuværende _vindue" +msgstr "Indfang det nuværende _vindue" #: src/screenshotdialog.ui:144 msgid "Select _area to grab" @@ -225,8 +246,8 @@ msgstr "Effekter" #: src/screenshotdialog.ui:192 msgid "Include _pointer" -msgstr "Inkluder _markør" +msgstr "Medtag _markør" #: src/screenshotdialog.ui:201 msgid "Include the window _border" -msgstr "Inkluder vinduets _kant" +msgstr "Medtag vinduets _kant" From 8b656821ed6ffe71a9d770051785c4933a4efc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Tue, 28 May 2019 15:55:25 +0200 Subject: [PATCH 23/24] Update Polish translation (#203) --- po/pl.po | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/po/pl.po b/po/pl.po index 0514611..67a8052 100644 --- a/po/pl.po +++ b/po/pl.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: xdg-desktop-portal-gtk\n" "Report-Msgid-Bugs-To: https://github.com/flatpak/xdg-desktop-portal-gtk/" "issues\n" -"POT-Creation-Date: 2019-01-19 03:27+0000\n" -"PO-Revision-Date: 2019-01-20 12:24+0100\n" +"POT-Creation-Date: 2019-05-17 03:29+0000\n" +"PO-Revision-Date: 2019-05-27 18:14+0200\n" "Last-Translator: Piotr Drąg \n" "Language-Team: Polish \n" "Language: pl\n" @@ -70,7 +70,7 @@ msgstr "Udostępnić informacje o użytkowniku proszącemu o to programowi?" msgid "Share Details" msgstr "Udostępnianie informacji" -#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:395 +#: src/accountdialog.ui:14 src/appchooserdialog.ui:17 src/filechooser.c:397 #: src/remotedesktopdialog.ui:16 src/screencastdialog.ui:16 #: src/screenshotdialog.ui:14 msgid "_Cancel" @@ -127,36 +127,57 @@ msgstr "Nie odnaleziono programów" msgid "Find Compatible Applications in Software" msgstr "Znajdź zgodne programy w Menedżerze oprogramowania" -#: src/filechooser.c:390 +#: src/background.c:255 +msgid "Background activity" +msgstr "Działanie w tle" + +#: src/background.c:257 +#, c-format +msgid "%s is running in the background." +msgstr "Program „%s” działa w tle." + +#: src/background.c:262 +msgid "Allow" +msgstr "Zezwól" + +#: src/background.c:269 +msgid "Forbid" +msgstr "Zabroń" + +#: src/background.c:276 +msgid "Ignore" +msgstr "Zignoruj" + +#: src/filechooser.c:392 msgid "_Save" msgstr "_Zapisz" -#: src/filechooser.c:392 +#: src/filechooser.c:394 msgid "_Open" msgstr "_Otwórz" -#: src/filechooser.c:504 +#: src/filechooser.c:552 msgid "Open files read-only" msgstr "Otwarcie plików tylko do odczytu" -#: src/remotedesktopdialog.c:190 +#: src/remotedesktopdialog.c:188 msgid "Pointer" msgstr "Kursor" -#: src/remotedesktopdialog.c:193 +#: src/remotedesktopdialog.c:191 msgid "Keyboard" msgstr "Klawiatura" -#: src/remotedesktopdialog.c:196 +#: src/remotedesktopdialog.c:194 msgid "Touch screen" msgstr "Ekran dotykowy" -#: src/remotedesktopdialog.c:303 +#: src/remotedesktopdialog.c:307 #, c-format msgid "Select devices to share with %s" msgstr "Wybór urządzeń do udostępnienia programowi „%s”" -#: src/remotedesktopdialog.c:308 +#: src/remotedesktopdialog.c:312 msgid "Select devices to share with the requesting application" msgstr "Wybór urządzeń do udostępnienia proszącemu o to programowi" From 7bea12533934abdd603982a39065477e8944df02 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 28 May 2019 15:13:24 +0000 Subject: [PATCH 24/24] 1.4.0 --- NEWS | 9 +++++++++ configure.ac | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3e3adea..df20c5b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +Changes in 1.4.0 +================ + +* Translation updates +* inhibit: Implement session state tracking +* screencast: Allow selecting source types +* screencast: Support cursor modes +* Add a background & autostart portal + Changes in 1.2.0 ================ diff --git a/configure.ac b/configure.ac index 1ba48db..5c6fb6f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.63]) -AC_INIT([xdg-desktop-portal-gtk],[1.3.0]) +AC_INIT([xdg-desktop-portal-gtk],[1.4.0]) AC_PROG_CC AM_PROG_CC_C_O