Compare commits

..

123 Commits

Author SHA1 Message Date
Felipe Borges
967b4d3ce9 45.4 2024-04-19 11:56:18 +02:00
Matthijs Velsink
42b05525b4 display: Fix crash due to shortcut propagation phase
For a managed GtkShortcutController, changing its propagation phase
away from `GTK_PHASE_BUBBLE` currently results in a lingering reference
due to a bug in GTK (gtk#6246). This means the Escape key shortcut
remains active even after leaving the Display panel, resulting in a
crash when pressing Escape in any panel after leaving the Display panel.

This is now fixed in GTK (gtk!7115), but there seems to be no reason for
changing the propagation phase at all anyways. Since the callback
returns `GDK_EVENT_PROPAGATE` when it does not activate, the event
should still make it to other handlers.

So, to speed up the fix for gnome-control-center, we remove the
propagation phase changes althogether. There is also no need to let the
shortcut have global scope, managed is enough.

Closes #2768

(cherry picked from commit e7e9753aac)
(cherry picked from commit 9eb2576f89)
2024-04-19 11:32:18 +02:00
Lukáš Tyrychtr
bfa3a1ce80 universal-access: Add a few activatable widgets in the typing page
This also fixes missing a11y labels for the sliders.
Fixes #2998.

(cherry picked from commit c3483b3a68)
(cherry picked from commit 06472e320d)
2024-04-19 11:32:05 +02:00
Maximiliano Sandoval
b4609b661c privacy: Remove rows that had their perms reset
When a permission for an app is reset, e.g. via:

    flatpak permission-reset APP_ID

the Changed signal simply contains one fewer entry in its dictionary. If
we had a row for an app_id, and such app_id is not in the new
permissions we remove the row from the list box.

Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2993
(cherry picked from commit 7f93969583)
(cherry picked from commit 13f533f3c5)
2024-04-19 11:31:59 +02:00
Maximiliano Sandoval
7f350031c2 privacy: Do not update on all Changed signals
The permission store emits more changes and these cause extra rows to
appear.

Partially fixes:
https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2993

(cherry picked from commit 6cdb19c6d7)
(cherry picked from commit 797defb3bd)
2024-04-19 11:31:53 +02:00
Maximiliano Sandoval
4adec45df7 privacy: location: Unpack GVariant inside GVariant
(cherry picked from commit 485f957a62)
2024-04-19 11:31:47 +02:00
Maximiliano Sandoval
d00302f518 privacy: camera: Unpack GVariant inside GVariant
Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2982
(cherry picked from commit 55afa6df47)
(cherry picked from commit 01bca6902c)
2024-04-19 11:31:34 +02:00
Felipe Borges
60316c0fe8 privacy, help: Link to "Screen Lock" documentation
When in the "Screen Lock" page, hitting F1 or going for Help should
open help:gnome-help/privacy-screen-lock

(cherry picked from commit b46f21d424)
2024-04-19 11:31:01 +02:00
Felipe Borges
eabdb0d758 privacy, help: Fix broken link to "Location Services" docs
The subpage tag name AND the correspondent docs page name were wrong.

(cherry picked from commit f4a1f9e9c3)
2024-04-19 11:30:53 +02:00
Felipe Borges
2d3ac85730 privacy, help: Remove links to pages without correspondent docs
(cherry picked from commit 7a9f5a3056)
2024-04-19 11:30:43 +02:00
Felipe Borges
23c57ccda2 privacy, help: Default to opening "Privacy Settings" help page
When in the main page or in a subpage without docs, the Help link
should open the "Privacy Settings" page at help:gnome-help/privacy

(cherry picked from commit a4074198a3)
2024-04-19 11:30:37 +02:00
Felipe Borges
7cdfba94a5 common: Check for valid GDateTime object before comparing
Avoids the critical below at runtime
11:14:36.7796                   **[873815]:CRITICAL: cc_util_get_smart_date: assertion 'date != NULL' failed
11:14:36.7802                   **[873815]:CRITICAL: cc_util_get_smart_date: assertion 'date != NULL' failed

Which comes from the location panel passing a NULL date object.

\#0  _g_log_abort (breakpoint=1) at ../shell/cc-log.c:72
        debugger_present = 1
\#1  0x000000000045c3c4 in cc_log_write
    (log_level=10, log_domain=0x7ffff7d592eb "GLib", log_message=0x234c400 "g_date_time_difference: assertion 'begin != NULL' failed", fields=0x7fffffffd740, n_fields=4, user_data=0x0)
    at ../shell/cc-log.c:315
        log_str = 0x234b8d0
        stream = 0x7ffff5dbb4e0 <_IO_2_1_stderr_>
        can_color = 1
\#2  0x000000000045c4f5 in cc_log_handler (log_level=G_LOG_LEVEL_CRITICAL, fields=0x7fffffffd740, n_fields=4, user_data=0x0) at ../shell/cc-log.c:348
        log_domain = 0x7ffff7d592eb "GLib"
        log_message = 0x234c400 "g_date_time_difference: assertion 'begin != NULL' failed"
\#3  0x00007ffff7c9f534 in g_log_structured_array () at /lib64/libglib-2.0.so.0
\#4  0x00007ffff7ca4f57 in g_log_default_handler () at /lib64/libglib-2.0.so.0
\#5  0x00007ffff7c9be29 in g_logv () at /lib64/libglib-2.0.so.0
\#6  0x00007ffff7c9c193 in g_log () at /lib64/libglib-2.0.so.0
\#7  0x00007ffff7c787fa in g_date_time_difference () at /lib64/libglib-2.0.so.0
\#8  0x000000000059c186 in cc_util_get_smart_date (date=0x0) at ../panels/common/cc-util.c:124
        today = 0x2350130
        local = 0x2350100
        span = 10791504
\#9  0x00000000004f8a20 in add_location_app (self=0x1dee1c0, app_id=0x232fef0 "org.gnome.Calendar", enabled=1, last_used=459618461810) at ../panels/privacy/cc-location-page.c:209
        data = 0xffffda80
        app_info = 0x2341c50
        t = 0x0
        row = 0x2348280
        w = 0x234fe00
        icon = 0x2345310
        last_used_str = 0x0
        desktop_id = 0x7fffcc034c30 "DL\310\375\a"
\#10 0x00000000004f8db4 in update_perm_store (self=0x1dee1c0, permissions=0x7fffcc04e2c0, permissions_data=0x7fffcc04ee80) at ../panels/privacy/cc-location-page.c:282
        enabled = 1
        last_used = 459618461810
        iter = {x = {140736616260288, 2, 0, 6386038, 140736616096608, 36922576, 16, 3579507750, 140737488345904, 140737350561909, 33733184, 36922576, 140737488345936, 140737350702366, 36922576, 3278251457363369984}}
        key = 0x232fef0 "org.gnome.Calendar"
        value = 0x7fffcc04e090
\#11 0x00000000004f8f4e in on_perm_store_lookup_done (source_object=0x1e24040, res=0x202ba40, user_data=0x1dee1c0) at ../panels/privacy/cc-location-page.c:324
        error = 0x0
        ret = 0x7fffcc04eef0
        permissions = 0x7fffcc04e2c0
        permissions_data = 0x7fffcc04ee80
\#12 0x00007ffff7e9082c in g_task_return_now () at /lib64/libgio-2.0.so.0
\#13 0x00007ffff7e944c3 in g_task_return () at /lib64/libgio-2.0.so.0
\#14 0x00007ffff7efe88b in reply_cb () at /lib64/libgio-2.0.so.0
\#15 0x00007ffff7e9082c in g_task_return_now () at /lib64/libgio-2.0.so.0
\#16 0x00007ffff7e944c3 in g_task_return () at /lib64/libgio-2.0.so.0

(cherry picked from commit 544c146ea8)
2024-04-19 11:29:51 +02:00
Robert Ancell
f4c430e7e1 Remove myself from the maintainers list.
I'm no longer engaged enough to be a maintainer so it's best to make that clear.
Still happy to review and be involved if others need it!
This is a great project and if you want to be more involved in GNOME I'd recommend it.

(cherry picked from commit e6de817031)
2024-04-19 11:28:56 +02:00
Matthijs Velsink
ee87c36201 datetime: Avoid emitted signals for manual changes
When setting widget values manually, block the callbacks to prevent
trying to change system time inadvertently.

Backport of 535404bb for GNOME 45.

See #2943
2024-04-16 14:51:43 +00:00
Felipe Borges
769c790ff8 ci: Use a F39 container image for the stable gnome-45 branch 2024-04-16 16:40:40 +02:00
Felipe Borges
afa9438155 ci: Build the gtk4 version in F39 to match container image 2024-04-16 16:40:40 +02:00
Peter Hutterer
d64153160d CI: Remove systemtap-runtime to avoid podman failures
Fixes podman issue
  Error: Error reading blob sha256:4bb4a44c73af78e20e3d4c36bc1ce95b4b77a546f11a65babf752f869f1ca655:
  open /var/lib/containers/storage/vfs/dir/9b8cfd27e86ef18db67fbda7d61d72046f3f5d8ad312655713d4cd8b065c80cd/usr/bin/staprun: permission denied

Related to https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1247
2024-04-16 16:21:10 +02:00
Athmane MOKRAOUI
dd13023893 Update Kabyle translation 2024-04-13 15:12:26 +00:00
Daniel Rusek
cc00aa9a9a Update Czech translation 2024-03-30 10:04:20 +00:00
Ekaterine Papava
9814dae52a Update Georgian translation 2024-03-25 05:47:21 +00:00
Daniel Rusek
9605ac5785 Update Czech translation 2024-03-14 11:18:16 +00:00
Ekaterine Papava
7b10a54d58 Update Georgian translation 2024-03-13 14:49:48 +00:00
Christian Kirbach
c2958255e0 Update German translation 2024-02-27 22:49:53 +00:00
Felipe Borges
4e107fa212 45.3 2024-02-12 13:23:54 +01:00
Matthijs Velsink
bc52ef0e52 datetime: Fix invalid pointer type with cast
Fixes build with -Wincompatible-pointer-types.
2024-02-06 06:58:31 +00:00
Matthijs Velsink
87fcec6529 wifi: Fix invalid pointer type with cast
Fixes build with -Wincompatible-pointer-types.
2024-02-06 06:58:31 +00:00
Christian Kirbach
f628a1ada3 Update German translation 2024-02-03 23:05:01 +00:00
zayar lwin
c6611f1cb8 Update Burmese translation 2024-02-02 12:39:27 +00:00
Jürgen Benvenuti
b362343b04 Update German translation 2024-01-28 13:14:14 +00:00
Daniel Rusek
1d723270ff Update Czech translation 2024-01-24 01:22:29 +00:00
Yosef Or Boczko
e0fbbd6279 Update Hebrew translation 2024-01-20 18:32:09 +00:00
Quentin PAGÈS
c90adb673e Update Occitan translation 2024-01-17 19:31:20 +00:00
Efstathios Iosifidis
65f151dfec Update Greek translation 2024-01-06 14:27:25 +00:00
Efstathios Iosifidis
42e994c6d5 Update Greek translation 2024-01-06 08:51:05 +00:00
Efstathios Iosifidis
25194046e7 Update Greek translation 2024-01-05 22:01:46 +00:00
Alynx Zhou
9670d032e7 system/region: Prevent preview crash from accessing invalid pointer
In !2051, we switch back to real locale before setting the label text,
however, according to nl_langinfo's manpage, the returned pointer could
be invalid after switching locale or creating new locale, so the program
may crash.

To fix this, we save the result before switching locale, so we won't
access the invalid pointer after switching locale.
2024-01-04 11:24:29 +08:00
Efstathios Iosifidis
0a8e61c9eb Update Greek translation 2024-01-03 20:10:05 +00:00
Efstathios Iosifidis
4ef09d387a Update Greek translation 2024-01-01 21:00:38 +00:00
Efstathios Iosifidis
1c83dcf37a Update Greek translation 2024-01-01 19:04:47 +00:00
Efstathios Iosifidis
a57a45ae18 Update Greek translation 2024-01-01 11:10:39 +00:00
Efstathios Iosifidis
4a1b9b2a2c Update Greek translation 2023-12-31 23:15:58 +00:00
Fabio Tomat
6d11167a3a Update Friulian translation 2023-12-28 20:49:15 +00:00
Matej Urbančič
92acbff00a Update Slovenian translation 2023-12-27 19:57:44 +00:00
Ekaterine Papava
88b0ab9204 Update Georgian translation 2023-12-17 16:00:05 +00:00
Automeris naranja
649d06d954 cc-panel-list: Wrap the text when showing "No Results Found"
https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/2024 fixed https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2788, but it's for gnome-46.
This commit fixes https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2788 with small changes (because it's for the
stable branch), using the same properties that AdwStatusPage uses for
its title and subtitle/description:

https://gitlab.gnome.org/GNOME/libadwaita/-/blob/libadwaita-1-4/src/adw-status-page.ui
2023-12-11 22:16:54 +00:00
Felipe Borges
cc5da95fec 45.2 2023-12-07 11:50:36 +01:00
Andre Klapper
84a69d0289 DOAP: Replace defunct mailing list with Discourse support forum 2023-12-07 11:31:08 +01:00
Felipe Borges
2a104f26d8 privacy: Make firmware page visibility check cancellable
So that the page doesn't crash when closing the panel before the
firmware page visibility has been set.
2023-12-07 11:29:57 +01:00
Felipe Borges
8aa48007a1 privacy: Make Bolt page visibility check cancellable
When the Bolt page gets disposed before it finishes initializing
its client object we get a crash. See #2700

A way to trigger the crash is to switch panels fast enough so that
the sync dbus call is not finished by the time the panel is disposed.

This is not a guaranteed fix since I can't reproduce the issue
consistently.
2023-12-07 11:29:46 +01:00
Jonathan Kang
77ab990e12 network-connection-editor: Close the editor when nm-connection-editor exits
Previously, when editing a connection that doesn't have native editor
support, nm-connection-editor is spawned to do the work. But after
closing nm-connection-editor, an empty editor dialog still exists.

Fix that in this commit.
2023-12-07 11:28:59 +01:00
Bruce Cowan
5a93a42041 Update British English translation 2023-12-06 12:57:39 +00:00
velsinki
64537f6bc3 background: Improve chooser performance
The size of the background item is currently never used, but setting it
using `gnome_bg_get_image_size ()` is expensive, since that actually
does a thumbnail retrieval.

Instead, we can retrieve the size of the background file directly,
improving the rendering performance of the chooser significantly.
2023-11-28 14:47:16 +01:00
Felipe Borges
0efaa27bea mouse: Prevent arrows in Test window from interfering with mouse events
Fixes #2769
2023-11-28 10:31:44 +01:00
Artur S0
22956cba01 Update Russian translation 2023-11-27 16:24:27 +00:00
Lukáš Tyrychtr
a8f74e39f1 sound: When setting mixer control for a stream row, update muted state as well
We were updating the volume state, but not the mute one, so, do both.

Fixes #2749
2023-11-27 12:52:26 +01:00
velsinki
e736e1b259 system/region: Preview measurement format in current locale
The Formats preview tries to find the measurement format of the locale
to preview, and then displays it. However, it displays the text in the
default locale, instead of in the real current locale, as newlocale ()
with base = (locale_t) 0 will use the default locale.

This is fixed by switching back to the real locale before setting the
label text.

Fixes #2458

Part-of: <https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/2051>
2023-11-27 12:48:42 +01:00
Maximiliano Sandoval R
3250055ebf window: Set the main window height request to 294
This is the size you get on a mobile screen on landscape mode. See
https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/migrating-to-breakpoints.html.
2023-11-27 12:47:38 +01:00
Marcos Miller
1aa75612e9 network: Show top buttons on unsupported network daemon page
When entering the network panel without the network daemon,
the window decoration buttons do not appear because the whole panel
content was overwritten by an AdwStatusPage.

Now only the content of the AdwToolbarView is changed, preserving
the AdwHeaderBar and buttons.

Fixes https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2695
2023-11-27 12:47:21 +01:00
Ismael
318f87cdbc network: Share WPA3 (SAE) networks with QR Code 2023-11-27 12:45:19 +01:00
Ondřej Pohořelský
9a5e225752 wifi: hide QR code icon when connection not successful
Don't show QR code icon when there is no info about connection being
valid and successful. Also hide it when we are connecting and when WiFi
has no password.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/2030>
2023-11-27 12:45:13 +01:00
Ondřej Pohořelský
cc529478dc network: remove wpa-none from key_mgmt
Network Manager dropped `wpa-none` value from `key_mgmt` a while ago[0]
There is no need to test for this option anymore.

[0]c97e0ce30b
2023-11-27 12:45:06 +01:00
Yaron Shahrabani
2a409e7872 Update Hebrew translation 2023-11-26 12:32:43 +00:00
Milo Casagrande
8c6e673c94 Update Italian translation 2023-11-24 15:02:12 +00:00
velsinki
9d57e857cf apps: Fix status page glitch on initialization
For an unknown reason, the AdwNavigationSplitView loading takes some
time, in which the Apps panel is not yet initialized. During that time,
the top item of the GtkStack, namely the No Apps AdwStatusPage will
show. This appears glitchy.

To work around this, make the first item of the GtkStack a "fake" empty
GtkBox that can show instead of the AdwStatusPage.

Fixes #2665
2023-11-24 10:40:11 +00:00
Sabri Ünal
3cc13bf47f Update Turkish translation 2023-11-23 17:07:24 +00:00
Lukáš Tyrychtr
ad47ec14c3 po: Fix missing closing tag in pt_BR locale
Fixes #2766
2023-11-23 11:38:06 +01:00
velsinki
b3afa91f1a background: Improve preview performance
Since 7cef6dc5, the background previews are rendered at the full
resolution. However, this is expensive and causes considerable lag,
especially for resizes. Since then, the thumbnail size has doubled to
256 pixels, making the previews sharper even at larger sizes.

So, to improve performance, let's effectively revert 7cef6dc5. The
revert is not possible without disabling frame = 0 retrieval, since that
is broken for non-slideshow backgrounds and was not used before anyways
with force_size = TRUE.

Related to #674
Related to #704
Related to #2448
2023-11-23 09:45:49 +01:00
Hugo Carvalho
39f12a7d1b Update Portuguese translation 2023-11-22 13:33:33 +00:00
Yuri Chornoivan
f6215b0c0c Update Ukrainian translation 2023-11-21 09:08:50 +00:00
velsinki
bd328beba4 applications: Fix File & Link Associations UI
When removing a File & Link Association from the dialog, or resetting
them, the UI does not update. Fix this by rebuilding the handler dialog
on both unset and reset.

Fixes #389
Fixes #2172
2023-11-21 15:57:13 +13:00
Felipe Borges
ff0052ceff user-accounts: Sync lock tooltip for the Avatar
We were adding the "Unlock" tooltip to the avatar widget but not
removing it when the panel was unlocked.

Fixes #2738
2023-11-10 12:10:30 +01:00
Ekaterine Papava
6f19ba27e0 Update Georgian translation 2023-11-09 09:54:14 +00:00
Jose Riha
295c5f7916 Update Slovak translation 2023-11-09 09:06:09 +00:00
velsinki
b5c7708093 privacy: Fix crash from free bug in cc-camera-page
The GVariant constructor g_variant_new () gives a floating reference,
which will be sunk by the g_dbus_..._call () methods. Unless the
constructed GVariant is manually referenced, it should not be used in a
g_autoptr () setting. Otherwise a use-after-free might occur in the
async g_dbus_..._call () methods.

This problem occurs here, which is simply prevented by not having the
g_autoptr () declaration for the GVariant.

Fixes #2647
Fixes #2704
Fixes #2635
Fixes #2706
2023-11-08 14:49:05 +01:00
Ekaterine Papava
d92c5bc9a6 Update Georgian translation 2023-11-05 22:35:57 +00:00
Asier Sarasua Garmendia
80772d947b Update Basque translation 2023-11-05 08:05:35 +00:00
Ngọc Quân Trần
1307efed3a Update Vietnamese translation 2023-11-05 02:29:21 +00:00
Daniel Rusek
cc0630b39e Update Czech translation 2023-11-05 01:54:21 +00:00
Daniel Rusek
c47512abf4 Update Czech translation 2023-11-05 00:14:31 +00:00
Artur S0
f14eef644e Update Russian translation 2023-11-04 02:09:19 +00:00
Felipe Borges
2af7116f59 ci: Stop building GLib from the source 2023-10-27 17:11:28 +02:00
Felipe Borges
5d6447b0b9 default-apps: Workaround AdwComboRow item selection at startup
Our callback handler for the AdwComboRow::selected-item property
changes gets called at startup, resulting in a slow and unnecessary
default app change.

This is a workaround to avoid calling g_app_info_set_as_default_for_type
without user input.

This is a backport of commit 6fb324634a

Fixes #2626
Fixes #2683
2023-10-27 17:06:33 +02:00
velsinki
b7309b1f19 network-connection-editor: Align Routes labels
Even though the routes_metric_label is in a GtkSizeGroup with the
GtkEntry for the metric, its size was set too big after adding the entry
to the size group. To fix this, add all the other labels and
corresponding entries to size groups as well. The hexpand can then be
removed as well on the labels.

Fixes #1235
2023-10-26 21:07:46 -05:00
Марко Костић
076e4f46f0 Update Serbian translation 2023-10-25 06:04:17 +00:00
Felipe Borges
a95ab55060 45.1 2023-10-23 15:24:35 +02:00
Maximiliano Sandoval R
0d01819cbd keyboard-shortcut-dialog: Allow escape to close
At the moment the search entry is consuming the Escape key press, so we
have to manually tell it what to do with it.

We clear the search on the first press, if there is input, and close the
window otherwise.
2023-10-23 10:49:22 +02:00
Marco Melorio
b083248538 mouse-panel: Increase AdwBreakpoint width to avoid videos being blurry
When reducing the window width, CCSplitRow won't have enough width
to display videos without blurriness. This change increases the
AdwBreakpoint width so CCSplitRow shows vertically before that problem
described earlier happens.

See also: https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1960#note_1869031

Part-of: <https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1960>

Partially fixes https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2631
2023-10-23 10:48:58 +02:00
Marco Melorio
f2df7c50ab cc-split-row: Reduce GtkPicture horizontal margins to avoid blurriness
There is a difference between the aspect ratio of the CCSplitRow widget
and the videos from the Mouse & Touchpad panel, which causes the videos
to appear blurry.

This change reduces the video margins so they can better align with the pixel grid.
See also: https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1960#note_1869031

Part-of: <https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1960>

Partially fixes https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2631
2023-10-23 10:48:40 +02:00
Felipe Borges
7397765226 a11y: Make Cursor size dialog close on Escape key
Addresses comment
https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1951#note_1865060
2023-10-23 10:48:12 +02:00
Marco Melorio
c0cbf0b566 illustrated-row: Use correct property to scale down image
This widget was using halign instead of content-fit to scale down the
image to the correct resolution, and it was making the image blurry in
some cases.

Fixes https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2382.
2023-10-23 10:47:42 +02:00
Ekaterine Papava
41ad0d9471 Update Georgian translation 2023-10-20 05:35:32 +00:00
Florentina Mușat
1bdb56b1d6 Update Romanian translation 2023-10-18 18:19:58 +00:00
Daniel Mustieles
55774c6e44 Updated Spanish translation 2023-10-17 15:53:30 +02:00
Artur S0
f565c9b4c4 Update Russian translation 2023-10-16 11:29:15 +00:00
Sabri Ünal
74dfd288a3 Update Turkish translation 2023-10-14 07:08:26 +00:00
Asier Sarasua Garmendia
454955aada Update Basque translation 2023-10-12 06:49:28 +00:00
Michael Catanzaro
30eda57465 Revert "network: Disable DNS entry if the automatic option is enabled"
This reverts commit 8a4a80b7b2.

This is a manual revert, because the code changed considerably in
a2b9620b1b. Anyway, although this seemed
like a good idea, problem is it clobbers the original state of the
connection without any explicit user action if the connection is
configured to use both manual and auto DNS. And this happens in practice
for imported Wireguard connections, which uselessly have auto DNS
enabled due to this NetworkManager bug:

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1399

Additional discussion:

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1745#note_2112420

The simplest solution is to not try to prevent the user from configuring
both manual and auto DNS. Instead, let's just warn the user that this
configuration may not be intended in a follow-up commit.

Fixes #2617

Part-of: <https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1944>
2023-10-09 21:09:01 +00:00
Daniel Rusek
b7b56e65c2 Update Czech translation 2023-10-09 21:04:46 +00:00
Daniel Șerbănescu
e9ffde0036 Update Romanian translation 2023-10-09 16:12:25 +00:00
Cyber Phantom
3f2488d553 info-overview: Don't set key binding twice 2023-10-09 12:20:52 +02:00
Sabri Ünal
98d52f881d Update Turkish translation 2023-10-07 06:35:42 +00:00
Daniel Rusek
2e59005b6f Update Czech translation 2023-10-06 22:56:54 +00:00
Michael Catanzaro
c7684fec5c network: fix editing connections without a device
For example, fix adding new VPN connections.

In 60b4956c05 I correctly observed that we
need to not run code that requires a device when there is no device.
NetConnectionEditor is a multipurpose dialog and self->device is
optional when creating the dialog. E.g. when modifying VPN
configuration, we update just the configuration, not an NMDevice.

However, I added this check too soon, before updating the connection
configuration. We need to update the configuration first, then only bail
before proceeding to update the device, not sooner.

Fix #2668
2023-10-03 13:04:08 +02:00
Felipe Borges
130c4ecbae mouse: Fix linked style of primary mouse button in RTL
Commit d980e0ffee fixed an issue when the "Left" button would appear
at the right side for RTL languages given that GtkBox would reorder
its horizontal children to RTL direction.

The solution at the time was to force the primary-button box to stay
in LTR direction when the rest of the interface is shown in RTL.
This introduced a regression where the CSS "linked" style of the
buttons used was the LTR one, breaking the "linked" styling.

This fix will manually reorder the Left/Right buttons rather than
calling gtk_widget_set_direction on the primary-button-box.

Fixes #2649
2023-10-03 11:01:58 +02:00
Sabri Ünal
ee7058adc2 Update Turkish translation 2023-10-01 18:30:08 +00:00
Aurimas Černius
38b0bc5667 Update Lithuanian translation 2023-09-25 20:09:39 +00:00
Rafael Fontenelle
cef09dfa7d Update Brazilian Portuguese translation 2023-09-25 13:26:57 +00:00
Martin
a9d37c85d1 Update Slovenian translation 2023-09-24 15:35:29 +00:00
Danial Behzadi
8922e6220c Update Persian translation 2023-09-24 12:35:23 +00:00
Piotr Drąg
a8be38080b Update Polish translation 2023-09-24 14:27:41 +02:00
Kristjan SCHMIDT
aacba75357 Update Esperanto translation 2023-09-23 23:34:37 +00:00
Danial Behzadi
538201116f Update Persian translation 2023-09-23 15:24:39 +00:00
Balázs Úr
59cfa336ab Update Hungarian translation 2023-09-22 22:40:51 +00:00
Jordi Mas i Hernandez
63818b7ae0 Update Catalan translation 2023-09-22 15:52:02 +00:00
Guillaume Bernard
165fd55ec2 Update French translation 2023-09-22 14:23:10 +00:00
Marco Melorio
b01cba0a82 privacy: Fix crash in the firmware security page
Make sure the timeouts are stopped when the page is finalized.
2023-09-22 12:41:56 +02:00
Kristjan SCHMIDT
8cfd9bb72c Update Esperanto translation 2023-09-21 22:30:34 +00:00
Asier Sarasua Garmendia
43ca1672c8 Update Basque translation 2023-09-21 17:28:25 +00:00
Baurzhan Muftakhidinov
47e856a4cf Update Kazakh translation 2023-09-21 15:27:07 +00:00
Boyuan Yang
b364cc063f Update Chinese (China) translation 2023-09-21 14:14:10 +00:00
Fran Dieguez
d0668ffcde Update Galician translation 2023-09-21 10:22:16 +00:00
Anders Jonsson
009b2fc1be Update Swedish translation 2023-09-21 08:27:34 +00:00
Sabri Ünal
234390e803 Update Turkish translation 2023-09-20 19:02:01 +00:00
646 changed files with 64339 additions and 70736 deletions

View File

@@ -1,12 +0,0 @@
# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
BasedOnStyle: GNU
AlwaysBreakAfterDefinitionReturnType: All
BreakBeforeBinaryOperators: None
BinPackParameters: false
SpaceAfterCStyleCast: true
PointerAlignment: Right
# Our column limit is actually 80, but setting that results in clang-format
# making a lot of dubious hanging-indent choices; disable it and assume the
# developer will line wrap appropriately. clang-format will still check
# existing hanging indents.
ColumnLimit: 0

View File

@@ -32,6 +32,13 @@ stages:
.Build procedure: &build_procedure
echo "== Building ==" &&
dnf install -y dnf5-plugins &&
git clone --depth 1 --branch 4.12.5 https://gitlab.gnome.org/GNOME/gtk.git &&
cd gtk &&
dnf5 builddep -y gtk4 &&
meson setup . _build -Dprefix=/usr -Dlibdir=lib64 &&
ninja -C _build install &&
cd .. &&
rm -rf _build/ &&
meson . _build ${BUILD_OPTS} -Dprofile=development &&
ninja -C _build 2>&1 | tee compilation.log
@@ -52,8 +59,8 @@ stages:
# stable branch.
# Could probably also switch away from rawhide,
# to stable fedora branch as well.
FDO_DISTRIBUTION_TAG: '2024-02-08.0-main'
FDO_DISTRIBUTION_VERSION: rawhide
FDO_DISTRIBUTION_TAG: '2024-04-16.0-main'
FDO_DISTRIBUTION_VERSION: 39
#############################################
# Create CI Docker Images #
@@ -80,7 +87,6 @@ build.container.fedora@x86_64:
accountsservice-devel
cheese-libs-devel
chrpath
clang-tools-extra
colord-devel colord-gtk-devel
cups-devel
desktop-file-utils
@@ -92,6 +98,7 @@ build.container.fedora@x86_64:
gobject-introspection-devel
gnome-bluetooth-libs-devel
gnome-desktop3-devel
gnome-online-accounts-devel
grilo-devel
gsettings-desktop-schemas-devel
gsound-devel
@@ -124,13 +131,14 @@ build.container.fedora@x86_64:
xorg-x11-server-Xvfb
mesa-dri-drivers
libsecret-devel
geocode-glib2-devel
libgweather4-devel
geocode-glib2-devel
lcms2-devel
geoclue2-devel
libnotify-devel
alsa-lib-devel
nss-devel
gcr3-devel
gcr-devel
setxkbmap
appstream-devel
@@ -177,12 +185,6 @@ build.container.fedora@x86_64:
ninja -C _build && \
ninja -C _build install && \
cd .. && \
git clone https://gitlab.gnome.org/GNOME/gnome-online-accounts.git && \
cd gnome-online-accounts && \
meson . _build --prefix=/usr -Dfedora=true && \
ninja -C _build && \
ninja -C _build install && \
cd .. && \
dnf remove -y systemtap-runtime
##
@@ -220,21 +222,8 @@ build:
##
# Stage: Test
#
# Runs static checks.
# Runs the unit tests.
##
style-check-diff:
extends:
- '.fdo.distribution-image@fedora'
- '.fedora.container.common'
needs:
- build.container.fedora@x86_64
stage: test
when: always
allow_failure: true
script:
- .gitlab-ci/run-style-check-diff.sh
test:
extends:
- '.fdo.distribution-image@fedora'

View File

@@ -1,133 +0,0 @@
#!/usr/bin/env python3
#
# === clang-format-diff.py - ClangFormat Diff Reformatter ---*- python -*-=== #
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===---------------------------------------------------------------------=== #
"""
This script reads input from a unified diff and reformats all the changed
lines. This is useful to reformat all the lines touched by a specific patch.
Example usage for git/svn users:
git diff -U0 --no-color HEAD^ | clang-format-diff.py -p1 -i
svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
"""
from __future__ import absolute_import, division, print_function
import argparse
import difflib
import re
import subprocess
import sys
if sys.version_info.major >= 3:
from io import StringIO
else:
from io import BytesIO as StringIO
def main():
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-i', action='store_true', default=False,
help='apply edits to files instead of displaying a '
'diff')
parser.add_argument('-p', metavar='NUM', default=0,
help='strip the smallest prefix containing P slashes')
parser.add_argument('-regex', metavar='PATTERN', default=None,
help='custom pattern selecting file paths to reformat '
'(case sensitive, overrides -iregex)')
parser.add_argument('-iregex', metavar='PATTERN',
default=r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc'
r'|js|ts|proto|protodevel|java|cs)',
help='custom pattern selecting file paths to reformat '
'(case insensitive, overridden by -regex)')
parser.add_argument('-sort-includes', action='store_true', default=False,
help='let clang-format sort include blocks')
parser.add_argument('-v', '--verbose', action='store_true',
help='be more verbose, ineffective without -i')
parser.add_argument('-style',
help='formatting style to apply (LLVM, Google, '
'Chromium, Mozilla, WebKit)')
parser.add_argument('-binary', default='clang-format',
help='location of binary to use for clang-format')
args = parser.parse_args()
# Extract changed lines for each file.
filename = None
lines_by_file = {}
for line in sys.stdin:
match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
if match:
filename = match.group(2)
if filename is None:
continue
if args.regex is not None:
if not re.match('^%s$' % args.regex, filename):
continue
else:
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
continue
match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
if match:
start_line = int(match.group(1))
line_count = 1
if match.group(3):
line_count = int(match.group(3))
if line_count == 0:
continue
end_line = start_line + line_count - 1
lines_by_file.setdefault(filename, []).extend(
['-lines', str(start_line) + ':' + str(end_line)])
# Reformat files containing changes in place.
# We need to count amount of bytes generated in the output of
# clang-format-diff. If clang-format-diff doesn't generate any bytes it
# means there is nothing to format.
format_line_counter = 0
for filename, lines in lines_by_file.items():
if args.i and args.verbose:
print('Formatting {}'.format(filename))
command = [args.binary, filename]
if args.i:
command.append('-i')
if args.sort_includes:
command.append('-sort-includes')
command.extend(lines)
if args.style:
command.extend(['-style', args.style])
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=None,
stdin=subprocess.PIPE,
universal_newlines=True)
stdout, _ = p.communicate()
if p.returncode != 0:
sys.exit(p.returncode)
if not args.i:
with open(filename) as f:
code = f.readlines()
formatted_code = StringIO(stdout).readlines()
diff = difflib.unified_diff(code, formatted_code,
filename, filename,
'(before formatting)',
'(after formatting)')
diff_string = ''.join(diff)
if diff_string:
format_line_counter += sys.stdout.write(diff_string)
if format_line_counter > 0:
sys.exit(1)
if __name__ == '__main__':
main()

View File

@@ -1,62 +0,0 @@
#!/bin/bash
set -e
ancestor_horizon=31 # days (one month)
# Recently, git is picky about directory ownership. Tell it not to worry.
git config --global --add safe.directory "$PWD"
# We need to add a new remote for the upstream target branch, since this script
# could be running in a personal fork of the repository which has out of date
# branches.
#
# Limit the fetch to a certain date horizon to limit the amount of data we get.
# If the branch was forked from origin/main before this horizon, it should
# probably be rebased.
if ! git ls-remote --exit-code upstream >/dev/null 2>&1 ; then
git remote add upstream https://gitlab.gnome.org/GNOME/gnome-control-center.git
fi
# Work out the newest common ancestor between the detached HEAD that this CI job
# has checked out, and the upstream target branch (which will typically be
# `upstream/main` or `upstream/glib-2-62`).
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` or `${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}`
# are only defined if were running in a merge request pipeline,
# fall back to `${CI_DEFAULT_BRANCH}` or `${CI_COMMIT_BRANCH}` respectively
# otherwise.
source_branch="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-${CI_COMMIT_BRANCH}}"
target_branch="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}"
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" origin "${source_branch}"
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" upstream "${target_branch}"
newest_common_ancestor_sha=$(git merge-base upstream/${target_branch} origin/${source_branch})
if [ -z "${newest_common_ancestor_sha}" ]; then
echo "Couldnt find common ancestor with upstream main branch. This typically"
echo "happens if you branched from main a long time ago. Please update"
echo "your clone, rebase, and re-push your branch."
exit 1
fi
git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
exit_status=$?
# The style check is not infallible. The clang-format configuration cannot
# perfectly describe GNOME Settings coding style: in particular, it cannot align
# function arguments. The documented coding style for GNOME Settings takes priority over
# clang-format suggestions. Hopefully we can eventually improve clang-format to
# be configurable enough for our coding style. Thats why this CI check is OK
# to fail: the idea is that people can look through the output and ignore it if
# its wrong. (That situation can also happen if someone touches pre-existing
# badly formatted code and it doesnt make sense to tidy up the wider coding
# style with the changes theyre making.)
echo ""
echo "Note that clang-format output is advisory and cannot always match the"
echo "GNOME Settings coding style, documented at:"
echo " https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/docs/CODING_STYLE.md"
echo "Warnings from this tool can be ignored in favour of the documented "
echo "coding style, or in favour of matching the style of existing"
echo "surrounding code."
exit ${exit_status}

287
NEWS
View File

@@ -1,231 +1,92 @@
=================
Version 46.beta.1
=================
============
Version 45.4
============
Exceptional release to fix translations
https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2893
=================
Version 46.beta.1
=================
Exceptional release to include gnome-online-accounts changes
(Freeze break exception https://gitlab.gnome.org/Teams/Releng/freeze-breaks/-/issues/164)
===============
Version 46.beta
===============
- Drop pkexec dependency
- Bump gcr dependency to gcr4
- Reorder sidebar/panel list
- Use g_clear_handle_id with g_source_remove to remove GSources
- Add CcHostname as a wrapper to interact with system-hostnamed
- Remove periods in subtitles/descriptions/labels according to the HIG
- Various string/sentence rewording (for clarity)
- Various style changes in symbolic icons
- Various ports of custom widgets to modern libadwaita alternatives
- Various new mnemonics added
- Various CI fixes
- Various translation updates
- CI fixes
Accessibility
- Expose new "show-status-shapes" setting
- Rephrase overamplification string in the "Hearing" settings
- Stop tracking old GTK theme
- Stop forcing HighContrast icon theme (The theme is considered deprecated)
- Improve accessibility of "Typing" settings sliders
Apps
- Tweak headings & descriptions from Default Apps sections
- Tweak the autorun-never option design (inverting the autorun-never option logic)
- Use modern libadwaita widgets in the Removable Media settings
Keyboard
- Use AdwActionRow to show the key modifier options (improves accessibility)
Network
- Fix missing VPN entries
Mouse
- Add "Test Settings" button to the body of the panel
- Modernize mouse test dialog (adds secondary-click test)
Printers
- Add padding to the sidebar items from "Printer Options"
- Add .suggested-action style class to "Test Page" button
Datetime
- Prevent unnecessary calls to auto time synchronization
Privacy
- Hide non-functional microphone panel
- Fix F1/Help link to panel's documentation
- Fix issues with writting camera/location permission-store data
- Fix issue with app listing as a result of flatpak permission-reset
Search
- Add commandline parameter for opening the Search Locations dialog directly
- Stop removing non-existent folders from tracker
- Expose single directory setting
- Add placeholder for custom locations
- Set title for non-existent bookmarks
- Always show switch for default/bookmarks
- Handle unset XDG dirs
- Tweak search locations labels
============
Version 45.3
============
Sharing
- Fix alignment of networks section in the File/Media sharing dialogs
- Use edit-delete-symbolic in networks list rather than window-close-symbolic
- Move main switches from dialog headerbars into the dialog's content area
Sound
- Show radio buttons as prefix for the Alert Sound rows
- Add tooltips to all speaker test buttons
System
- Move "Remote Login" from sharing panel to System (now named "Secure Shell")
- Use polkit to request permissions to enable/disable sshd
- Create CcSystemDetailsWindow upon opening (speed up System panel startup time)
- Fix crash in About page after dark mode switch
- Don't show Remote Desktop settings when backend is not available
- Show gnome-control-center version on the "GNOME Version" row in the About page
- Fix language chooser dialog not closing in Users page
Wacom
- Port some widgets to modern libadwaita alternatives
- Switch to using a dialog for stylus button assignments
- Highlight the currently active stylus
- Give proper ids and classes to the stylus SVG components
- Provide connector name for disambiguation
- Drop list to handle pads
- Pair only builtin pads with tablets
- Prefer the stylus over the eraser
- Don't call the standard styli "Standard stylus"
Wi-Fi
- Show password when sharing QR Code
- Fix crash with toast notifications in the Saved Networks dialog
================
Version 46.alpha
================
- Introduce the new "System" panel, grouping the settings of Region & Language, Date & Time, Users, Remote Desktop, and About.
- Add an "About Settings" dialog
- Various appdata improvements
- Various mnemonics added
- Various tooltips added
- Various CI fixes
- Various accessibility fixes
- Make "gnome-control-center --version" work on non-supported environments
- Bump meson dependency to >= 0.58
- Disable "deprecated-declarations" by default for builds
- Introduce -Ddeprecated-declarations=enabled meson build option
- Add CODEOWNERS file
Accessibility
- Rename "Overlay Scrollbars" to "Always Show Scrollbars" and invert this setting logic
- Reword the "Accessibility Menu" row
- Add description text to "Cursor Size" dialog
- Port Cursor Size dialog to AdwWindow
- Use AdwSpinRow in Zoom -> Magnification Factor row
Appearance
- Improve overall load and resize performance of background thumbnails
- Improve background chooser performance
- Make background preview thumbnails sharpier
Apps
- Drop sidebar by implementing a new mockup with a search bar inside the panel
- Move "Default Apps" and "Removable Media" panels into the "Apps" panel
- Add a banner indicating when an app isn't sandboxed
- Separate the "Required Permissions" row into its own section
- Add headings to rows from the app settings section
- Port "Removable Media Settings" row to AdwSwitchRow
- Ignore symlinks when measuring cache/data size to improve accuracy
- Use "computer-fail-symbolic" icon instead of GNOME Software's icon
- Fix "File & Link Associations" crash
- Fix "File & Link Associations" UI not updating
- Fix launching an app page from the command line (ex.: "gnome-control-center application $APP_ID)
- Replace snapd-glib with a native implementation
Cellular
- Various HIG compliance changes
Date & Time
- Add description to "Week Numbers" row
Displays
- Port custom switch rows to AdwSwitchRow
Keyboard
- Add "Left Ctrl" key to Compose Key options
- Add "Insert" key to Compose Key options
- Port Shortcut Editor from deprecated GtkDialog to AdwWindow/AdwToolbarView
- Fix showing window decoration buttons when showing the "Unsupported network daemon" status page
- Show title buttons at the initial state of "Set Shortcuts" dialog
- Add visual outline to shortcut graphic arrows
Mouse
- Add "Secondary Click" option for Touchpads (aka "Click Method")
- Add "Disable While Typing" setting to Touchpad page
- Update edge-scroll animation to represent better dimensions of physical devices
- Port custom switch rows to AdwSwitchRow
- Split "Scroll Method" and "Direction" into separate row groups
- Prevent test window arrows from interferingf with scrolling events
- Fix illustrations looking blurry on small window sizes
- Fix the linked-style of the primary mouse button setting to work on RTL languages
Network
- Use period as thousands separator on network speed label
- Avoid critical warning for floating reference in hotspot dialog
- Various UI spacing and alignment changes in the connection editor pages
- Share WPA3 (SAE) networks with QRCode
- Hide QRCode icon when connection not successful
- Handle bluetooth device connections ourselves (instead of depending on NM connection-editor)
- Don't show "Saved Wi-Fi Networks" row when there's nothing to show
- Use a "Undo" toast to allow users to undo forgetting a network in "Saved Wi-Fi Networks"
- Make the "forget network" button show only an icon (instead of a icon+label)
- Fix sensitivity of DNS and route configuration widgets
- Warn user if both automatic and manual DNS is configured
- Unset DNS entry errors when entry is empty
- Disable Wi-Fi Hotspot row when Wi-Fi is not active
Notifications
- Stop listing system services on the panel
Online Accounts
- Various memory leak fixes
Power
- Add mnemonics to help navigate the automatic suspend dialog
- Modernize the Suspend dialog
Privacy & Security
- Rename panel from "Privacy" to "Privacy & Security"
- Update panel description text
- Rename "Location Services" page to "Location"
- Make icons larger in Location/Camera/Microphone pages
- Make page visibility checks cancellable to avoid crashes
- Fix crashes on Camera and Firmware Security pages
- Rename location switch title to "Automatic Device Location"
- Reword and re-style the "Privacy" policy text
Datetime
- Fix build with -Wincompatible-pointer-types
Region
- Preview measurement format in current locale
- Prevent preview crash from accessing invalid pointer
Remote Desktop
- Use "rdp" instead of "ms-rd" for hostname URL
- Add documentation link to instruct how to use remote desktop
Wifi
- Fix build with -Wincompatible-pointer-types
Sharing
- Make panel adaptative
- Use AdwPreferencesPage/AdwPreferencesGroup in all dialogs
============
Version 45.2
============
Apps
- Fix status page glitch on initialization
- Fix "File and Link Association" interface not reflecting changes
Background
- Improve background preview and chooser performance
Default Apps
- Fix undesired resetting of default apps during startup
Mouse
- Fix interference issue with scroll event in Mouse Test window
Network
- Close network editor when using non-native nm-connection-editor
- Show decoration buttons on empty-state (no network device found page)
- Share WPA3 (SAE) networks with QR Code
- Hide QR Code icon when connection is not successful
- Remove deprecated 'wpa-none'
- Fix route label alignments
Privacy
- Fix crash from free bug in the Camera page
- Fix potential crash on Bolt page visibility
Region
- Show preview measurement format in current locale
Sound
- Update mute state when setting mixer control for a stream
Users
- Port to AdwNavigationView/Page widgets
- Move into the "System" panel
- Use AdwAvatar to generate default user icon and mark generated avatars as such
- Show tooltip information for the Avatar widget
Wacom
- Update illustration style
- Generate a smooth pressure curve instead of just 7
- Introduce mark indicating the center-point of the stylus pressure curve
- Extend ther pressurecurve range by 25% in each direction
- Use the ExpressKey Remote name for the EKR
============
Version 45.1
============
About
- Add more types of processor support
Accessibility
- Make Cursor Size dialog close on Escape key
Keyboard
- Allow closing Shortcuts dialog with Escape key
Mouse
- Fix linked style of primary mouse button in RTL languages
- Avoid making videos blurry
Network
- Fix editing connections without a device
- Revert "Disable DNS entry if automatic DNS option is enabled"
============
Version 45.0

View File

@@ -302,8 +302,6 @@
"buildsystem" : "meson",
"config-opts" : [
"-Dsystemdsystemunitdir=/app/lib/systemd/system",
"-Dudevrulesdir=/app/lib/udev",
"-Dudevhwdbdir=/app/lib/udev",
"-Dgtk-doc=false",
"-Dman=false",
"-Dintrospection=disabled"
@@ -311,8 +309,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/upower/upower.git",
"tag" : "v1.90.2"
"url" : "git://anongit.freedesktop.org/upower"
}
]
},
@@ -363,8 +360,7 @@
"-Dqt=false",
"-Dselinux=false",
"-Dsession_tracking=no",
"-Dsystemdsystemunitdir=/app/lib/systemd/system",
"-Dudev_dir=/app/lib/udev",
"-Dsystemdsystemunitdir='no'",
"-Dsystemd_journal=false",
"-Dtests=no",
"-Dvapi=false"
@@ -428,14 +424,8 @@
"config-opts" : [
"-Dintrospection=false",
"-Dbash_completion=false",
"-Dudevdir=/app/lib/udev",
"-Dudevdir=/app/lib",
"-Dsystemdsystemunitdir=/app/lib/systemd/system",
"-Ddbus_policy_dir=/app/etc/dbus-1/system.d",
"-Dsystemd_journal=false",
"-Dtests=false",
"-Dman=false",
"-Dfuzzer=false",
"-Dexamples=false",
"-Dmbim=false",
"-Dplugin_dell=disabled",
"-Dplugin_foxconn=disabled",
@@ -446,7 +436,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git",
"url" : "git://anongit.freedesktop.org/ModemManager/ModemManager",
"branch" : "main"
}
]
@@ -455,7 +445,6 @@
"name" : "gnome-settings-daemon",
"buildsystem" : "meson",
"config-opts" : [
"-Dudev_dir=/app/lib/udev",
"-Dsystemd=false"
],
"sources" : [
@@ -629,54 +618,6 @@
}
]
},
{
"name": "python3-jinja2",
"buildsystem": "simple",
"build-commands": [
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"jinja2\" --no-build-isolation"
],
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/1d/97/2288fe498044284f39ab8950703e88abbac2abbdf65524d576157af70556/MarkupSafe-2.1.1.tar.gz",
"sha256": "7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/bc/c3/f068337a370801f372f2f8f6bad74a5c140f6fda3d9de154052708dd3c65/Jinja2-3.1.2-py3-none-any.whl",
"sha256": "6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
}
]
},
{
"name": "python3-attrs",
"buildsystem": "simple",
"build-commands": [
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"attrs\" --no-build-isolation"
],
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/f0/eb/fcb708c7bf5056045e9e98f62b93bd7467eb718b0202e7698eb11d66416c/attrs-23.1.0-py3-none-any.whl",
"sha256": "1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"
}
]
},
{
"name" : "libei",
"buildsystem" : "meson",
"config-opts" : [
"-Dliboeffis=disabled",
"-Dtests=disabled"
],
"sources" : [
{
"type" : "git",
"branch" : "main",
"url" : "https://gitlab.freedesktop.org/libinput/libei.git"
}
]
},
{
"name" : "mutter",
"buildsystem" : "meson",
@@ -695,7 +636,6 @@
"-Dintrospection=true",
"-Ddocs=false",
"-Dtests=false",
"-Dnative_tests=false",
"-Dprofiler=false"
],
"sources" : [
@@ -803,7 +743,6 @@
"-Dman=false",
"-Dtests=false",
"-Dnetworkmanager=false",
"-Dcamera_monitor=false",
"-Dsystemd=false"
],
"sources" : [
@@ -836,8 +775,6 @@
}
],
"config-opts" : [
"-Dsnap=false",
"-Dtests=false",
"-Dprofile=development"
]
}

View File

@@ -1,52 +0,0 @@
# These are the people responsible for Settings panels and domain-specific
# parts of the GNOME Settings codebase.
#
# If you open a merge request for files listed here, please add the following
# people to the list of reviewers.
# The syntax of this file is defined by GitLab:
# https://docs.gitlab.com/ee/user/project/code_owners.html
# Which, in turn, is similar to the .gitignore and .gitattributes files:
#
# - comments start with `#`
# - the first column contains paths and globs
# - the second column contains GitLab user names or email addresses,
# separated by spaces
#
# The last matching glob (rather than the union of *all* matching globs) gives
# the owners of a piece of code.
#
# If you want to be responsible for code reviews in specific sections of
# the GNOME Settings code base, add yourself here.
# General maintainers
* @felipeborges @robert_ancell
# Panels
## About
panels/info-overview/* @cyberphantom52
## Accessibility
panels/universal-access/* @pksadiq
## Appearance
panels/background/* @velsinki
## Apps
panels/applications/cc-default-apps-* @nishalkulkarni
panels/applications/cc-removable-media-settings* @nishalkulkarni
## Bluetooth
panels/bluetooth/* @hadess
## Printers
panels/printers/* @mkasik
## Sound
panels/sound/* @melix99
## Wacom
panels/wacom/* @carlosg
## WWAN (Cellular)
panels/wwan/* @pksadiq

View File

@@ -22,15 +22,6 @@
</foaf:Person>
</maintainer>
<!-- General -->
<maintainer>
<foaf:Person>
<foaf:name>Robert Ancell</foaf:name>
<foaf:mbox rdf:resource="mailto:robert.ancell@canonical.com" />
<gnome:userid>rancell</gnome:userid>
</foaf:Person>
</maintainer>
<!-- Bluetooth -->
<maintainer>
<foaf:Person>
@@ -40,6 +31,15 @@
</foaf:Person>
</maintainer>
<!-- Display -->
<maintainer>
<foaf:Person>
<foaf:name>Benjamin Berg</foaf:name>
<foaf:mbox rdf:resource="mailto:bberg@gnome.org" />
<gnome:userid>bberg</gnome:userid>
</foaf:Person>
</maintainer>
<!-- Printers -->
<maintainer>
<foaf:Person>

View File

@@ -1,8 +1,8 @@
project(
'gnome-control-center', 'c',
version : '46.beta.2',
version : '45.4',
license : 'GPL2+',
meson_version : '>= 0.58.0'
meson_version : '>= 0.57.0'
)
control_center_prefix = get_option('prefix')
@@ -39,15 +39,12 @@ else
endif
application_id = 'org.gnome.Settings@0@'.format(profile)
version_split = meson.project_version().split('.')
# defines
set_defines = [
# package
['PACKAGE', meson.project_name()],
['PACKAGE_VERSION', meson.project_version()],
['VERSION', meson.project_version()],
['MAJOR_VERSION', version_split[0]],
['PROFILE', get_option('profile')],
# i18n
['GETTEXT_PACKAGE', control_center_gettext]
@@ -76,15 +73,6 @@ config_h.set('USER_DIR_MODE', '0700',
# compiler flags
common_flags = ['-DHAVE_CONFIG_H']
# We have so many deprecation warnings that it becomes impossible to notice any other useful
# warning, thus making the compiler output completely useless. Ideally, we should fix all
# of those but, until then, it's better to add this flag so that we avoid adding even more
# warnings by accident. If you want to fix some of those, just build Settings with:
# meson _build -Ddeprecated-declarions=enabled
if get_option('deprecated-declarations').disabled()
common_flags += '-Wno-deprecated-declarations'
endif
# Only add this when optimizing is enabled (default)
optimized_src = '''
#if __OPTIMIZE__ == 0
@@ -126,7 +114,7 @@ libgvc = subproject(
)
libgvc_dep = libgvc.get_variable('libgvc_dep')
goa_req_version = '>= 3.49.1'
goa_req_version = '>= 3.25.3'
pulse_req_version = '>= 2.0'
gtk_dep = dependency(
@@ -179,7 +167,7 @@ accounts_dep = dependency('accountsservice', version: '>= 0.6.39')
colord_dep = dependency('colord', version: '>= 0.1.34')
gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: '>= 2.23.0')
gio_dep = dependency('gio-2.0')
glib_dep = dependency('glib-2.0', version: '>= 2.76.6')
glib_dep = dependency('glib-2.0', version: '>= 2.75.0')
gnome_desktop_dep = dependency('gnome-desktop-4')
gnome_bg_dep = dependency('gnome-bg-4')
gnome_rr_dep = dependency('gnome-rr-4')
@@ -194,7 +182,7 @@ gudev_dep = dependency('gudev-1.0', version: '>= 232')
x11_dep = dependency('x11', version: '>= 1.8')
xi_dep = dependency('xi', version: '>= 1.2')
epoxy_dep = dependency('epoxy')
gcr_dep = dependency('gcr-4', version: '>= 4.1.0')
gcr_dep = dependency('gcr-base-3')
pwquality_dep = dependency('pwquality', version: '>= 1.2.2')
m_dep = cc.find_library('m')
@@ -258,8 +246,9 @@ config_h.set10('HAVE_FN_EXPLICIT_BZERO',
# Snap support
enable_snap = get_option('snap')
if enable_snap
json_glib_dep = dependency('json-glib-1.0')
libsoup_dep = dependency('libsoup-3.0')
snapd_glib_deps = [
dependency('snapd-glib-2', version: '>= 1.62')
]
endif
config_h.set('HAVE_SNAP', enable_snap,
description: 'Define to 1 if Snap support is enabled')

View File

@@ -1,8 +1,7 @@
option('deprecated-declarations', type: 'feature', value: 'disabled', description: 'build with deprecated declaration warnings')
option('documentation', type: 'boolean', value: false, description: 'build documentation')
option('ibus', type: 'boolean', value: true, description: 'build with IBus support')
option('privileged_group', type: 'string', value: 'wheel', description: 'name of group that has elevated permissions')
option('snap', type: 'boolean', value: true, description: 'build with Snap support')
option('snap', type: 'boolean', value: false, description: 'build with Snap support')
option('tests', type: 'boolean', value: true, description: 'build tests')
option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
option('profile', type: 'combo', choices: ['default','development'], value: 'default')

View File

@@ -2,8 +2,6 @@
<gresources>
<gresource prefix="/org/gnome/control-center/applications">
<file preprocess="xml-stripblanks">cc-applications-panel.ui</file>
<file preprocess="xml-stripblanks">cc-default-apps-page.ui</file>
<file preprocess="xml-stripblanks">cc-removable-media-settings.ui</file>
<file preprocess="xml-stripblanks">cc-applications-row.ui</file>
<file preprocess="xml-stripblanks">cc-info-row.ui</file>
<file preprocess="xml-stripblanks">cc-snap-row.ui</file>

View File

@@ -23,6 +23,9 @@
#include <config.h>
#include <glib/gi18n.h>
#ifdef HAVE_SNAP
#include <snapd-glib/snapd-glib.h>
#endif
#ifdef HAVE_MALCONTENT
#include <libmalcontent/malcontent.h>
#endif
@@ -32,14 +35,11 @@
#include "cc-applications-panel.h"
#include "cc-applications-row.h"
#include "cc-info-row.h"
#include "cc-default-apps-page.h"
#include "cc-removable-media-settings.h"
#include "cc-applications-resources.h"
#include "cc-util.h"
#ifdef HAVE_SNAP
#include "cc-snapd-client.h"
#include "cc-snap-row.h"
#endif
#include "cc-util.h"
#include "globs.h"
#include "search.h"
#include "utils.h"
@@ -54,21 +54,11 @@ struct _CcApplicationsPanel
{
CcPanel parent;
CcDefaultAppsPage *default_apps_page;
AdwSwitchRow *autorun_never_row;
CcRemovableMediaSettings *removable_media_settings;
AdwNavigationView *navigation_view;
AdwNavigationPage *app_settings_page;
GtkListBox *app_listbox;
GtkEntry *app_search_entry;
GtkWidget *empty_search_placeholder;
GtkStack *app_listbox_stack;
AdwNavigationPage *sidebar_box;
GtkListBox *sidebar_listbox;
GtkEntry *sidebar_search_entry;
GAppInfoMonitor *monitor;
gulong monitor_id;
GListModel *app_model;
GListModel *filter_model;
GtkFilter *filter;
#ifdef HAVE_MALCONTENT
GCancellable *cancellable;
@@ -88,17 +78,16 @@ struct _CcApplicationsPanel
GtkLabel *app_name_label;
GtkButton *launch_button;
GtkButton *view_details_button;
AdwBanner *sandbox_banner;
GtkWidget *sandbox_info_button;
GDBusProxy *perm_store;
GSettings *media_handling_settings;
GtkListBoxRow *perm_store_pending_row;
GSettings *notification_settings;
GSettings *location_settings;
GSettings *privacy_settings;
GSettings *search_settings;
GtkStack *stack;
GtkWidget *empty_box;
GtkWidget *settings_box;
GtkButton *install_button;
AdwPreferencesGroup *integration_section;
@@ -117,12 +106,13 @@ struct _CcApplicationsPanel
AdwSwitchRow *shortcuts;
AdwSwitchRow *microphone;
CcInfoRow *no_microphone;
AdwPreferencesGroup *other_permissions_section;
CcInfoRow *builtin;
GtkWindow *builtin_dialog;
AdwPreferencesPage *builtin_page;
GtkListBox *builtin_list;
#ifdef HAVE_SNAP
GList *snap_permission_rows;
#endif
GtkButton *handler_reset;
GtkWindow *handler_dialog;
@@ -709,9 +699,11 @@ add_snap_permissions (CcApplicationsPanel *self,
const gchar *app_id)
{
const gchar *snap_name;
g_autoptr(CcSnapdClient) client = NULL;
g_autoptr(JsonArray) plugs = NULL;
g_autoptr(JsonArray) slots = NULL;
g_autoptr(SnapdClient) client = NULL;
g_autoptr(GPtrArray) interfaces = NULL;
g_autoptr(GPtrArray) plugs = NULL;
g_autoptr(GPtrArray) slots = NULL;
SnapdInterface *interface = NULL;
gint added = 0;
g_autoptr(GError) error = NULL;
g_autoptr(GError) interfaces_error = NULL;
@@ -720,20 +712,31 @@ add_snap_permissions (CcApplicationsPanel *self,
return FALSE;
snap_name = app_id + strlen (PORTAL_SNAP_PREFIX);
client = cc_snapd_client_new ();
client = snapd_client_new ();
if (!cc_snapd_client_get_all_connections_sync (client, &plugs, &slots, cc_panel_get_cancellable (CC_PANEL (self)), &error))
interfaces = snapd_client_get_interfaces2_sync (client,
SNAPD_GET_INTERFACES_FLAGS_NONE,
NULL,
NULL, &interfaces_error);
if (interfaces == NULL)
g_warning ("Failed to get snap interfaces: %s", interfaces_error->message);
if (!snapd_client_get_connections2_sync (client,
SNAPD_GET_CONNECTIONS_FLAGS_SELECT_ALL,
NULL, NULL,
NULL, NULL,
&plugs, &slots,
NULL, &error))
{
g_warning ("Failed to get snap connections: %s", error->message);
return FALSE;
}
for (guint i = 0; i < json_array_get_length (plugs); i++)
for (int i = 0; i < plugs->len; i++)
{
JsonObject *plug = json_array_get_object_element (plugs, i);
const gchar *plug_interface;
SnapdPlug *plug = g_ptr_array_index (plugs, i);
CcSnapRow *row;
g_autoptr(JsonArray) available_slots = NULL;
g_autoptr(GPtrArray) available_slots = NULL;
const gchar * const hidden_interfaces[] = { "content",
"desktop", "desktop-legacy",
"mir",
@@ -743,25 +746,34 @@ add_snap_permissions (CcApplicationsPanel *self,
NULL };
/* Skip if not relating to this snap */
if (g_strcmp0 (json_object_get_string_member (plug, "snap"), snap_name) != 0)
if (g_strcmp0 (snapd_plug_get_snap (plug), snap_name) != 0)
continue;
/* Ignore interfaces that are too low level to make sense to show or disable */
plug_interface = json_object_get_string_member (plug, "interface");
if (g_strv_contains (hidden_interfaces, plug_interface))
if (g_strv_contains (hidden_interfaces, snapd_plug_get_interface (plug)))
continue;
available_slots = json_array_new ();
for (guint j = 0; j < json_array_get_length (slots); j++)
available_slots = g_ptr_array_new_with_free_func (g_object_unref);
for (int j = 0; j < slots->len; j++)
{
JsonObject *slot = json_array_get_object_element (slots, j);
if (g_strcmp0 (plug_interface, json_object_get_string_member (slot, "interface")) != 0)
SnapdSlot *slot = g_ptr_array_index (slots, j);
if (g_strcmp0 (snapd_plug_get_interface (plug), snapd_slot_get_interface (slot)) != 0)
continue;
json_array_add_object_element (available_slots, slot);
g_ptr_array_add (available_slots, g_object_ref (slot));
}
row = cc_snap_row_new (cc_panel_get_cancellable (CC_PANEL (self)), plug, available_slots);
if (interfaces != NULL)
{
for (int j = 0; j < interfaces->len; j++)
{
SnapdInterface *i = g_ptr_array_index (interfaces, j);
if (g_strcmp0 (snapd_interface_get_name (i), snapd_plug_get_interface (plug)) == 0)
interface = i;
}
}
row = cc_snap_row_new (cc_panel_get_cancellable (CC_PANEL (self)), interface, plug, available_slots);
adw_preferences_group_add (self->integration_section, GTK_WIDGET (row));
self->snap_permission_rows = g_list_prepend (self->snap_permission_rows, row);
added++;
@@ -771,22 +783,6 @@ add_snap_permissions (CcApplicationsPanel *self,
}
#endif
static void
update_sandbox_banner (CcApplicationsPanel *self,
const gchar *display_name,
gboolean is_sandboxed)
{
g_autofree gchar *sandbox_banner_message = NULL;
gtk_widget_set_visible (GTK_WIDGET (self->sandbox_banner), !is_sandboxed);
if (is_sandboxed)
return;
/* Translators: %s is an app name. (e.g. "Firefox is not sandboxed") */
sandbox_banner_message = g_strdup_printf (_("%s is not sandboxed"), display_name);
adw_banner_set_title (self->sandbox_banner, sandbox_banner_message);
}
static gint
add_static_permission_row (CcApplicationsPanel *self,
const gchar *title,
@@ -816,14 +812,9 @@ add_static_permissions (CcApplicationsPanel *self,
g_autofree gchar *str = NULL;
gint added = 0;
g_autofree gchar *text = NULL;
gboolean is_sandboxed, is_snap = FALSE;
is_snap = app_id && g_str_has_prefix (app_id, PORTAL_SNAP_PREFIX);
if (app_id && !is_snap)
if (app_id && !g_str_has_prefix (app_id, PORTAL_SNAP_PREFIX))
keyfile = get_flatpak_metadata (app_id);
is_sandboxed = (keyfile != NULL) || is_snap;
update_sandbox_banner (self, g_app_info_get_display_name (info), is_sandboxed);
if (keyfile == NULL)
return FALSE;
@@ -866,7 +857,7 @@ add_static_permissions (CcApplicationsPanel *self,
static void
remove_static_permissions (CcApplicationsPanel *self)
{
gtk_list_box_remove_all (self->builtin_list);
listbox_remove_all (self->builtin_list);
}
/* --- header section --- */
@@ -968,9 +959,9 @@ update_integration_section (CcApplicationsPanel *self,
gtk_widget_set_visible (GTK_WIDGET (self->no_location), set && disabled);
has_any |= set;
#ifdef HAVE_SNAP
#ifdef HAVE_SNAP
has_any |= add_snap_permissions (self, info, portal_app_id);
#endif
#endif
}
else
{
@@ -1003,10 +994,15 @@ unset_cb (CcApplicationsPanel *self,
GtkButton *button)
{
const gchar *type;
GtkListBoxRow *selected;
GAppInfo *info;
selected = gtk_list_box_get_selected_row (self->sidebar_listbox);
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (selected));
type = (const gchar *)g_object_get_data (G_OBJECT (button), "type");
g_app_info_remove_supports_type (self->current_app_info, type, NULL);
g_app_info_remove_supports_type (info, type, NULL);
update_handler_dialog (self, self->current_app_info);
}
@@ -1112,10 +1108,15 @@ app_info_recommended_for (GAppInfo *info,
static void
handler_reset_cb (CcApplicationsPanel *self)
{
GtkListBoxRow *selected;
GAppInfo *info;
const gchar **types;
gint i;
types = g_app_info_get_supported_types (self->current_app_info);
selected = gtk_list_box_get_selected_row (self->sidebar_listbox);
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (selected));
types = g_app_info_get_supported_types (info);
if (types == NULL || types[0] == NULL)
return;
@@ -1123,7 +1124,7 @@ handler_reset_cb (CcApplicationsPanel *self)
for (i = 0; types[i]; i++)
{
gchar *ctype = g_content_type_from_mime_type (types[i]);
g_app_info_add_supports_type (self->current_app_info, ctype, NULL);
g_app_info_add_supports_type (info, ctype, NULL);
}
g_signal_handler_unblock (self->monitor, self->monitor_id);
g_signal_emit_by_name (self->monitor, "changed");
@@ -1235,23 +1236,6 @@ on_storage_row_activated_cb (CcApplicationsPanel *self)
gtk_window_present (self->storage_dialog);
}
static void
on_items_changed_cb (GListModel *list,
guint position,
guint removed,
guint added,
gpointer data)
{
CcApplicationsPanel *self = data;
if (g_list_model_get_n_items (list) == 0)
gtk_stack_set_visible_child (self->app_listbox_stack,
self->empty_search_placeholder);
else
gtk_stack_set_visible_child (self->app_listbox_stack,
GTK_WIDGET (self->app_listbox));
}
static void
update_total_size (CcApplicationsPanel *self)
{
@@ -1264,7 +1248,7 @@ update_total_size (CcApplicationsPanel *self)
g_object_set (self->total, "info", formatted_size, NULL);
/* Translators: '%s' is the formatted size, e.g. "26.2 MB" */
subtitle = g_strdup_printf (_("%s of disk space used"), formatted_size);
subtitle = g_strdup_printf (_("%s of disk space used."), formatted_size);
g_object_set (self->storage, "subtitle", subtitle, NULL);
}
@@ -1407,7 +1391,7 @@ update_usage_section (CcApplicationsPanel *self,
remove_static_permissions (self);
has_builtin = add_static_permissions (self, info, portal_app_id);
gtk_widget_set_visible (GTK_WIDGET (self->other_permissions_section), has_builtin);
gtk_widget_set_visible (GTK_WIDGET (self->builtin), has_builtin);
gtk_widget_set_visible (GTK_WIDGET (self->usage_section), portal_app_id || has_builtin);
}
@@ -1422,22 +1406,23 @@ update_panel (CcApplicationsPanel *self,
if (self->perm_store == NULL)
{
/* Async permission store not initialized, row will be re-activated in the callback */
self->perm_store_pending_row = row;
g_message ("No permissions store proxy yet, come back later");
return;
}
if (row == NULL)
{
g_message ("No app selected, try again");
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (self), _("Apps"));
gtk_stack_set_visible_child (self->stack, self->empty_box);
gtk_widget_set_visible (GTK_WIDGET (self->view_details_button), FALSE);
return;
}
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (row));
adw_navigation_page_set_title (self->app_settings_page,
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (self),
g_app_info_get_display_name (info));
adw_navigation_view_push_by_tag(self->navigation_view, "settings-box");
gtk_stack_set_visible_child (self->stack, self->settings_box);
gtk_widget_set_visible (GTK_WIDGET (self->view_details_button), gnome_software_is_installed ());
g_clear_pointer (&self->current_app_id, g_free);
@@ -1453,45 +1438,19 @@ update_panel (CcApplicationsPanel *self,
self->current_portal_app_id = get_portal_app_id (info);
}
static gint
compare_rows (gconstpointer a,
gconstpointer b,
gpointer data)
{
GAppInfo *item1 = (GAppInfo *) a;
GAppInfo *item2 = (GAppInfo *) b;
g_autofree gchar *key1 = NULL;
g_autofree gchar *key2 = NULL;
key1 = g_utf8_casefold (g_app_info_get_display_name (item1), -1);
key2 = g_utf8_casefold (g_app_info_get_display_name (item2), -1);
const gchar *sort_key1 = g_utf8_collate_key (key1, -1);
const gchar *sort_key2 = g_utf8_collate_key (key2, -1);
return strcmp (sort_key1, sort_key2);
}
static void
populate_applications (CcApplicationsPanel *self)
{
g_autolist(GObject) infos = NULL;
GList *l;
g_list_store_remove_all (G_LIST_STORE (self->app_model));
listbox_remove_all (self->sidebar_listbox);
#ifdef HAVE_MALCONTENT
g_signal_handler_block (self->manager, self->app_filter_id);
#endif
infos = g_app_info_get_all ();
if (!infos)
gtk_widget_set_visible (GTK_WIDGET (self->app_search_entry), 0);
else
gtk_widget_set_visible (GTK_WIDGET (self->app_search_entry), 1);
for (l = infos; l; l = l->next)
{
GAppInfo *info = l->data;
@@ -1507,33 +1466,45 @@ populate_applications (CcApplicationsPanel *self)
#endif
row = GTK_WIDGET (cc_applications_row_new (info));
g_list_store_insert_sorted (G_LIST_STORE (self->app_model), info, compare_rows, NULL);
gtk_list_box_insert (self->sidebar_listbox, row, -1);
id = get_app_id (info);
if (g_strcmp0 (id, self->current_app_id) == 0)
gtk_list_box_select_row (self->app_listbox, GTK_LIST_BOX_ROW (row));
gtk_list_box_select_row (self->sidebar_listbox, GTK_LIST_BOX_ROW (row));
}
#ifdef HAVE_MALCONTENT
g_signal_handler_unblock (self->manager, self->app_filter_id);
#endif
}
static gint
compare_rows (GtkListBoxRow *row1,
GtkListBoxRow *row2,
gpointer data)
{
const gchar *key1 = cc_applications_row_get_sort_key (CC_APPLICATIONS_ROW (row1));
const gchar *key2 = cc_applications_row_get_sort_key (CC_APPLICATIONS_ROW (row2));
return strcmp (key1, key2);
}
static gboolean
filter_app_rows (GObject *item,
gpointer data)
filter_sidebar_rows (GtkListBoxRow *row,
gpointer data)
{
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (data);
g_autofree gchar *app_name = NULL;
g_autofree gchar *search_text = NULL;
const gchar *text;
GAppInfo *info = G_APP_INFO (item);
GAppInfo *info;
text = gtk_editable_get_text (GTK_EDITABLE (self->app_search_entry));
text = gtk_editable_get_text (GTK_EDITABLE (self->sidebar_search_entry));
/* Only filter after the second character */
if (g_utf8_strlen (text, -1) < 2)
return TRUE;
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (row));
app_name = cc_util_normalize_casefold_and_unaccent (g_app_info_get_name (info));
search_text = cc_util_normalize_casefold_and_unaccent (text);
@@ -1561,6 +1532,7 @@ row_activated_cb (CcApplicationsPanel *self,
GtkListBoxRow *row)
{
update_panel (self, row);
g_signal_emit_by_name (self, "sidebar-activated");
}
static void
@@ -1583,10 +1555,7 @@ on_perm_store_ready (GObject *source_object,
self->perm_store = proxy;
if (self->perm_store_pending_row)
g_signal_emit_by_name (self->perm_store_pending_row, "activate");
self->perm_store_pending_row = NULL;
update_panel (self, gtk_list_box_get_selected_row (self->sidebar_listbox));
}
static void
@@ -1596,7 +1565,7 @@ select_app (CcApplicationsPanel *self,
{
GtkWidget *child;
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->app_listbox));
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->sidebar_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
@@ -1604,7 +1573,7 @@ select_app (CcApplicationsPanel *self,
GAppInfo *info = cc_applications_row_get_info (row);
if (g_str_has_prefix (g_app_info_get_id (info), app_id))
{
gtk_list_box_select_row (self->app_listbox, GTK_LIST_BOX_ROW (row));
gtk_list_box_select_row (self->sidebar_listbox, GTK_LIST_BOX_ROW (row));
if (emit_activate)
g_signal_emit_by_name (row, "activate");
break;
@@ -1631,38 +1600,38 @@ on_launch_button_clicked_cb (CcApplicationsPanel *self)
&error);
if (error)
g_warning ("Error launching app: %s", error->message);
g_warning ("Error launching application: %s", error->message);
}
static void
on_app_search_entry_activated_cb (CcApplicationsPanel *self)
on_sidebar_search_entry_activated_cb (CcApplicationsPanel *self)
{
GtkListBoxRow *row;
row = gtk_list_box_get_row_at_y (self->app_listbox, 0);
row = gtk_list_box_get_row_at_y (self->sidebar_listbox, 0);
if (!row)
return;
/* Show the app */
gtk_list_box_select_row (self->app_listbox, row);
gtk_list_box_select_row (self->sidebar_listbox, row);
g_signal_emit_by_name (row, "activate");
/* Cleanup the entry */
gtk_editable_set_text (GTK_EDITABLE (self->app_search_entry), "");
gtk_widget_grab_focus (GTK_WIDGET (self->app_search_entry));
gtk_editable_set_text (GTK_EDITABLE (self->sidebar_search_entry), "");
gtk_widget_grab_focus (GTK_WIDGET (self->sidebar_search_entry));
}
static void
on_app_search_entry_search_changed_cb (CcApplicationsPanel *self)
on_sidebar_search_entry_search_changed_cb (CcApplicationsPanel *self)
{
gtk_filter_changed (self->filter, GTK_FILTER_CHANGE_DIFFERENT);
gtk_list_box_invalidate_filter (self->sidebar_listbox);
}
static void
on_app_search_entry_search_stopped_cb (CcApplicationsPanel *self)
on_sidebar_search_entry_search_stopped_cb (CcApplicationsPanel *self)
{
gtk_editable_set_text (GTK_EDITABLE (self->app_search_entry), "");
gtk_editable_set_text (GTK_EDITABLE (self->sidebar_search_entry), "");
}
static void
@@ -1670,7 +1639,6 @@ cc_applications_panel_dispose (GObject *object)
{
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (object);
g_clear_pointer (&self->sandbox_info_button, gtk_widget_unparent);
g_clear_pointer (&self->builtin_dialog, gtk_window_destroy);
g_clear_pointer (&self->handler_dialog, gtk_window_destroy);
g_clear_pointer (&self->storage_dialog, gtk_window_destroy);
@@ -1699,7 +1667,6 @@ cc_applications_panel_finalize (GObject *object)
g_clear_object (&self->manager);
#endif
g_clear_object (&self->media_handling_settings);
g_clear_object (&self->notification_settings);
g_clear_object (&self->location_settings);
g_clear_object (&self->privacy_settings);
@@ -1754,35 +1721,103 @@ cc_applications_panel_set_property (GObject *object,
static void
cc_applications_panel_constructed (GObject *object)
{
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (object);
GtkListBoxRow *row;
G_OBJECT_CLASS (cc_applications_panel_parent_class)->constructed (object);
/* Select the first row */
row = gtk_list_box_get_row_at_index (self->sidebar_listbox, 0);
gtk_list_box_select_row (self->sidebar_listbox, row);
}
static void
notify_collapsed_cb (CcApplicationsPanel *self)
{
GtkSelectionMode selection_mode;
gboolean collapsed;
GtkRoot *root;
g_assert (CC_IS_APPLICATIONS_PANEL (self));
root = gtk_widget_get_root (GTK_WIDGET (self));
g_object_get (root, "collapsed", &collapsed, NULL);
selection_mode = collapsed ? GTK_SELECTION_NONE : GTK_SELECTION_SINGLE;
gtk_list_box_set_selection_mode (self->sidebar_listbox, selection_mode);
if (!collapsed)
{
if (self->current_app_id)
select_app (self, self->current_app_id, FALSE);
else
{
GtkListBoxRow *row;
row = gtk_list_box_get_row_at_index (self->sidebar_listbox, 0);
row_activated_cb (self, row);
}
}
}
static void
cc_applications_panel_root (GtkWidget *widget)
{
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (widget);
GtkRoot *root;
GTK_WIDGET_CLASS (cc_applications_panel_parent_class)->root (widget);
root = gtk_widget_get_root (widget);
g_signal_connect_swapped (root, "notify::collapsed", G_CALLBACK (notify_collapsed_cb), self);
notify_collapsed_cb (self);
}
static void
cc_applications_panel_unroot (GtkWidget *widget)
{
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (widget);
GtkRoot *root = gtk_widget_get_root (widget);
g_signal_handlers_disconnect_by_func (root, notify_collapsed_cb, self);
GTK_WIDGET_CLASS (cc_applications_panel_parent_class)->unroot (widget);
}
static AdwNavigationPage*
cc_applications_panel_get_sidebar_widget (CcPanel *panel)
{
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (panel);
return self->sidebar_box;
}
static void
cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
{
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
g_type_ensure (CC_TYPE_DEFAULT_APPS_PAGE);
g_type_ensure (CC_TYPE_REMOVABLE_MEDIA_SETTINGS);
object_class->dispose = cc_applications_panel_dispose;
object_class->finalize = cc_applications_panel_finalize;
object_class->constructed = cc_applications_panel_constructed;
object_class->set_property = cc_applications_panel_set_property;
widget_class->root = cc_applications_panel_root;
widget_class->unroot = cc_applications_panel_unroot;
panel_class->get_sidebar_widget = cc_applications_panel_get_sidebar_widget;
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-applications-panel.ui");
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_icon_image);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_listbox);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_name_label);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_search_entry);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_settings_page);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, other_permissions_section);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, autorun_never_row);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin_dialog);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin_page);
@@ -1791,9 +1826,7 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, camera);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, clear_cache_button);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, data);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, default_apps_page);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, empty_search_placeholder);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_listbox_stack);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, empty_box);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_dialog);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_page);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_file_group);
@@ -1805,7 +1838,6 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, launch_button);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, location);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, microphone);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, navigation_view);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, no_camera);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, no_location);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, no_microphone);
@@ -1814,13 +1846,15 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, notification);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, background);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, wallpaper);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, removable_media_settings);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sandbox_banner);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sandbox_info_button);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, screenshot);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, shortcuts);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_box);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_listbox);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_search_entry);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, search);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, settings_box);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sound);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, stack);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, storage);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, storage_dialog);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, total);
@@ -1844,21 +1878,11 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
gtk_widget_class_bind_template_callback (widget_class, on_builtin_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_handler_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_launch_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_app_search_entry_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_app_search_entry_search_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_app_search_entry_search_stopped_cb);
gtk_widget_class_bind_template_callback (widget_class, on_sidebar_search_entry_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_sidebar_search_entry_search_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_sidebar_search_entry_search_stopped_cb);
gtk_widget_class_bind_template_callback (widget_class, on_storage_row_activated_cb);
}
static GtkWidget *
app_row_new (gpointer item,
gpointer user_data)
{
GAppInfo *info = item;
return GTK_WIDGET (cc_applications_row_new (info));
}
gtk_widget_class_bind_template_callback (widget_class, on_storage_row_activated_cb);}
static void
cc_applications_panel_init (CcApplicationsPanel *self)
@@ -1876,7 +1900,7 @@ cc_applications_panel_init (CcApplicationsPanel *self)
gtk_widget_set_visible (GTK_WIDGET (self->install_button), gnome_software_is_installed ());
g_signal_connect_object (self->app_listbox, "row-activated",
g_signal_connect_object (self->sidebar_listbox, "row-activated",
G_CALLBACK (row_activated_cb), self, G_CONNECT_SWAPPED);
g_signal_connect_object (self->view_details_button,
@@ -1885,32 +1909,17 @@ cc_applications_panel_init (CcApplicationsPanel *self)
self,
G_CONNECT_SWAPPED);
self->filter = GTK_FILTER (gtk_custom_filter_new ((GtkCustomFilterFunc) filter_app_rows,
self, NULL));
gtk_list_box_set_sort_func (self->sidebar_listbox,
compare_rows,
NULL, NULL);
self->app_model = G_LIST_MODEL (g_list_store_new (G_TYPE_APP_INFO));
self->filter_model = G_LIST_MODEL (gtk_filter_list_model_new (self->app_model,
GTK_FILTER (self->filter)));
g_signal_connect (self->filter_model, "items-changed",
G_CALLBACK (on_items_changed_cb), self);
gtk_list_box_bind_model (self->app_listbox,
self->filter_model,
app_row_new,
NULL,
NULL);
gtk_list_box_set_filter_func (self->sidebar_listbox,
filter_sidebar_rows,
self, NULL);
self->location_settings = g_settings_new ("org.gnome.system.location");
self->privacy_settings = g_settings_new ("org.gnome.desktop.privacy");
self->search_settings = g_settings_new ("org.gnome.desktop.search-providers");
self->media_handling_settings = g_settings_new ("org.gnome.desktop.media-handling");
g_settings_bind (self->media_handling_settings,
"autorun-never",
self->autorun_never_row,
"active",
G_SETTINGS_BIND_INVERT_BOOLEAN);
#ifdef HAVE_MALCONTENT
/* FIXME: should become asynchronous */
system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, self->cancellable, &error);

View File

@@ -2,123 +2,93 @@
<interface>
<template class="CcApplicationsPanel" parent="CcPanel">
<property name="child">
<object class="AdwNavigationView" id="navigation_view">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<!-- App Search Page (Main Ladning Page) -->
<child>
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Apps</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
<property name="content">
<object class="GtkStack" id="stack">
<!-- This "fake" empty box is there to show instead of the AdwStatusPage before the panel is initialized -->
<child>
<object class="GtkBox"/>
</child>
<child>
<object class="AdwStatusPage" id="empty_box">
<property name="icon-name">org.gnome.Software-symbolic</property>
<property name="title" translatable="yes">No Apps</property>
<child>
<object class="GtkButton" id="install_button">
<property name="label" translatable="yes">_Install Some…</property>
<property name="use-underline">True</property>
<property name="halign">center</property>
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
<style>
<class name="pill" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesPage" id="settings_box">
<!-- App icon & buttons -->
<child>
<object class="AdwPreferencesGroup">
<property name="content">
<object class="AdwPreferencesPage" id="app_search_stack_page">
<!-- Searchbar -->
<child>
<object class="AdwPreferencesGroup">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<child>
<object class="AdwClamp">
<property name="maximum-size">280</property>
<child>
<object class="GtkSearchEntry" id="app_search_entry">
<property name="placeholder_text" translatable="yes">Search apps</property>
<signal name="activate" handler="on_app_search_entry_activated_cb" object="CcApplicationsPanel" swapped="yes" />
<signal name="search-changed" handler="on_app_search_entry_search_changed_cb" object="CcApplicationsPanel" swapped="yes" />
<signal name="stop-search" handler="on_app_search_entry_search_stopped_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
<object class="GtkImage" id="app_icon_image">
<property name="icon-name">org.gnome.Software</property>
<property name="pixel-size">96</property>
<style>
<class name="icon-dropshadow" />
</style>
</object>
</child>
</object>
</child>
<!-- Default Apps Row -->
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="CcListRow">
<property name="activatable">True</property>
<property name="title" translatable="yes">_Default Apps</property>
<property name="show-arrow">True</property>
<property name="action-name">navigation.push</property>
<property name="action-target">'default-apps'</property>
<object class="GtkLabel" id="app_name_label">
<property name="wrap">True</property>
<style>
<class name="title" />
<class name="title-1" />
</style>
</object>
</child>
</object>
</child>
<!-- Apps List -->
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="GtkStack" id="app_listbox_stack">
<property name="vhomogeneous">False</property>
<object class="GtkBox">
<property name="halign">center</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">18</property>
<child>
<!-- Empty search results placeholder -->
<object class="GtkBox" id="empty_search_placeholder">
<!--AdwStatusPage can't be used here, see: https://gitlab.gnome.org/GNOME/libadwaita/-/issues/697-->
<property name="orientation">vertical</property>
<property name="valign">center</property>
<!--Use AdwClamp like AdwStatusPage-->
<child>
<object class="AdwClamp">
<style>
<class name="status-page"/>
</style>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="pixel_size">128</property>
<property name="icon_name">computer-fail-symbolic</property>
<style>
<class name="dim-label"/>
<class name="icon"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">No Apps Found</property>
<property name="wrap">True</property>
<property name="wrap-mode">word-char</property>
<property name="justify">center</property>
<style>
<class name="title"/>
<class name="title-1"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="install_button">
<property name="label" translatable="yes">_Find in Software</property>
<property name="use_underline">True</property>
<property name="halign">center</property>
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
<style>
<class name="pill"/>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox" id="app_listbox">
<property name="selection-mode">none</property>
<object class="GtkButton" id="launch_button">
<property name="label" translatable="yes">_Open</property>
<property name="use-underline">True</property>
<property name="can-shrink">True</property>
<signal name="clicked" handler="on_launch_button_clicked_cb" object="CcApplicationsPanel" swapped="yes" />
<style>
<class name="boxed-list" />
<class name="pill" />
<class name="suggested-action" />
</style>
</object>
</child>
<child>
<object class="GtkButton" id="view_details_button">
<property name="label" translatable="yes">App _Details</property>
<property name="use-underline">True</property>
<property name="can-shrink">True</property>
<style>
<class name="pill" />
</style>
</object>
</child>
@@ -128,317 +98,240 @@
</child>
</object>
</property>
</object>
</property>
</object>
</child>
<!-- Default Apps Page -->
<child>
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Default Apps</property>
<property name="tag">default-apps</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<property name="content">
<object class="AdwPreferencesPage">
<!-- Default Apps Settings -->
<child>
<object class="AdwPreferencesGroup" id="integration_section">
<child>
<object class="CcDefaultAppsPage" id="default_apps_page" />
</child>
<!-- "Automatically Launch Apps" row -->
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Removable Media</property>
<child>
<object class="AdwSwitchRow" id="autorun_never_row">
<property name="title" translatable="yes">Automat_ically Launch Apps</property>
<property name="subtitle" translatable="yes">Start apps when media is connected or inserted</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
<!-- Removable Media Settings -->
<child>
<object class="CcRemovableMediaSettings" id="removable_media_settings" />
</child>
</object>
</property>
</object>
</property>
</object>
</child>
<!-- App Settings Page -->
<child>
<object class="AdwNavigationPage" id="app_settings_page">
<property name="title" translatable="yes">App Settings</property>
<property name="tag">settings-box</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<property name="content">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwBanner" id="sandbox_banner">
<property name="visible">False</property>
<property name="revealed">True</property>
<child>
<object class="CcListRowInfoButton" id="sandbox_info_button">
<property name="visible" bind-source="sandbox_banner" bind-property="visible" bind-flags="sync-create|default"/>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-end">3</property>
<property name="text" translatable="yes">App settings cannot be fully enforced for apps which are not sandboxed. These apps may use permissions which are not shown.</property>
</object>
</child>
<object class="AdwSwitchRow" id="search">
<property name="title" translatable="yes">Search</property>
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
<signal name="notify::active" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwPreferencesPage" id="settings_box">
<!-- App icon & buttons -->
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<child>
<object class="GtkImage" id="app_icon_image">
<property name="icon-name">org.gnome.Software</property>
<property name="pixel-size">96</property>
<style>
<class name="icon-dropshadow" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="app_name_label">
<property name="wrap">True</property>
<style>
<class name="title" />
<class name="title-1" />
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="halign">center</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">18</property>
<child>
<object class="GtkButton" id="launch_button">
<property name="label" translatable="yes">_Open</property>
<property name="use-underline">True</property>
<property name="can-shrink">True</property>
<signal name="clicked" handler="on_launch_button_clicked_cb" object="CcApplicationsPanel" swapped="yes" />
<style>
<class name="pill" />
<class name="suggested-action" />
</style>
</object>
</child>
<child>
<object class="GtkButton" id="view_details_button">
<property name="label" translatable="yes">App _Details</property>
<property name="use-underline">True</property>
<property name="can-shrink">True</property>
<style>
<class name="pill" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="integration_section">
<property name="title" translatable="yes">Permissions</property>
<child>
<object class="AdwSwitchRow" id="search">
<property name="title" translatable="yes">_Search</property>
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_search">
<property name="title" translatable="yes">_Search</property>
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="notification">
<property name="title" translatable="yes">_Notifications</property>
<property name="subtitle" translatable="yes">Show system notifications</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="notification_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="background">
<property name="title" translatable="yes">_Run in Background</property>
<property name="subtitle" translatable="yes">Allow activity when the app is closed</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="background_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="screenshot">
<property name="title" translatable="yes">Scr_eenshots</property>
<property name="subtitle" translatable="yes">Take pictures of the screen at any time</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="screenshot_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="wallpaper">
<property name="title" translatable="yes">Change _Wallpaper</property>
<property name="subtitle" translatable="yes">Change the desktop wallpaper</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="wallpaper_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="sound">
<property name="title" translatable="yes">So_unds</property>
<property name="subtitle" translatable="yes">Reproduce sounds</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="sound_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_sound">
<property name="title" translatable="yes">So_unds</property>
<property name="subtitle" translatable="yes">Reproduce sounds</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="shortcuts">
<property name="title" translatable="yes">_Inhibit Shortcuts</property>
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="shortcuts_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="camera">
<property name="title" translatable="yes">Camera</property>
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
<signal name="notify::active" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_camera">
<property name="title" translatable="yes">C_amera</property>
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="microphone">
<property name="title" translatable="yes">_Microphone</property>
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_microphone">
<property name="title" translatable="yes">_Microphone</property>
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="location">
<property name="title" translatable="yes">_Location Services</property>
<property name="subtitle" translatable="yes">Access device location data</property>
<property name="use-underline">True</property>
<signal name="notify::active" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_location">
<property name="title" translatable="yes">_Location Services</property>
<property name="subtitle" translatable="yes">Access device location data</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="other_permissions_section">
<child>
<object class="CcInfoRow" id="builtin">
<property name="title" translatable="yes">Re_quired Access</property>
<property name="subtitle" translatable="yes">System access that is required by the app</property>
<property name="has-expander">True</property>
<property name="is-link">True</property>
<signal name="activated" handler="on_builtin_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="usage_section">
<property name="title" translatable="yes">General</property>
<child>
<object class="CcInfoRow" id="handler_row">
<property name="title" translatable="yes">_File &amp;amp; Link Associations</property>
<property name="has-expander">True</property>
<property name="is-link">True</property>
<signal name="activated" handler="on_handler_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
<child>
<object class="CcInfoRow" id="storage">
<property name="title" translatable="yes">S_torage</property>
<property name="has-expander">1</property>
<property name="is-link">1</property>
<signal name="activated" handler="on_storage_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
</object>
</child>
<object class="CcInfoRow" id="no_search">
<property name="title" translatable="yes">Search</property>
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="notification">
<property name="title" translatable="yes">Notifications</property>
<property name="subtitle" translatable="yes">Show system notifications</property>
<signal name="notify::active" handler="notification_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="background">
<property name="title" translatable="yes">Run in Background</property>
<property name="subtitle" translatable="yes">Allow activity when the app is closed</property>
<signal name="notify::active" handler="background_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="screenshot">
<property name="title" translatable="yes">Screenshots</property>
<property name="subtitle" translatable="yes">Take pictures of the screen at any time</property>
<signal name="notify::active" handler="screenshot_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="wallpaper">
<property name="title" translatable="yes">Change Wallpaper</property>
<property name="subtitle" translatable="yes">Change the desktop wallpaper.</property>
<signal name="notify::active" handler="wallpaper_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="sound">
<property name="title" translatable="yes">Sounds</property>
<property name="subtitle" translatable="yes">Reproduce sounds.</property>
<signal name="notify::active" handler="sound_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_sound">
<property name="title" translatable="yes">Sounds</property>
<property name="subtitle" translatable="yes">Reproduce sounds</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="shortcuts">
<property name="title" translatable="yes">Inhibit Shortcuts</property>
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts</property>
<signal name="notify::active" handler="shortcuts_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="camera">
<property name="title" translatable="yes">Camera</property>
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
<signal name="notify::active" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_camera">
<property name="title" translatable="yes">Camera</property>
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="microphone">
<property name="title" translatable="yes">Microphone</property>
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
<signal name="notify::active" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_microphone">
<property name="title" translatable="yes">Microphone</property>
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="location">
<property name="title" translatable="yes">Location Services</property>
<property name="subtitle" translatable="yes">Access device location data</property>
<signal name="notify::active" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
</object>
</child>
<child>
<object class="CcInfoRow" id="no_location">
<property name="title" translatable="yes">Location Services</property>
<property name="subtitle" translatable="yes">Access device location data</property>
<property name="info" translatable="yes">Disabled</property>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</child>
</child>
<child>
<object class="AdwPreferencesGroup" id="usage_section">
<child>
<object class="CcInfoRow" id="builtin">
<property name="title" translatable="yes">Required Access</property>
<property name="subtitle" translatable="yes">System access that is required by the app</property>
<property name="has-expander">True</property>
<property name="is-link">True</property>
<signal name="activated" handler="on_builtin_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
<child>
<object class="CcInfoRow" id="handler_row">
<property name="title" translatable="yes">File &amp;amp; Link Associations</property>
<property name="has-expander">True</property>
<property name="is-link">True</property>
<signal name="activated" handler="on_handler_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
<child>
<object class="CcInfoRow" id="storage">
<property name="title" translatable="yes">Storage</property>
<property name="has-expander">1</property>
<property name="is-link">1</property>
<signal name="activated" handler="on_storage_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</property>
</template>
<!-- Sidebar -->
<object class="AdwNavigationPage" id="sidebar_box">
<property name="title" translatable="yes">Apps</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<child type="top">
<object class="AdwBin">
<style>
<class name="toolbar"/>
</style>
<property name="child">
<object class="GtkSearchEntry" id="sidebar_search_entry">
<property name="placeholder_text" translatable="yes">Search apps</property>
<signal name="activate" handler="on_sidebar_search_entry_activated_cb" object="CcApplicationsPanel" swapped="yes" />
<signal name="search-changed" handler="on_sidebar_search_entry_search_changed_cb" object="CcApplicationsPanel" swapped="yes" />
<signal name="stop-search" handler="on_sidebar_search_entry_search_stopped_cb" object="CcApplicationsPanel" swapped="yes" />
</object>
</property>
</object>
</child>
<property name="content">
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="child">
<object class="GtkListBox" id="sidebar_listbox">
<property name="selection-mode">browse</property>
<style>
<class name="navigation-sidebar" />
</style>
<child type="placeholder">
<object class="GtkBox" id="empty_search_placeholder">
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="margin-top">18</property>
<property name="margin-bottom">18</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage">
<property name="can_focus">False</property>
<property name="pixel_size">64</property>
<property name="icon_name">edit-find-symbolic</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can_focus">False</property>
<property name="label" translatable="yes">No results found</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.44"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Try a different search</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</property>
</object>
<!-- Built-in Permissions dialog -->
<object class="AdwWindow" id="builtin_dialog">
<property name="title" translatable="yes">Required Access</property>
@@ -532,13 +425,10 @@
<object class="GtkButton" id="handler_reset">
<property name="valign">center</property>
<property name="margin-top">12</property>
<property name="label" translatable="yes">_Reset</property>
<property name="use-underline">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Reset</property>
<signal name="clicked" handler="handler_reset_cb" object="CcApplicationsPanel" swapped="yes"/>
<style>
<class name="destructive-action" />
<class name="pill" />
</style>
</object>
</child>
@@ -558,8 +448,7 @@
<property name="resizable">True</property>
<property name="hide-on-close">True</property>
<property name="default-width">420</property>
<property name="width-request">360</property>
<property name="height-request">294</property>
<property name="default-height">420</property>
<child>
<object class="GtkShortcutController">
<property name="scope">managed</property>
@@ -578,7 +467,7 @@
</child>
<property name="content">
<object class="AdwPreferencesPage">
<property name="description" translatable="yes">How much disk space this app is occupying with app data and caches</property>
<property name="description" translatable="yes">How much disk space this app is occupying with app data and caches.</property>
<child>
<object class="AdwPreferencesGroup">
<child>
@@ -611,13 +500,9 @@
<object class="AdwPreferencesGroup">
<child>
<object class="GtkButton" id="clear_cache_button">
<property name="label" translatable="yes">_Clear Cache</property>
<property name="label" translatable="yes">_Clear Cache</property>
<property name="use-underline">True</property>
<property name="halign">center</property>
<signal name="clicked" handler="clear_cache_cb" object="CcApplicationsPanel" swapped="yes"/>
<style>
<class name="pill" />
</style>
</object>
</child>
</object>

View File

@@ -26,12 +26,17 @@
struct _CcApplicationsRow
{
AdwActionRow parent;
GtkListBoxRow parent;
GAppInfo *info;
gchar *sortkey;
GtkWidget *box;
GtkWidget *image;
GtkWidget *label;
};
G_DEFINE_TYPE (CcApplicationsRow, cc_applications_row, ADW_TYPE_ACTION_ROW)
G_DEFINE_TYPE (CcApplicationsRow, cc_applications_row, GTK_TYPE_LIST_BOX_ROW)
static void
cc_applications_row_finalize (GObject *object)
@@ -39,6 +44,7 @@ cc_applications_row_finalize (GObject *object)
CcApplicationsRow *self = CC_APPLICATIONS_ROW (object);
g_object_unref (self->info);
g_free (self->sortkey);
G_OBJECT_CLASS (cc_applications_row_parent_class)->finalize (object);
}
@@ -52,6 +58,10 @@ cc_applications_row_class_init (CcApplicationsRowClass *klass)
object_class->finalize = cc_applications_row_finalize;
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-applications-row.ui");
gtk_widget_class_bind_template_child (widget_class, CcApplicationsRow, box);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsRow, image);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsRow, label);
}
static void
@@ -64,26 +74,23 @@ CcApplicationsRow *
cc_applications_row_new (GAppInfo *info)
{
CcApplicationsRow *self;
g_autoptr(GIcon) icon = NULL;
GtkWidget *w;
g_autofree gchar *key = NULL;
GIcon *icon;
self = g_object_new (CC_TYPE_APPLICATIONS_ROW, NULL);
self->info = g_object_ref (info);
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (self), TRUE);
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self),
g_markup_escape_text (g_app_info_get_display_name (info), -1));
key = g_utf8_casefold (g_app_info_get_display_name (info), -1);
self->sortkey = g_utf8_collate_key (key, -1);
icon = g_app_info_get_icon (info);
if (icon != NULL)
g_object_ref (icon);
gtk_image_set_from_gicon (GTK_IMAGE (self->image), g_app_info_get_icon (info));
else
icon = g_themed_icon_new ("application-x-executable");
w = gtk_image_new_from_gicon (icon);
gtk_style_context_add_class (gtk_widget_get_style_context (w), "lowres-icon");
gtk_image_set_icon_size (GTK_IMAGE (w), GTK_ICON_SIZE_LARGE);
adw_action_row_add_prefix (ADW_ACTION_ROW (self), w);
gtk_image_set_from_icon_name (GTK_IMAGE (self->image), "application-x-executable");
gtk_label_set_label (GTK_LABEL (self->label), g_app_info_get_display_name (info));
return self;
}
@@ -93,3 +100,9 @@ cc_applications_row_get_info (CcApplicationsRow *self)
{
return self->info;
}
const gchar *
cc_applications_row_get_sort_key (CcApplicationsRow *self)
{
return self->sortkey;
}

View File

@@ -21,15 +21,16 @@
#pragma once
#include <gtk/gtk.h>
#include <adwaita.h>
G_BEGIN_DECLS
#define CC_TYPE_APPLICATIONS_ROW (cc_applications_row_get_type())
G_DECLARE_FINAL_TYPE (CcApplicationsRow, cc_applications_row, CC, APPLICATIONS_ROW, AdwActionRow)
G_DECLARE_FINAL_TYPE (CcApplicationsRow, cc_applications_row, CC, APPLICATIONS_ROW, GtkListBoxRow)
CcApplicationsRow* cc_applications_row_new (GAppInfo *info);
GAppInfo* cc_applications_row_get_info (CcApplicationsRow *row);
const gchar* cc_applications_row_get_sort_key (CcApplicationsRow *row);
G_END_DECLS

View File

@@ -1,12 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="CcApplicationsRow" parent="AdwActionRow">
<child type="suffix">
<object class="GtkImage">
<property name="icon-name">go-next-symbolic</property>
<template class="CcApplicationsRow" parent="GtkListBoxRow">
<child>
<object class="GtkBox" id="box">
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="spacing">12</property>
<child>
<object class="GtkImage" id="image">
<property name="pixel-size">32</property>
<style>
<class name="lowres-icon"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="xalign">0</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="CcDefaultAppsPage" parent="AdwPreferencesGroup">
<property name="title" translatable="yes">Default Apps</property>
<child>
<object class="CcDefaultAppsRow" id="web_row">
<property name="title" translatable="yes">_Web</property>
<property name="use-underline">True</property>
<property name="content-type">x-scheme-handler/http</property>
<property name="filters">text/html;application/xhtml+xml;x-scheme-handler/https</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="mail_row">
<property name="title" translatable="yes">_Mail</property>
<property name="use_underline">True</property>
<property name="content-type">x-scheme-handler/mailto</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="calendar_row">
<property name="title" translatable="yes">_Calendar</property>
<property name="use-underline">True</property>
<property name="content-type">text/calendar</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="music_row">
<property name="title" translatable="yes">M_usic</property>
<property name="use-underline">True</property>
<property name="content-type">audio/x-vorbis+ogg</property>
<property name="filters">audio/*</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="video_row">
<property name="title" translatable="yes">_Video</property>
<property name="use-underline">True</property>
<property name="content-type">video/x-ogm+ogg</property>
<property name="filters">video/*</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="photos_row">
<property name="title" translatable="yes">_Photos</property>
<property name="use-underline">True</property>
<property name="content-type">image/jpeg</property>
<property name="filters">image/*</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="calls_row">
<property name="visible">False</property>
<property name="title" translatable="yes" comments="Translators: This is a telephone call">Ca_lls</property>
<property name="use-underline">True</property>
<property name="content-type">x-scheme-handler/tel</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
<child>
<object class="CcDefaultAppsRow" id="sms_row">
<property name="visible">False</property>
<property name="title" translatable="yes">_SMS</property>
<property name="use-underline">True</property>
<property name="content-type">x-scheme-handler/sms</property>
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
</object>
</child>
</template>
</interface>

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="CcInfoRow" parent="AdwActionRow">
<property name="use-underline">True</property>
<child>
<object class="GtkLabel" id="info">
<property name="valign">center</property>

View File

@@ -1,167 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<template class="CcRemovableMediaSettings" parent="AdwPreferencesGroup">
<child>
<object class="AdwActionRow" id="cd_audio_row">
<property name="title" translatable="yes">CD _Audio</property>
<property name="use_underline">True</property>
<property name="activatable_widget">audio_cdda_chooser</property>
<child>
<object class="GtkAppChooserButton" id="audio_cdda_chooser">
<property name="valign">center</property>
<property name="content_type">x-content/audio-cdda</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="dvd_video_row">
<property name="title" translatable="yes">_DVD Video</property>
<property name="use_underline">True</property>
<property name="activatable_widget">video_dvd_chooser</property>
<child>
<object class="GtkAppChooserButton" id="video_dvd_chooser">
<property name="valign">center</property>
<property name="content_type">x-content/video-dvd</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="music_player_row">
<property name="title" translatable="yes">Music Pla_yer</property>
<property name="use_underline">True</property>
<property name="activatable_widget">music_player_chooser</property>
<child>
<object class="GtkAppChooserButton" id="music_player_chooser">
<property name="valign">center</property>
<property name="content_type">x-content/audio-player</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="photos_row">
<property name="title" translatable="yes">P_hotos</property>
<property name="use_underline">True</property>
<property name="activatable_widget">dcf_chooser</property>
<child>
<object class="GtkAppChooserButton" id="dcf_chooser">
<property name="valign">center</property>
<property name="content_type">x-content/image-dcf</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="software_row">
<property name="title" translatable="yes">Sof_tware</property>
<property name="use_underline">True</property>
<property name="activatable_widget">software_chooser</property>
<child>
<object class="GtkAppChooserButton" id="software_chooser">
<property name="valign">center</property>
<property name="content_type">x-content/unix-software</property>
</object>
</child>
</object>
</child>
<child>
<object class="CcListRow" id="other_media_row">
<property name="title" translatable="yes">_Other Media</property>
<property name="show-arrow">True</property>
<property name="subtitle" translatable="yes">Select how other media should be handled</property>
<signal name="activated" handler="on_extra_options_button_clicked" object="CcRemovableMediaSettings"/>
</object>
</child>
</template>
<object class="GtkSizeGroup">
<widgets>
<widget name="audio_cdda_chooser"/>
<widget name="video_dvd_chooser"/>
<widget name="music_player_chooser"/>
<widget name="dcf_chooser"/>
<widget name="software_chooser"/>
</widgets>
</object>
<object class="AdwWindow" id="other_type_dialog">
<property name="title" translatable="yes">Other Media</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="hide-on-close">True</property>
<property name="width-request">360</property>
<property name="height-request">294</property>
<property name="default-width">360</property>
<property name="default-height">294</property>
<signal name="close-request" handler="on_extra_options_dialog_close_request" object="CcRemovableMediaSettings" swapped="yes"/>
<child>
<object class="GtkShortcutController">
<property name="scope">managed</property>
<child>
<object class="GtkShortcut">
<property name="trigger">Escape</property>
<property name="action">action(window.close)</property>
</object>
</child>
</object>
</child>
<property name="content">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<property name="content">
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">_Type</property>
<property name="use-underline">True</property>
<property name="activatable-widget">other_type_combo_box</property>
<child>
<object class="GtkComboBox" id="other_type_combo_box">
<property name="model">other_type_list_store</property>
<property name="valign">center</property>
<signal name="changed" handler="on_other_type_combo_box_changed" object="CcRemovableMediaSettings" swapped="yes"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="other_action_row">
<property name="title" translatable="yes">_Action</property>
<property name="use-underline">True</property>
<child>
<object class="GtkBox" id="other_action_box">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
<object class="GtkListStore" id="other_type_list_store">
<columns>
<!-- column-name description -->
<column type="gchararray"/>
<!-- column-name content-type -->
<column type="gchararray"/>
</columns>
</object>
</interface>

View File

@@ -23,39 +23,37 @@
#include "cc-snap-row.h"
#include "cc-applications-resources.h"
#include "cc-snapd-client.h"
#define CHANGE_POLL_TIME 100
struct _CcSnapRow
{
AdwActionRow parent;
GtkSwitch *slot_toggle;
GtkComboBox *slots_combo;
GtkListStore *slots_combo_model;
GtkSwitch *slot_toggle;
GtkComboBox *slots_combo;
GtkListStore *slots_combo_model;
GCancellable *cancellable;
GCancellable *cancellable;
CcSnapdClient *client;
JsonObject *plug;
JsonObject *connected_slot;
JsonArray *slots;
JsonObject *target_slot;
gchar *change_id;
guint change_timeout;
SnapdPlug *plug;
SnapdSlot *connected_slot;
GPtrArray *slots;
};
G_DEFINE_TYPE (CcSnapRow, cc_snap_row, ADW_TYPE_ACTION_ROW)
typedef struct
{
CcSnapRow *self;
SnapdSlot *slot;
} ConnectData;
static void
update_state (CcSnapRow *self)
{
gboolean have_single_option;
GtkTreeIter iter;
have_single_option = json_array_get_length (self->slots) == 1;
have_single_option = self->slots->len == 1;
gtk_widget_set_visible (GTK_WIDGET (self->slot_toggle), have_single_option);
gtk_widget_set_visible (GTK_WIDGET (self->slots_combo), !have_single_option);
@@ -65,7 +63,7 @@ update_state (CcSnapRow *self)
{
do
{
JsonObject *slot;
SnapdSlot *slot;
gtk_tree_model_get (GTK_TREE_MODEL (self->slots_combo_model), &iter, 0, &slot, -1);
if (slot == self->connected_slot)
@@ -88,111 +86,96 @@ enable_controls (CcSnapRow *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->slots_combo), TRUE);
}
static void
change_complete (CcSnapRow *self)
static ConnectData *
connect_data_new (CcSnapRow *self, SnapdSlot *slot)
{
g_clear_object (&self->client);
g_clear_pointer (&self->target_slot, json_object_unref);
g_clear_pointer (&self->change_id, g_free);
g_clear_handle_id (&self->change_timeout, g_source_remove);
ConnectData *data;
data = g_new0 (ConnectData, 1);
data->self = self;
data->slot = g_object_ref (slot);
return data;
}
static void
connect_data_free (ConnectData *data)
{
g_clear_object (&data->slot);
g_free (data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ConnectData, connect_data_free)
static void
connect_interface_cb (GObject *client, GAsyncResult *result, gpointer user_data)
{
g_autoptr(ConnectData) data = user_data;
CcSnapRow *self = data->self;
SnapdSlot *slot = data->slot;
g_autoptr(GError) error = NULL;
if (snapd_client_connect_interface_finish (SNAPD_CLIENT (client), result, &error))
{
g_clear_object (&self->connected_slot);
self->connected_slot = g_object_ref (slot);
}
else
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_warning ("Failed to connect interface: %s", error->message);
}
update_state (self);
enable_controls (self);
}
static gboolean
poll_change_cb (gpointer user_data)
{
CcSnapRow *self = user_data;
g_autoptr(JsonObject) change = NULL;
g_autoptr(GError) error = NULL;
change = cc_snapd_client_get_change_sync (self->client, self->change_id, self->cancellable, &error);
if (change == NULL)
{
g_warning ("Failed to monitor change %s: %s", self->change_id, error->message);
change_complete (self);
return G_SOURCE_REMOVE;
}
if (json_object_get_boolean_member (change, "ready"))
{
const gchar *status = json_object_get_string_member (change, "status");
if (g_strcmp0 (status, "Done") == 0)
{
g_clear_pointer (&self->connected_slot, json_object_unref);
self->connected_slot = self->target_slot ? json_object_ref (self->target_slot) : NULL;
}
else
{
g_warning ("Change completed with status %s", status);
}
change_complete (self);
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}
static void
monitor_change (CcSnapRow *self, const gchar *change_id)
connect_plug (CcSnapRow *self, SnapdSlot *slot)
{
g_free (self->change_id);
self->change_id = g_strdup (change_id);
g_clear_handle_id (&self->change_timeout, g_source_remove);
self->change_timeout = g_timeout_add (CHANGE_POLL_TIME, poll_change_cb, self);
}
static CcSnapdClient *
get_client(CcSnapRow *self)
{
if (self->client == NULL)
self->client = cc_snapd_client_new ();
return self->client;
}
static void
connect_plug (CcSnapRow *self, JsonObject *slot)
{
g_autofree gchar *change_id = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(SnapdClient) client = NULL;
/* already connected */
if (self->connected_slot != NULL &&
g_strcmp0 (json_object_get_string_member (self->connected_slot, "snap"),
json_object_get_string_member (slot, "snap")) == 0 &&
g_strcmp0 (json_object_get_string_member (self->connected_slot, "slot"),
json_object_get_string_member (slot, "slot")) == 0)
if (self->connected_slot == slot)
return;
disable_controls (self);
change_id = cc_snapd_client_connect_interface_sync (get_client (self),
json_object_get_string_member (self->plug, "snap"),
json_object_get_string_member (self->plug, "plug"),
json_object_get_string_member (slot, "snap"),
json_object_get_string_member (slot, "slot"),
self->cancellable,
&error);
if (change_id == NULL)
client = snapd_client_new ();
snapd_client_connect_interface_async (client,
snapd_plug_get_snap (self->plug), snapd_plug_get_name (self->plug),
snapd_slot_get_snap (slot), snapd_slot_get_name (slot),
NULL, NULL,
self->cancellable,
connect_interface_cb, connect_data_new (self, slot));
}
static void
disconnect_interface_cb (GObject *client, GAsyncResult *result, gpointer user_data)
{
CcSnapRow *self = user_data;
g_autoptr(GError) error = NULL;
if (snapd_client_disconnect_interface_finish (SNAPD_CLIENT (client), result, &error))
{
g_warning ("Failed to connect plug: %s", error->message);
change_complete (self);
return;
g_clear_object (&self->connected_slot);
}
else
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_warning ("Failed to disconnect interface: %s", error->message);
}
g_clear_pointer (&self->target_slot, json_object_unref);
self->target_slot = json_object_ref (slot);
monitor_change (self, change_id);
update_state (self);
enable_controls (self);
}
static void
disconnect_plug (CcSnapRow *self)
{
g_autofree gchar *change_id = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(SnapdClient) client = NULL;
/* already disconnected */
if (self->connected_slot == NULL)
@@ -200,20 +183,13 @@ disconnect_plug (CcSnapRow *self)
disable_controls (self);
change_id = cc_snapd_client_disconnect_interface_sync (get_client (self),
json_object_get_string_member (self->plug, "snap"),
json_object_get_string_member (self->plug, "plug"),
"", "",
self->cancellable, &error);
if (change_id == NULL)
{
g_warning ("Failed to disconnect plug: %s", error->message);
change_complete (self);
return;
}
g_clear_pointer (&self->target_slot, json_object_unref);
monitor_change (self, change_id);
client = snapd_client_new ();
snapd_client_disconnect_interface_async (client,
snapd_plug_get_snap (self->plug), snapd_plug_get_name (self->plug),
NULL, NULL,
NULL, NULL,
self->cancellable,
disconnect_interface_cb, self);
}
static void
@@ -221,8 +197,8 @@ switch_changed_cb (CcSnapRow *self)
{
if (gtk_switch_get_active (self->slot_toggle))
{
if (json_array_get_length (self->slots) == 1)
connect_plug (self, json_array_get_object_element (self->slots, 0));
if (self->slots->len == 1)
connect_plug (self, g_ptr_array_index (self->slots, 0));
}
else
{
@@ -234,7 +210,7 @@ static void
combo_changed_cb (CcSnapRow *self)
{
GtkTreeIter iter;
JsonObject *slot = NULL;
SnapdSlot *slot = NULL;
if (!gtk_combo_box_get_active_iter (self->slots_combo, &iter))
return;
@@ -246,134 +222,14 @@ combo_changed_cb (CcSnapRow *self)
disconnect_plug (self);
}
static const gchar *
make_interface_label (const gchar *interface_name)
{
if (strcmp (interface_name, "account-control") == 0)
return _("Add user accounts and change passwords");
else if (strcmp (interface_name, "alsa") == 0)
return _("Play and record sound");
else if (strcmp (interface_name, "audio-playback") == 0)
return _("Play audio");
else if (strcmp (interface_name, "audio-record") == 0)
return _("Record audio");
else if (strcmp (interface_name, "avahi-observe") == 0)
return _("Detect network devices using mDNS/DNS-SD (Bonjour/zeroconf)");
else if (strcmp (interface_name, "bluetooth-control") == 0)
return _("Access bluetooth hardware directly");
else if (strcmp (interface_name, "bluez") == 0)
return _("Use bluetooth devices");
else if (strcmp (interface_name, "camera") == 0)
return _("Use your camera");
else if (strcmp (interface_name, "cups-control") == 0)
return _("Print documents");
else if (strcmp (interface_name, "joystick") == 0)
return _("Use any connected joystick");
else if (strcmp (interface_name, "docker") == 0)
return _("Allow connecting to the Docker service");
else if (strcmp (interface_name, "firewall-control") == 0)
return _("Configure network firewall");
else if (strcmp (interface_name, "fuse-support") == 0)
return _("Setup and use privileged FUSE filesystems");
else if (strcmp (interface_name, "fwupd") == 0)
return _("Update firmware on this device");
else if (strcmp (interface_name, "hardware-observe") == 0)
return _("Access hardware information");
else if (strcmp (interface_name, "hardware-random-control") == 0)
return _("Provide entropy to hardware random number generator");
else if (strcmp (interface_name, "hardware-random-observe") == 0)
return _("Use hardware-generated random numbers");
else if (strcmp (interface_name, "home") == 0)
return _("Access files in your home folder");
else if (strcmp (interface_name, "libvirt") == 0)
return _("Access libvirt service");
else if (strcmp (interface_name, "locale-control") == 0)
return _("Change system language and region settings");
else if (strcmp (interface_name, "location-control") == 0)
return _("Change location settings and providers");
else if (strcmp (interface_name, "location-observe") == 0)
return _("Access your location");
else if (strcmp (interface_name, "log-observe") == 0)
return _("Read system and application logs");
else if (strcmp (interface_name, "lxd") == 0)
return _("Access LXD service");
else if (strcmp (interface_name, "modem-manager") == 0)
return _("Use and configure modems");
else if (strcmp (interface_name, "mount-observe") == 0)
return _("Read system mount information and disk quotas");
else if (strcmp (interface_name, "mpris") == 0)
return _("Control music and video players");
else if (strcmp (interface_name, "network-control") == 0)
return _("Change low-level network settings");
else if (strcmp (interface_name, "network-manager") == 0)
return _("Access the NetworkManager service to read and change network settings");
else if (strcmp (interface_name, "network-observe") == 0)
return _("Read access to network settings");
else if (strcmp (interface_name, "network-setup-control") == 0)
return _("Change network settings");
else if (strcmp (interface_name, "network-setup-observe") == 0)
return _("Read network settings");
else if (strcmp (interface_name, "ofono") == 0)
return _("Access the ofono service to read and change network settings for mobile telephony");
else if (strcmp (interface_name, "openvswitch") == 0)
return _("Control Open vSwitch hardware");
else if (strcmp (interface_name, "optical-drive") == 0)
return _("Read from CD/DVD");
else if (strcmp (interface_name, "password-manager-service") == 0)
return _("Read, add, change, or remove saved passwords");
else if (strcmp (interface_name, "ppp") == 0)
return _("Access pppd and ppp devices for configuring Point-to-Point Protocol connections");
else if (strcmp (interface_name, "process-control") == 0)
return _("Pause or end any process on the system");
else if (strcmp (interface_name, "pulseaudio") == 0)
return _("Play and record sound");
else if (strcmp (interface_name, "raw-usb") == 0)
return _("Access USB hardware directly");
else if (strcmp (interface_name, "removable-media") == 0)
return _("Read/write files on removable storage devices");
else if (strcmp (interface_name, "screen-inhibit-control") == 0)
return _("Prevent screen sleep/lock");
else if (strcmp (interface_name, "serial-port") == 0)
return _("Access serial port hardware");
else if (strcmp (interface_name, "shutdown") == 0)
return _("Restart or power off the device");
else if (strcmp (interface_name, "snapd-control") == 0)
return _("Install, remove and configure software");
else if (strcmp (interface_name, "storage-framework-service") == 0)
return _("Access Storage Framework service");
else if (strcmp (interface_name, "system-observe") == 0)
return _("Read process and system information");
else if (strcmp (interface_name, "system-trace") == 0)
return _("Monitor and control any running program");
else if (strcmp (interface_name, "time-control") == 0)
return _("Change the date and time");
else if (strcmp (interface_name, "timeserver-control") == 0)
return _("Change time server settings");
else if (strcmp (interface_name, "timezone-control") == 0)
return _("Change the time zone");
else if (strcmp (interface_name, "udisks2") == 0)
return _("Access the UDisks2 service for configuring disks and removable media");
else if (strcmp (interface_name, "upower-observe") == 0)
return _("Access energy usage data");
else if (strcmp (interface_name, "u2f-devices") == 0)
return _("Read/write access to U2F devices exposed");
else
return interface_name;
}
static void
cc_snap_row_finalize (GObject *object)
{
CcSnapRow *self = CC_SNAP_ROW (object);
g_clear_object (&self->cancellable);
g_clear_object (&self->client);
g_clear_pointer (&self->plug, json_object_unref);
g_clear_pointer (&self->slots, json_array_unref);
g_clear_pointer (&self->target_slot, json_object_unref);
g_clear_pointer (&self->change_id, g_free);
g_clear_handle_id (&self->change_timeout, g_source_remove);
self->change_timeout = 0;
g_clear_object (&self->plug);
g_clear_pointer (&self->slots, g_ptr_array_unref);
G_OBJECT_CLASS (cc_snap_row_parent_class)->finalize (object);
}
@@ -403,48 +259,51 @@ cc_snap_row_init (CcSnapRow *self)
}
CcSnapRow *
cc_snap_row_new (GCancellable *cancellable, JsonObject *plug, JsonArray *slots)
cc_snap_row_new (GCancellable *cancellable, SnapdInterface *interface, SnapdPlug *plug, GPtrArray *slots)
{
CcSnapRow *self;
const gchar *label = NULL;
GPtrArray *connected_slots;
g_autofree gchar *label = NULL;
GtkTreeIter iter;
g_return_val_if_fail (SNAPD_IS_PLUG (plug), NULL);
self = CC_SNAP_ROW (g_object_new (CC_TYPE_SNAP_ROW, NULL));
self->cancellable = g_object_ref (cancellable);
self->plug = json_object_ref (plug);
self->slots = json_array_ref (slots);
self->plug = g_object_ref (plug);
self->slots = g_ptr_array_ref (slots);
if (json_object_has_member (plug, "connections"))
connected_slots = snapd_plug_get_connected_slots (plug);
if (connected_slots->len > 0)
{
JsonArray *connected_slots = json_object_get_array_member (plug, "connections");
JsonObject *connected_slot_ref = json_array_get_object_element (connected_slots, 0);
SnapdSlotRef *connected_slot_ref = g_ptr_array_index (connected_slots, 0);
for (guint i = 0; i < json_array_get_length (slots); i++)
for (int i = 0; i < slots->len; i++)
{
JsonObject *slot = json_array_get_object_element (slots, i);
SnapdSlot *slot = g_ptr_array_index (slots, i);
if (g_strcmp0 (json_object_get_string_member (slot, "snap"),
json_object_get_string_member (connected_slot_ref, "snap")) == 0 &&
g_strcmp0 (json_object_get_string_member (slot, "slot"),
json_object_get_string_member (connected_slot_ref, "slot")) == 0)
if (g_strcmp0 (snapd_slot_get_snap (slot), snapd_slot_ref_get_snap (connected_slot_ref)) == 0 &&
g_strcmp0 (snapd_slot_get_name (slot), snapd_slot_ref_get_slot (connected_slot_ref)) == 0)
self->connected_slot = slot;
}
}
label = make_interface_label (json_object_get_string_member (plug, "interface"));
if (interface != NULL)
label = snapd_interface_make_label (interface);
else
label = g_strdup (snapd_plug_get_interface (plug));
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self), label);
/* Add option into combo box */
gtk_list_store_append (self->slots_combo_model, &iter);
gtk_list_store_set (self->slots_combo_model, &iter, 1, "--", -1);
for (guint i = 0; i < json_array_get_length (slots); i++)
for (int i = 0; i < slots->len; i++)
{
JsonObject *slot = json_array_get_object_element (slots, i);
SnapdSlot *slot = g_ptr_array_index (slots, i);
g_autofree gchar *label = NULL;
label = g_strdup_printf ("%s:%s", json_object_get_string_member (slot, "snap"),
json_object_get_string_member (slot, "slot"));
label = g_strdup_printf ("%s:%s", snapd_slot_get_snap (slot), snapd_slot_get_name (slot));
gtk_list_store_append (self->slots_combo_model, &iter);
gtk_list_store_set (self->slots_combo_model, &iter, 0, slot, 1, label, -1);
}

View File

@@ -21,7 +21,7 @@
#pragma once
#include <adwaita.h>
#include <json-glib/json-glib.h>
#include <snapd-glib/snapd-glib.h>
G_BEGIN_DECLS
@@ -29,7 +29,8 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CcSnapRow, cc_snap_row, CC, SNAP_ROW, AdwActionRow)
CcSnapRow* cc_snap_row_new (GCancellable *cancellable,
JsonObject *plug,
JsonArray *slots);
SnapdInterface *interface,
SnapdPlug *plug,
GPtrArray *slots);
G_END_DECLS

View File

@@ -3,7 +3,7 @@
<object class="GtkListStore" id="slots_combo_model">
<columns>
<!-- column-name slot -->
<column type="JsonObject"/>
<column type="GObject"/>
<!-- column-name label -->
<column type="gchararray"/>
</columns>

View File

@@ -1,290 +0,0 @@
/* cc-snapd-client.c
*
* Copyright 2023 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <libsoup/soup.h>
#include "cc-snapd-client.h"
// Unix socket that snapd communicates on.
#define SNAPD_SOCKET_PATH "/var/run/snapd.socket"
struct _CcSnapdClient
{
GObject parent;
// HTTP connection to snapd.
SoupSession *session;
};
G_DEFINE_TYPE (CcSnapdClient, cc_snapd_client, G_TYPE_OBJECT)
// Make an HTTP request to send to snapd.
static SoupMessage *
make_message (const gchar *method, const gchar *path, JsonNode *request_body)
{
g_autofree gchar *uri = NULL;
SoupMessage *msg;
SoupMessageHeaders *request_headers;
uri = g_strdup_printf("http://locahost%s", path);
msg = soup_message_new (method, uri);
request_headers = soup_message_get_request_headers (msg);
// Allow authentication via polkit.
soup_message_headers_append (request_headers, "X-Allow-Interaction", "true");
if (request_body != NULL)
{
g_autoptr(JsonGenerator) generator = NULL;
g_autofree gchar *body_text = NULL;
gsize body_length;
g_autoptr(GBytes) body_bytes = NULL;
generator = json_generator_new ();
json_generator_set_root (generator, request_body);
body_text = json_generator_to_data (generator, &body_length);
body_bytes = g_bytes_new (body_text, body_length);
soup_message_set_request_body_from_bytes (msg, "application/json", body_bytes);
}
return msg;
}
// Process an HTTP response recveived from snapd.
static JsonObject *
process_body (SoupMessage *msg, GBytes *body, GError **error)
{
const gchar *content_type;
g_autoptr(JsonParser) parser = NULL;
const gchar *body_data;
size_t body_length;
JsonNode *root;
JsonObject *response;
gint64 status_code;
g_autoptr(GError) internal_error = NULL;
content_type = soup_message_headers_get_one (soup_message_get_response_headers (msg), "Content-Type");
if (g_strcmp0 (content_type, "application/json") != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid content type %s returned", content_type);
return NULL;
}
parser = json_parser_new ();
body_data = g_bytes_get_data (body, &body_length);
if (!json_parser_load_from_data (parser, body_data, body_length, &internal_error))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to decode JSON content: %s", internal_error->message);
return NULL;
}
root = json_parser_get_root (parser);
if (!JSON_NODE_HOLDS_OBJECT (root))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Returned JSON not an object");
return NULL;
}
response = json_node_get_object (root);
status_code = json_object_get_int_member (response, "status-code");
if (status_code != SOUP_STATUS_OK && status_code != SOUP_STATUS_ACCEPTED)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid status code %" G_GINT64_FORMAT, status_code);
return NULL;
}
return json_object_ref (response);
}
// Send an HTTP request to snapd and process the response.
static JsonObject *
call_sync (CcSnapdClient *self,
const gchar *method, const gchar *path, JsonNode *request_body,
GCancellable *cancellable, GError **error)
{
g_autoptr(SoupMessage) msg = NULL;
g_autoptr(GBytes) response_body = NULL;
msg = make_message (method, path, request_body);
response_body = soup_session_send_and_read (self->session, msg, cancellable, error);
if (response_body == NULL)
return NULL;
return process_body (msg, response_body, error);
}
// Perform a snap interface action.
static gchar *
call_interfaces_sync (CcSnapdClient *self,
const gchar *action,
const gchar *plug_snap, const gchar *plug_name,
const gchar *slot_snap, const gchar *slot_name,
GCancellable *cancellable, GError **error)
{
g_autoptr(JsonBuilder) builder = NULL;
g_autoptr(JsonObject) response = NULL;
const gchar *change_id;
builder = json_builder_new();
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "action");
json_builder_add_string_value (builder, action);
json_builder_set_member_name (builder, "plugs");
json_builder_begin_array (builder);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "snap");
json_builder_add_string_value (builder, plug_snap);
json_builder_set_member_name (builder, "plug");
json_builder_add_string_value (builder, plug_name);
json_builder_end_object (builder);
json_builder_end_array (builder);
json_builder_set_member_name (builder, "slots");
json_builder_begin_array (builder);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "snap");
json_builder_add_string_value (builder, slot_snap);
json_builder_set_member_name (builder, "slot");
json_builder_add_string_value (builder, slot_name);
json_builder_end_object (builder);
json_builder_end_array (builder);
json_builder_end_object (builder);
response = call_sync (self, "POST", "/v2/interfaces",
json_builder_get_root (builder), cancellable, error);
if (response == NULL)
return NULL;
change_id = json_object_get_string_member (response, "change");
return g_strdup (change_id);
}
static void
cc_snapd_client_dispose (GObject *object)
{
CcSnapdClient *self = CC_SNAPD_CLIENT (object);
g_clear_object(&self->session);
G_OBJECT_CLASS (cc_snapd_client_parent_class)->dispose (object);
}
static void
cc_snapd_client_class_init (CcSnapdClientClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = cc_snapd_client_dispose;
}
static void
cc_snapd_client_init (CcSnapdClient *self)
{
g_autoptr(GSocketAddress) address = g_unix_socket_address_new (SNAPD_SOCKET_PATH);
self->session = soup_session_new_with_options ("remote-connectable", address, NULL);
}
CcSnapdClient *
cc_snapd_client_new (void)
{
return CC_SNAPD_CLIENT (g_object_new (CC_TYPE_SNAPD_CLIENT, NULL));
}
JsonObject *
cc_snapd_client_get_snap_sync (CcSnapdClient *self, const gchar *name, GCancellable *cancellable, GError **error)
{
g_autofree gchar *path = NULL;
g_autoptr(JsonObject) response = NULL;
JsonObject *result;
path = g_strdup_printf ("/v2/snaps/%s", name);
response = call_sync (self, "GET", path, NULL, cancellable, error);
if (response == NULL)
return NULL;
result = json_object_get_object_member (response, "result");
if (result == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid response to %s", path);
return NULL;
}
return json_object_ref (result);
}
JsonObject *
cc_snapd_client_get_change_sync (CcSnapdClient *self, const gchar *change_id, GCancellable *cancellable, GError **error)
{
g_autofree gchar *path = NULL;
g_autoptr(JsonObject) response = NULL;
JsonObject *result;
path = g_strdup_printf ("/v2/changes/%s", change_id);
response = call_sync (self, "GET", path, NULL, cancellable, error);
if (response == NULL)
return NULL;
result = json_object_get_object_member (response, "result");
if (result == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid response to %s", path);
return NULL;
}
return json_object_ref (result);
}
gboolean
cc_snapd_client_get_all_connections_sync (CcSnapdClient *self,
JsonArray **plugs, JsonArray **slots,
GCancellable *cancellable, GError **error)
{
g_autoptr(JsonObject) response = NULL;
JsonObject *result;
response = call_sync (self, "GET", "/v2/connections?select=all", NULL, cancellable, error);
if (response == NULL)
return FALSE;
result = json_object_get_object_member (response, "result");
if (result == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid response to /v2/connections");
return FALSE;
}
*plugs = json_array_ref (json_object_get_array_member (result, "plugs"));
*slots = json_array_ref (json_object_get_array_member (result, "slots"));
return TRUE;
}
gchar *
cc_snapd_client_connect_interface_sync (CcSnapdClient *self,
const gchar *plug_snap, const gchar *plug_name,
const gchar *slot_snap, const gchar *slot_name,
GCancellable *cancellable, GError **error)
{
return call_interfaces_sync (self, "connect", plug_snap, plug_name, slot_snap, slot_name, cancellable, error);
}
gchar *
cc_snapd_client_disconnect_interface_sync (CcSnapdClient *self,
const gchar *plug_snap, const gchar *plug_name,
const gchar *slot_snap, const gchar *slot_name,
GCancellable *cancellable, GError **error)
{
return call_interfaces_sync (self, "disconnect", plug_snap, plug_name, slot_snap, slot_name, cancellable, error);
}

View File

@@ -1,70 +0,0 @@
/* cc-snapd-client.h
*
* Copyright 2023 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <json-glib/json-glib.h>
G_BEGIN_DECLS
#define CC_TYPE_SNAPD_CLIENT (cc_snapd_client_get_type())
G_DECLARE_FINAL_TYPE (CcSnapdClient, cc_snapd_client, CC, SNAPD_CLIENT, GObject)
// Creates a client to contact snapd.
CcSnapdClient *cc_snapd_client_new (void);
// Get information on an installed snap.
JsonObject *cc_snapd_client_get_snap_sync (CcSnapdClient *client,
const gchar *name,
GCancellable *cancellable,
GError **error);
// Get information on a snap change.
JsonObject *cc_snapd_client_get_change_sync (CcSnapdClient *client,
const gchar *change_id,
GCancellable *cancellable,
GError **error);
// Get the state of the snap interface connections.
gboolean cc_snapd_client_get_all_connections_sync (CcSnapdClient *client,
JsonArray **plugs,
JsonArray **slots,
GCancellable *cancellable,
GError **error);
// Connect a plug to a slot. Returns the change ID to monitor for completion of this task.
gchar *cc_snapd_client_connect_interface_sync (CcSnapdClient *client,
const gchar *plug_snap,
const gchar *plug_name,
const gchar *slot_snap,
const gchar *slot_name,
GCancellable *cancellable,
GError **error);
// Disconnect a plug to a slot. Returns the change ID to monitor for completion of this task.
gchar *cc_snapd_client_disconnect_interface_sync (CcSnapdClient *client,
const gchar *plug_snap,
const gchar *plug_name,
const gchar *slot_snap,
const gchar *slot_name,
GCancellable *cancellable,
GError **error);
G_END_DECLS

View File

@@ -12,4 +12,5 @@ StartupNotify=true
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-AccountSettings;
OnlyShowIn=GNOME;Unity;
# Translators: Search terms to find the Apps panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
Keywords=application;flatpak;permission;setting;default;preferred;media;autorun;cd;dvd;usb;audio;video;disc;removable;device;system;
Keywords=application;flatpak;permission;setting;
X-GNOME-ControlCenter-HasSidebar=true

View File

@@ -14,37 +14,23 @@ sources = files(
'cc-applications-panel.c',
'cc-applications-row.c',
'cc-info-row.c',
'cc-default-apps-page.c',
'cc-default-apps-row.c',
'cc-removable-media-settings.c',
'globs.c',
'search.c',
'utils.c',
)
resource_data = files(
'cc-applications-panel.ui',
'cc-default-apps-page.ui',
'cc-removable-media-settings.ui',
)
sources += gnome.compile_resources(
'cc-' + cappletname + '-resources',
cappletname + '.gresource.xml',
c_name : 'cc_' + cappletname,
dependencies: resource_data,
export : true
)
deps = common_deps
if host_is_linux
deps += mm_dep
endif
if enable_snap
deps += [ json_glib_dep, libsoup_dep ]
sources += [ 'cc-snap-row.c', 'cc-snapd-client.c' ]
deps += snapd_glib_deps
sources += files('cc-snap-row.c')
endif
if enable_malcontent

View File

@@ -24,15 +24,15 @@
#include <config.h>
#include <glib/gi18n.h>
#ifdef HAVE_SNAP
#include <snapd-glib/snapd-glib.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <ftw.h>
#include "utils.h"
#ifdef HAVE_SNAP
#include "cc-snapd-client.h"
#endif
static gint
ftw_remove_cb (const gchar *path,
@@ -105,7 +105,7 @@ file_size_thread_func (GTask *task,
g_private_replace (&size_key, g_new0 (guint64, 1));
nftw (path, ftw_size_cb, 20, FTW_PHYS | FTW_DEPTH);
nftw (path, ftw_size_cb, 20, FTW_DEPTH);
total = g_new0 (guint64, 1);
*total = *(guint64*)g_private_get (&size_key);
@@ -142,6 +142,15 @@ file_size_finish (GFile *file,
return TRUE;
}
void
listbox_remove_all (GtkListBox *listbox)
{
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (listbox))))
gtk_list_box_remove (listbox, child);
}
static gchar *
get_output_of (const gchar **argv)
{
@@ -227,19 +236,19 @@ guint64
get_snap_app_size (const gchar *snap_name)
{
#ifdef HAVE_SNAP
g_autoptr(CcSnapdClient) client = NULL;
g_autoptr(JsonObject) snap = NULL;
g_autoptr(SnapdClient) client = NULL;
g_autoptr(SnapdSnap) snap = NULL;
g_autoptr(GError) error = NULL;
client = cc_snapd_client_new ();
snap = cc_snapd_client_get_snap_sync (client, snap_name, NULL, &error);
client = snapd_client_new ();
snap = snapd_client_get_snap_sync (client, snap_name, NULL, &error);
if (snap == NULL)
{
g_warning ("Failed to get snap size: %s", error->message);
return 0;
}
return json_object_get_int_member (snap, "installed-size");
return snapd_snap_get_installed_size (snap);
#else
return 0;
#endif

View File

@@ -44,6 +44,8 @@ gboolean file_size_finish (GFile *file,
guint64 *size,
GError **error);
void listbox_remove_all (GtkListBox *listbox);
GKeyFile* get_flatpak_metadata (const gchar *app_id);
guint64 get_flatpak_app_size (const gchar *app_id);

View File

@@ -0,0 +1,219 @@
/* bg-colors-source.c */
/*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#include <config.h>
#include "bg-colors-source.h"
#include "cc-background-item.h"
#include <cairo-gobject.h>
#include <glib/gi18n-lib.h>
#include <gdesktop-enums.h>
struct _BgColorsSource
{
BgSource parent_instance;
};
G_DEFINE_TYPE (BgColorsSource, bg_colors_source, BG_TYPE_SOURCE)
struct {
GDesktopBackgroundShading type;
int orientation;
const char *pcolor;
} items[] = {
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#000000" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#db5d33" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#008094" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#5d479d" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ab2876" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#fad166" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#437740" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#d272c4" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ed9116" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ff89a9" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#7a8aa2" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#888888" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#475b52" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#425265" },
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#7a634b" },
};
static gchar *
get_colors_path (void)
{
return g_build_filename (g_get_user_config_dir (), "gnome-control-center", "backgrounds", "colors.ini", NULL);
}
static char *
get_colors_dir (void)
{
return g_build_filename (g_get_user_config_dir (), "gnome-control-center", "backgrounds", NULL);
}
static void
bg_colors_source_add_color (BgColorsSource *self,
GListStore *store,
const char *color)
{
CcBackgroundItemFlags flags;
g_autoptr(CcBackgroundItem) item = NULL;
item = cc_background_item_new (NULL);
flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
CC_BACKGROUND_ITEM_HAS_SCOLOR |
CC_BACKGROUND_ITEM_HAS_SHADING |
CC_BACKGROUND_ITEM_HAS_PLACEMENT |
CC_BACKGROUND_ITEM_HAS_URI;
/* It does have a URI, it's "none" */
g_object_set (G_OBJECT (item),
"uri", "file:///" DATADIR "/gnome-control-center/pixmaps/noise-texture-light.png",
"primary-color", color,
"secondary-color", color,
"shading", G_DESKTOP_BACKGROUND_SHADING_SOLID,
"placement", G_DESKTOP_BACKGROUND_STYLE_WALLPAPER,
"flags", flags,
NULL);
cc_background_item_load (item, NULL);
/* insert the item into the liststore */
g_list_store_append (store, item);
}
static void
bg_colors_source_constructed (GObject *object)
{
BgColorsSource *self = BG_COLORS_SOURCE (object);
guint i;
GListStore *store;
g_autoptr(GKeyFile) keyfile = NULL;
g_autofree gchar *path = NULL;
G_OBJECT_CLASS (bg_colors_source_parent_class)->constructed (object);
store = bg_source_get_liststore (BG_SOURCE (self));
for (i = 0; i < G_N_ELEMENTS (items); i++)
bg_colors_source_add_color (self, store, items[i].pcolor);
keyfile = g_key_file_new ();
path = get_colors_path ();
if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL))
{
g_auto(GStrv) colors = NULL;
colors = g_key_file_get_string_list (keyfile, "Colors", "custom-colors", NULL, NULL);
for (i = 0; colors != NULL && colors[i] != NULL; i++)
bg_colors_source_add_color (self, store, colors[i]);
}
}
gboolean
bg_colors_source_add (BgColorsSource *self,
GdkRGBA *rgba,
GtkTreeRowReference **ret_row_ref)
{
GListStore *store;
g_autofree gchar *c = NULL;
g_auto(GStrv) colors = NULL;
gsize len;
g_autoptr(GKeyFile) keyfile = NULL;
g_autoptr(GError) error = NULL;
g_autofree gchar *dir = NULL;
g_autofree gchar *path = NULL;
c = g_strdup_printf ("#%02x%02x%02x",
(int)(255*rgba->red),
(int)(255*rgba->green),
(int)(255*rgba->blue));
store = bg_source_get_liststore (BG_SOURCE (self));
bg_colors_source_add_color (self, store, c);
/* Save to the keyfile */
dir = get_colors_dir ();
g_mkdir_with_parents (dir, 0700);
path = get_colors_path ();
colors = NULL;
len = 0;
keyfile = g_key_file_new ();
if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL))
colors = g_key_file_get_string_list (keyfile, "Colors", "custom-colors", &len, NULL);
if (len == 0 && colors != NULL)
g_clear_pointer (&colors, g_strfreev);
if (colors == NULL)
{
colors = g_new0 (char *, 2);
colors[0] = g_steal_pointer (&c);
len = 1;
}
else
{
char **new_colors;
guint i;
new_colors = g_new0 (char *, len + 2);
for (i = 0; colors[i] != NULL; i++)
{
new_colors[i] = colors[i];
colors[i] = NULL;
}
new_colors[len] = g_steal_pointer (&c);
len++;
g_strfreev (colors);
colors = new_colors;
}
g_key_file_set_string_list (keyfile, "Colors", "custom-colors", (const gchar * const*) colors, len);
if (!g_key_file_save_to_file (keyfile, path, &error))
g_warning ("Could not save custom color: %s", error->message);
return TRUE;
}
static void
bg_colors_source_init (BgColorsSource *self)
{
}
static void
bg_colors_source_class_init (BgColorsSourceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = bg_colors_source_constructed;
}
BgColorsSource *
bg_colors_source_new (GtkWidget *widget)
{
return g_object_new (BG_TYPE_COLORS_SOURCE, "widget", widget, NULL);
}

View File

@@ -1,6 +1,6 @@
/* cc-wacom-stylus-action-dialog.h
*
* Copyright © 2024 Red Hat, Inc.
/* bg-colors-source.h */
/*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,22 +15,24 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-2.0-or-later
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#pragma once
#include <adwaita.h>
#include <gtk/gtk.h>
#include "bg-source.h"
G_BEGIN_DECLS
#define CC_TYPE_WACOM_STYLUS_ACTION_DIALOG (cc_wacom_stylus_action_dialog_get_type ())
#define BG_TYPE_COLORS_SOURCE (bg_colors_source_get_type ())
G_DECLARE_FINAL_TYPE (BgColorsSource, bg_colors_source, BG, COLORS_SOURCE, BgSource)
G_DECLARE_FINAL_TYPE (CcWacomStylusActionDialog, cc_wacom_stylus_action_dialog, CC, WACOM_STYLUS_ACTION_DIALOG, AdwWindow)
BgColorsSource *bg_colors_source_new (GtkWidget *widget);
GtkWidget* cc_wacom_stylus_action_dialog_new (GSettings *settings,
const char *stylus_name,
guint button,
const char *key);
gboolean bg_colors_source_add (BgColorsSource *self,
GdkRGBA *rgba,
GtkTreeRowReference **ret_row_ref);
G_END_DECLS

View File

@@ -396,9 +396,11 @@ bg_recent_source_init (BgRecentSource *self)
}
BgRecentSource*
bg_recent_source_new (void)
bg_recent_source_new (GtkWidget *widget)
{
return g_object_new (BG_TYPE_RECENT_SOURCE, NULL);
return g_object_new (BG_TYPE_RECENT_SOURCE,
"widget", widget,
NULL);
}
void

View File

@@ -28,7 +28,7 @@ G_BEGIN_DECLS
#define BG_TYPE_RECENT_SOURCE (bg_recent_source_get_type())
G_DECLARE_FINAL_TYPE (BgRecentSource, bg_recent_source, BG, RECENT_SOURCE, BgSource)
BgRecentSource* bg_recent_source_new (void);
BgRecentSource* bg_recent_source_new (GtkWidget *widget);
void bg_recent_source_add_file (BgRecentSource *self,
const gchar *path);

View File

@@ -23,19 +23,55 @@
#include <cairo-gobject.h>
#define THUMBNAIL_WIDTH 144
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
typedef struct
{
GnomeDesktopThumbnailFactory *thumbnail_factory;
GListStore *store;
GtkWidget *widget;
gint thumbnail_height;
gint thumbnail_width;
} BgSourcePrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (BgSource, bg_source, G_TYPE_OBJECT)
enum
{
PROP_0,
PROP_LISTSTORE
PROP_LISTSTORE = 1,
PROP_WIDGET
};
static void
bg_source_calculate_thumbnail_dimensions (BgSource *source)
{
BgSourcePrivate *priv = bg_source_get_instance_private (source);
gint scale_factor;
priv->thumbnail_height = THUMBNAIL_HEIGHT;
priv->thumbnail_width = THUMBNAIL_WIDTH;
if (priv->widget == NULL)
return;
scale_factor = gtk_widget_get_scale_factor (priv->widget);
if (scale_factor > 1)
{
priv->thumbnail_height *= scale_factor;
priv->thumbnail_width *= scale_factor;
}
}
static void
bg_source_constructed (GObject *object)
{
G_OBJECT_CLASS (bg_source_parent_class)->constructed (object);
bg_source_calculate_thumbnail_dimensions (BG_SOURCE (object));
}
static void
bg_source_get_property (GObject *object,
guint property_id,
@@ -55,12 +91,33 @@ bg_source_get_property (GObject *object,
}
}
static void
bg_source_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
BgSource *source = BG_SOURCE (object);
BgSourcePrivate *priv = bg_source_get_instance_private (source);
switch (property_id)
{
case PROP_WIDGET:
priv->widget = GTK_WIDGET (g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
bg_source_dispose (GObject *object)
{
BgSource *source = BG_SOURCE (object);
BgSourcePrivate *priv = bg_source_get_instance_private (source);
g_clear_object (&priv->thumbnail_factory);
g_clear_object (&priv->store);
G_OBJECT_CLASS (bg_source_parent_class)->dispose (object);
@@ -72,7 +129,9 @@ bg_source_class_init (BgSourceClass *klass)
GParamSpec *pspec;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = bg_source_constructed;
object_class->get_property = bg_source_get_property;
object_class->set_property = bg_source_set_property;
object_class->dispose = bg_source_dispose;
pspec = g_param_spec_object ("liststore",
@@ -81,6 +140,13 @@ bg_source_class_init (BgSourceClass *klass)
G_TYPE_LIST_STORE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_LISTSTORE, pspec);
pspec = g_param_spec_object ("widget",
"Widget",
"Widget used to view the source",
GTK_TYPE_WIDGET,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_WIDGET, pspec);
}
static void
@@ -88,6 +154,7 @@ bg_source_init (BgSource *self)
{
BgSourcePrivate *priv = bg_source_get_instance_private (self);
priv->store = g_list_store_new (CC_TYPE_BACKGROUND_ITEM);
priv->thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
}
GListStore*
@@ -100,3 +167,47 @@ bg_source_get_liststore (BgSource *source)
priv = bg_source_get_instance_private (source);
return priv->store;
}
gint
bg_source_get_scale_factor (BgSource *source)
{
BgSourcePrivate *priv;
g_return_val_if_fail (BG_IS_SOURCE (source), 1);
priv = bg_source_get_instance_private (source);
return gtk_widget_get_scale_factor (priv->widget);
}
gint
bg_source_get_thumbnail_height (BgSource *source)
{
BgSourcePrivate *priv;
g_return_val_if_fail (BG_IS_SOURCE (source), THUMBNAIL_HEIGHT);
priv = bg_source_get_instance_private (source);
return priv->thumbnail_height;
}
gint
bg_source_get_thumbnail_width (BgSource *source)
{
BgSourcePrivate *priv;
g_return_val_if_fail (BG_IS_SOURCE (source), THUMBNAIL_WIDTH);
priv = bg_source_get_instance_private (source);
return priv->thumbnail_width;
}
GnomeDesktopThumbnailFactory*
bg_source_get_thumbnail_factory (BgSource *source)
{
BgSourcePrivate *priv;
g_return_val_if_fail (BG_IS_SOURCE (source), NULL);
priv = bg_source_get_instance_private (source);
return priv->thumbnail_factory;
}

View File

@@ -35,4 +35,12 @@ struct _BgSourceClass
GListStore* bg_source_get_liststore (BgSource *source);
gint bg_source_get_scale_factor (BgSource *source);
gint bg_source_get_thumbnail_height (BgSource *source);
gint bg_source_get_thumbnail_width (BgSource *source);
GnomeDesktopThumbnailFactory* bg_source_get_thumbnail_factory (BgSource *source);
G_END_DECLS

View File

@@ -157,7 +157,8 @@ bg_wallpapers_source_class_init (BgWallpapersSourceClass *klass)
}
BgWallpapersSource *
bg_wallpapers_source_new (void)
bg_wallpapers_source_new (GtkWidget *widget)
{
return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, NULL);
return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, "widget", widget, NULL);
}

View File

@@ -29,6 +29,6 @@ G_BEGIN_DECLS
#define BG_TYPE_WALLPAPERS_SOURCE (bg_wallpapers_source_get_type ())
G_DECLARE_FINAL_TYPE (BgWallpapersSource, bg_wallpapers_source, BG, WALLPAPERS_SOURCE, BgSource)
BgWallpapersSource *bg_wallpapers_source_new (void);
BgWallpapersSource *bg_wallpapers_source_new (GtkWidget *widget);
G_END_DECLS

View File

@@ -24,14 +24,12 @@
#include <glib/gi18n.h>
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
#include "bg-colors-source.h"
#include "bg-recent-source.h"
#include "bg-wallpapers-source.h"
#include "cc-background-chooser.h"
#include "cc-background-paintable.h"
#define THUMBNAIL_WIDTH 144
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
struct _CcBackgroundChooser
{
GtkBox parent;
@@ -44,8 +42,6 @@ struct _CcBackgroundChooser
BgWallpapersSource *wallpapers_source;
BgRecentSource *recent_source;
GnomeDesktopThumbnailFactory *thumbnail_factory;
};
G_DEFINE_TYPE (CcBackgroundChooser, cc_background_chooser, GTK_TYPE_BOX)
@@ -104,7 +100,6 @@ create_widget_func (gpointer model_item,
gpointer user_data)
{
g_autoptr(CcBackgroundPaintable) paintable = NULL;
GnomeDesktopThumbnailFactory *thumbnail_factory;
CcBackgroundItem *item;
GtkWidget *overlay;
GtkWidget *child;
@@ -117,13 +112,7 @@ create_widget_func (gpointer model_item,
source = BG_SOURCE (user_data);
item = CC_BACKGROUND_ITEM (model_item);
thumbnail_factory = g_object_get_data (G_OBJECT (source), "thumbnail-factory");
paintable = cc_background_paintable_new (thumbnail_factory,
item,
CC_BACKGROUND_PAINT_LIGHT_DARK,
THUMBNAIL_WIDTH,
THUMBNAIL_HEIGHT);
paintable = cc_background_paintable_new (source, item);
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (paintable));
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
@@ -154,8 +143,6 @@ create_widget_func (gpointer model_item,
gtk_widget_add_css_class (button, "circular");
gtk_widget_add_css_class (button, "remove-button");
gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("Remove Background"));
g_signal_connect (button,
"clicked",
G_CALLBACK (on_delete_background_clicked_cb),
@@ -277,7 +264,6 @@ cc_background_chooser_finalize (GObject *object)
g_clear_object (&self->recent_source);
g_clear_object (&self->wallpapers_source);
g_clear_object (&self->thumbnail_factory);
G_OBJECT_CLASS (cc_background_chooser_parent_class)->finalize (object);
}
@@ -312,13 +298,8 @@ cc_background_chooser_init (CcBackgroundChooser *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->recent_source = bg_recent_source_new ();
self->wallpapers_source = bg_wallpapers_source_new ();
self->thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
g_object_set_data (G_OBJECT (self->recent_source), "thumbnail-factory", self->thumbnail_factory);
g_object_set_data (G_OBJECT (self->wallpapers_source), "thumbnail-factory", self->thumbnail_factory);
self->recent_source = bg_recent_source_new (GTK_WIDGET (self));
self->wallpapers_source = bg_wallpapers_source_new (GTK_WIDGET (self));
setup_flowbox (self);
}

View File

@@ -31,7 +31,6 @@
#include "cc-background-item.h"
#include "gdesktop-enums-types.h"
#include "cc-background-enum-types.h"
typedef struct {
int width;
@@ -223,15 +222,15 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
pixbuf = gnome_bg_create_frame_thumbnail (bg,
thumbs,
&monitor_layout,
scale_factor * width,
scale_factor * height,
width,
height,
frame);
} else {
pixbuf = gnome_bg_create_thumbnail (bg,
thumbs,
&monitor_layout,
scale_factor * width,
scale_factor * height);
width,
height);
}
update_size (item);
@@ -771,7 +770,7 @@ cc_background_item_class_init (CcBackgroundItemClass *klass)
g_param_spec_flags ("flags",
"flags",
"flags",
CC_TYPE_BACKGROUND_ITEM_FLAGS,
G_DESKTOP_TYPE_BACKGROUND_ITEM_FLAGS,
0,
G_PARAM_READWRITE));
@@ -885,7 +884,7 @@ flags_to_str (CcBackgroundItemFlags flag)
GFlagsClass *fclass;
GFlagsValue *value;
fclass = G_FLAGS_CLASS (g_type_class_peek (CC_TYPE_BACKGROUND_ITEM_FLAGS));
fclass = G_FLAGS_CLASS (g_type_class_peek (G_DESKTOP_TYPE_BACKGROUND_ITEM_FLAGS));
value = g_flags_get_first_value (fclass, flag);
g_assert (value);

View File

@@ -19,36 +19,28 @@
#include <config.h>
#include "cc-background-enum-types.h"
#include "cc-background-paintable.h"
struct _CcBackgroundPaintable
{
GObject parent_instance;
GnomeDesktopThumbnailFactory *thumbnail_factory;
BgSource *source;
CcBackgroundItem *item;
int width;
int height;
int scale_factor;
GtkTextDirection text_direction;
GdkPaintable *texture;
GdkPaintable *dark_texture;
CcBackgroundPaintFlags paint_flags;
};
enum
{
PROP_0,
PROP_THUMBNAIL_FACTORY,
PROP_SOURCE,
PROP_ITEM,
PROP_WIDTH,
PROP_HEIGHT,
PROP_SCALE_FACTOR,
PROP_TEXT_DIRECTION,
PROP_PAINT_FLAGS,
N_PROPS
};
@@ -63,32 +55,34 @@ G_DEFINE_TYPE_WITH_CODE (CcBackgroundPaintable, cc_background_paintable, G_TYPE_
static void
update_cache (CcBackgroundPaintable *self)
{
g_autoptr(GdkPixbuf) pixbuf = NULL;
g_autoptr(GdkPixbuf) dark_pixbuf = NULL;
gboolean has_dark;
g_autoptr (GdkPixbuf) pixbuf = NULL;
GnomeDesktopThumbnailFactory *factory;
int width, height;
g_clear_object (&self->texture);
g_clear_object (&self->dark_texture);
has_dark = cc_background_item_has_dark_version (self->item);
factory = bg_source_get_thumbnail_factory (self->source);
width = bg_source_get_thumbnail_width (self->source);
height = bg_source_get_thumbnail_height (self->source);
if ((self->paint_flags & CC_BACKGROUND_PAINT_LIGHT) || !has_dark)
{
pixbuf = cc_background_item_get_thumbnail (self->item,
self->thumbnail_factory,
self->width,
self->height,
self->scale_factor,
FALSE);
self->texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
}
pixbuf = cc_background_item_get_thumbnail (self->item,
factory,
width,
height,
self->scale_factor,
FALSE);
if ((self->paint_flags & CC_BACKGROUND_PAINT_DARK) && has_dark)
self->texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
if (cc_background_item_has_dark_version (self->item))
{
g_autoptr (GdkPixbuf) dark_pixbuf = NULL;
dark_pixbuf = cc_background_item_get_thumbnail (self->item,
self->thumbnail_factory,
self->width,
self->height,
factory,
width,
height,
self->scale_factor,
TRUE);
self->dark_texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (dark_pixbuf));
@@ -103,7 +97,7 @@ cc_background_paintable_dispose (GObject *object)
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object);
g_clear_object (&self->item);
g_clear_object (&self->thumbnail_factory);
g_clear_object (&self->source);
g_clear_object (&self->texture);
g_clear_object (&self->dark_texture);
@@ -130,22 +124,14 @@ cc_background_paintable_get_property (GObject *object,
switch (prop_id)
{
case PROP_THUMBNAIL_FACTORY:
g_value_set_object (value, self->thumbnail_factory);
case PROP_SOURCE:
g_value_set_object (value, self->source);
break;
case PROP_ITEM:
g_value_set_object (value, self->item);
break;
case PROP_WIDTH:
g_value_set_int (value, self->width);
break;
case PROP_HEIGHT:
g_value_set_int (value, self->height);
break;
case PROP_SCALE_FACTOR:
g_value_set_int (value, self->scale_factor);
break;
@@ -154,10 +140,6 @@ cc_background_paintable_get_property (GObject *object,
g_value_set_enum (value, self->text_direction);
break;
case PROP_PAINT_FLAGS:
g_value_set_flags (value, self->paint_flags);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -173,22 +155,14 @@ cc_background_paintable_set_property (GObject *object,
switch (prop_id)
{
case PROP_THUMBNAIL_FACTORY:
g_set_object (&self->thumbnail_factory, g_value_get_object (value));
case PROP_SOURCE:
g_set_object (&self->source, g_value_get_object (value));
break;
case PROP_ITEM:
g_set_object (&self->item, g_value_get_object (value));
break;
case PROP_WIDTH:
self->width = g_value_get_int (value);
break;
case PROP_HEIGHT:
self->height = g_value_get_int (value);
break;
case PROP_SCALE_FACTOR:
self->scale_factor = g_value_get_int (value);
update_cache (self);
@@ -199,10 +173,6 @@ cc_background_paintable_set_property (GObject *object,
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
break;
case PROP_PAINT_FLAGS:
self->paint_flags = g_value_get_flags (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -218,11 +188,11 @@ cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
object_class->get_property = cc_background_paintable_get_property;
object_class->set_property = cc_background_paintable_set_property;
properties[PROP_THUMBNAIL_FACTORY] =
g_param_spec_object ("thumbnail-factory",
"Thumbnail factory",
"Thumbnail factory",
GNOME_DESKTOP_TYPE_THUMBNAIL_FACTORY,
properties[PROP_SOURCE] =
g_param_spec_object ("source",
"Source",
"Source",
BG_TYPE_SOURCE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
@@ -236,24 +206,6 @@ cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
properties[PROP_WIDTH] =
g_param_spec_int ("width",
"Width",
"Width",
1, G_MAXINT, 144,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
properties[PROP_HEIGHT] =
g_param_spec_int ("height",
"Height",
"Height",
1, G_MAXINT, 144 * 3 / 4,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
properties[PROP_SCALE_FACTOR] =
g_param_spec_int ("scale-factor",
"Scale Factor",
@@ -271,16 +223,6 @@ cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
properties[PROP_PAINT_FLAGS] =
g_param_spec_flags ("paint-flags",
"Paint Flags",
"Paint Flags",
CC_TYPE_BACKGROUND_PAINT_FLAGS,
CC_BACKGROUND_PAINT_LIGHT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -306,12 +248,6 @@ cc_background_paintable_snapshot (GdkPaintable *paintable,
return;
}
if (!self->texture)
{
gdk_paintable_snapshot (self->dark_texture, snapshot, width, height);
return;
}
is_rtl = self->text_direction == GTK_TEXT_DIR_RTL;
gtk_snapshot_push_clip (GTK_SNAPSHOT (snapshot),
@@ -335,27 +271,24 @@ static int
cc_background_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
GdkPaintable *valid_texture = self->texture ? self->texture : self->dark_texture;
return gdk_paintable_get_intrinsic_width (valid_texture) / self->scale_factor;
return gdk_paintable_get_intrinsic_width (self->texture) / self->scale_factor;
}
static int
cc_background_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
GdkPaintable *valid_texture = self->texture ? self->texture : self->dark_texture;
return gdk_paintable_get_intrinsic_height (valid_texture) / self->scale_factor;
return gdk_paintable_get_intrinsic_height (self->texture) / self->scale_factor;
}
static double
cc_background_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
GdkPaintable *valid_texture = self->texture ? self->texture : self->dark_texture;
return gdk_paintable_get_intrinsic_aspect_ratio (valid_texture);
return gdk_paintable_get_intrinsic_aspect_ratio (self->texture);
}
static void
@@ -367,24 +300,15 @@ cc_background_paintable_paintable_init (GdkPaintableInterface *iface)
iface->get_intrinsic_aspect_ratio = cc_background_paintable_get_intrinsic_aspect_ratio;
}
/* Workaround for a typo in libgnome-desktop, see gnome-desktop!160 */
#define G_TYPE_INSTANCE_CHECK_TYPE G_TYPE_CHECK_INSTANCE_TYPE
CcBackgroundPaintable *
cc_background_paintable_new (GnomeDesktopThumbnailFactory *thumbnail_factory,
CcBackgroundItem *item,
CcBackgroundPaintFlags paint_flags,
int width,
int height)
cc_background_paintable_new (BgSource *source,
CcBackgroundItem *item)
{
g_return_val_if_fail (GNOME_DESKTOP_IS_THUMBNAIL_FACTORY (thumbnail_factory), NULL);
g_return_val_if_fail (BG_IS_SOURCE (source), NULL);
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
return g_object_new (CC_TYPE_BACKGROUND_PAINTABLE,
"thumbnail-factory", thumbnail_factory,
"source", source,
"item", item,
"paint-flags", paint_flags,
"width", width,
"height", height,
NULL);
}

View File

@@ -23,25 +23,13 @@
#include "bg-source.h"
#include "cc-background-item.h"
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
G_BEGIN_DECLS
#define CC_TYPE_BACKGROUND_PAINTABLE (cc_background_paintable_get_type ())
G_DECLARE_FINAL_TYPE (CcBackgroundPaintable, cc_background_paintable, CC, BACKGROUND_PAINTABLE, GObject)
typedef enum {
CC_BACKGROUND_PAINT_LIGHT = 1 << 0,
CC_BACKGROUND_PAINT_DARK = 1 << 1
} CcBackgroundPaintFlags;
#define CC_BACKGROUND_PAINT_LIGHT_DARK (CC_BACKGROUND_PAINT_LIGHT | \
CC_BACKGROUND_PAINT_DARK)
CcBackgroundPaintable * cc_background_paintable_new (GnomeDesktopThumbnailFactory *thumbnail_factory,
CcBackgroundItem *item,
CcBackgroundPaintFlags paint_flags,
int width,
int height);
CcBackgroundPaintable * cc_background_paintable_new (BgSource *source,
CcBackgroundItem *item);
G_END_DECLS

View File

@@ -20,8 +20,8 @@
<property name="focusable">False</property>
<child>
<object class="AdwClamp">
<property name="maximum-size">400</property>
<property name="tightening-threshold">300</property>
<property name="maximum_size">400</property>
<property name="tightening_threshold">300</property>
<child>
<object class="GtkGrid">
<property name="column-homogeneous">True</property>
@@ -52,9 +52,7 @@
</child>
<child>
<object class="GtkLabel" id="default_label">
<property name="label" translatable="yes">_Default</property>
<property name="use-underline">True</property>
<property name="mnemonic-widget">default_toggle</property>
<property name="label" translatable="yes">Default</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
@@ -84,9 +82,7 @@
</child>
<child>
<object class="GtkLabel" id="dark_label">
<property name="label" translatable="yes">Da_rk</property>
<property name="use-underline">True</property>
<property name="mnemonic-widget">dark_toggle</property>
<property name="label" translatable="yes">Dark</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
@@ -111,8 +107,7 @@
<child>
<object class="AdwButtonContent">
<property name="icon-name">list-add-symbolic</property>
<property name="label" translatable="yes">_Add Picture…</property>
<property name="use-underline">True</property>
<property name="label" translatable="yes">Add Picture…</property>
</object>
</child>
<signal name="clicked" handler="on_add_picture_button_clicked_cb" object="CcBackgroundPanel" swapped="yes" />

View File

@@ -21,16 +21,12 @@
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
#include "cc-background-preview.h"
#include "cc-background-paintable.h"
#define THUMBNAIL_WIDTH 256 /* No use asking for more, gnome_bg caps at 256 */
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
struct _CcBackgroundPreview
{
GtkWidget parent;
GtkWidget *picture;
GtkWidget *drawing_area;
GtkWidget *light_dark_window;
GtkWidget *dark_window;
@@ -52,6 +48,35 @@ enum
static GParamSpec *properties [N_PROPS];
/* Callbacks */
static void
draw_preview_func (GtkDrawingArea *drawing_area,
cairo_t *cr,
gint width,
gint height,
gpointer user_data)
{
CcBackgroundPreview *self = CC_BACKGROUND_PREVIEW (user_data);
g_autoptr(GdkPixbuf) pixbuf = NULL;
gint scale_factor;
if (!self->item)
return;
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (drawing_area));
pixbuf = cc_background_item_get_thumbnail (self->item,
self->thumbnail_factory,
width,
height,
scale_factor,
self->is_dark &&
cc_background_item_has_dark_version (self->item));
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
cairo_paint (cr);
}
/* GObject overrides */
static void
@@ -59,7 +84,7 @@ cc_background_preview_dispose (GObject *object)
{
CcBackgroundPreview *self = (CcBackgroundPreview *)object;
g_clear_pointer (&self->picture, gtk_widget_unparent);
g_clear_pointer (&self->drawing_area, gtk_widget_unparent);
g_clear_pointer (&self->light_dark_window, gtk_widget_unparent);
g_clear_pointer (&self->dark_window, gtk_widget_unparent);
@@ -147,6 +172,36 @@ cc_background_preview_get_request_mode (GtkWidget *widget)
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
}
static void
get_primary_monitor_geometry (int *width, int *height)
{
GdkDisplay *display;
GListModel *monitors;
display = gdk_display_get_default ();
monitors = gdk_display_get_monitors (display);
if (monitors)
{
g_autoptr(GdkMonitor) primary_monitor = NULL;
GdkRectangle monitor_layout;
primary_monitor = g_list_model_get_item (monitors, 0);
gdk_monitor_get_geometry (primary_monitor, &monitor_layout);
if (width)
*width = monitor_layout.width;
if (height)
*height = monitor_layout.height;
return;
}
if (width)
*width = 1920;
if (height)
*height = 1080;
}
static void
cc_background_preview_measure (GtkWidget *widget,
GtkOrientation orientation,
@@ -157,17 +212,21 @@ cc_background_preview_measure (GtkWidget *widget,
gint *natural_baseline)
{
GtkWidget *child;
int width;
get_primary_monitor_geometry (&width, NULL);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
*natural = THUMBNAIL_WIDTH;
*minimum = 0;
}
*natural = width;
else if (for_size < 0)
*natural = 0;
else
{
*natural = MAX (0, for_size * 3 / 4); /* 4:3 aspect ratio */
*minimum = *natural;
}
*natural = floor ((double) for_size * 0.75); /* 4:3 aspect ratio */
if (orientation == GTK_ORIENTATION_VERTICAL)
*minimum = *natural;
else
*minimum = 0;
for (child = gtk_widget_get_first_child (widget);
child;
@@ -210,7 +269,7 @@ cc_background_preview_size_allocate (GtkWidget *widget,
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (is_rtl ? margin_x : opposite_margin_x,
margin_y));
gtk_widget_allocate (self->picture, width, height, baseline, NULL);
gtk_widget_allocate (self->drawing_area, width, height, baseline, NULL);
gtk_widget_allocate (self->dark_window, window_width, window_height,
baseline, back_transform);
gtk_widget_allocate (self->light_dark_window, window_width, window_height,
@@ -248,7 +307,7 @@ cc_background_preview_class_init (CcBackgroundPreviewClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-preview.ui");
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, picture);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, drawing_area);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, light_dark_window);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, dark_window);
@@ -275,27 +334,15 @@ void
cc_background_preview_set_item (CcBackgroundPreview *self,
CcBackgroundItem *item)
{
g_autoptr(CcBackgroundPaintable) paintable;
CcBackgroundPaintFlags paint_flags;
g_return_if_fail (CC_IS_BACKGROUND_PREVIEW (self));
g_return_if_fail (CC_IS_BACKGROUND_ITEM (item));
if (!g_set_object (&self->item, item))
return;
paint_flags = self->is_dark ? CC_BACKGROUND_PAINT_DARK : CC_BACKGROUND_PAINT_LIGHT;
paintable = cc_background_paintable_new (self->thumbnail_factory,
item,
paint_flags,
THUMBNAIL_WIDTH,
THUMBNAIL_HEIGHT);
g_object_bind_property (self->picture, "scale-factor",
paintable, "scale-factor", G_BINDING_SYNC_CREATE);
gtk_picture_set_paintable (GTK_PICTURE (self->picture), GDK_PAINTABLE (paintable));
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (self->drawing_area),
draw_preview_func, self, NULL);
gtk_widget_queue_draw (self->drawing_area);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]);
}

View File

@@ -8,9 +8,7 @@
<!-- Wallpaper -->
<child>
<object class="GtkPicture" id="picture">
<property name="content-fit">cover</property>
</object>
<object class="GtkDrawingArea" id="drawing_area"/>
</child>
<!-- Always dark window -->

View File

@@ -626,7 +626,10 @@ cc_background_xml_finalize (GObject *object)
g_slist_free_full (xml->monitors, g_object_unref);
g_clear_pointer (&xml->wp_hash, g_hash_table_destroy);
g_clear_handle_id (&xml->item_added_id, g_source_remove);
if (xml->item_added_id != 0) {
g_source_remove (xml->item_added_id);
xml->item_added_id = 0;
}
g_clear_pointer (&xml->item_added_queue, g_async_queue_unref);
G_OBJECT_CLASS (cc_background_xml_parent_class)->finalize (object);

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#222222">
<path d="m 3.011719 1 c -1.644531 0 -3.0000002 1.355469 -3.0000002 3 v 6 c 0 1.644531 1.3554692 3 3.0000002 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -5 h -0.011719 c 0 -0.550781 -0.449219 -1 -1 -1 s -1 0.449219 -1 1 v 0.5 l 0.011719 4.5 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570313 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429687 -1 1 -1 h 4.988281 c 0.550781 0 1 -0.449219 1 -1 c 0 -0.542969 -0.4375 -0.988281 -0.980469 -1 z m 0 0"/>
<g fill="#2e3436">
<path d="m 3.011719 1 c -1.644531 0 -3.0000002 1.355469 -3.0000002 3 v 6 c 0 1.644531 1.3554692 3 3.0000002 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -6 c 0 -0.570312 -0.167969 -1.101562 -0.449219 -1.558594 l -1.550781 1.554688 v 6.003906 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570313 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429687 -1 1 -1 h 5.96875 l 2.007812 -2 z m 0 0"/>
<path d="m 11.011719 7 c 0 1.65625 -1.339844 3.007812 -3 3 h -3 v -3 c 0 -1.660156 1.34375 -3 3 -3 c 1.660156 0 3 1.339844 3 3 z m 0 0"/>
<path d="m 13.410156 0 l -3.46875 3.457031 c 0.683594 0.355469 1.234375 0.910157 1.589844 1.589844 l 0.171875 -0.171875 l 0.007813 0.007812 l 4.300781 -4.300781 v -0.582031 z m 0 0"/>
<path d="m 5.011719 14 c -1.105469 0 -2 0.894531 -2 2 h 10 c 0 -1.105469 -0.894531 -2 -2 -2 z m 0 0"/>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 999 B

View File

@@ -17,14 +17,10 @@ install_data(
common_sources = []
common_sources += gnome.mkenums_simple(
'cc-background-enum-types',
sources: ['cc-background-item.h', 'cc-background-paintable.h']
)
enums = 'gdesktop-enums-types'
enums_header = files(
gsettings_desktop_dep.get_variable(pkgconfig: 'prefix') + '/include/gsettings-desktop-schemas/gdesktop-enums.h'
gsettings_desktop_dep.get_variable(pkgconfig: 'prefix') + '/include/gsettings-desktop-schemas/gdesktop-enums.h',
'cc-background-item.h'
)
common_sources += gnome.mkenums(
@@ -54,6 +50,7 @@ common_sources += gnome.compile_resources(
)
sources = common_sources + files(
'bg-colors-source.c',
'bg-recent-source.c',
'bg-source.c',
'bg-wallpapers-source.c',

View File

@@ -27,7 +27,7 @@
<object class="AdwStatusPage" id="no_devices_page">
<property name="icon-name">bluetooth-active-symbolic</property>
<property name="title" translatable="yes">No Bluetooth Found</property>
<property name="description" translatable="yes">Plug in a dongle to use Bluetooth</property>
<property name="description" translatable="yes">Plug in a dongle to use Bluetooth.</property>
</object>
</child>
<child>
@@ -61,7 +61,7 @@
<object class="AdwStatusPage" id="hw_airplane_page">
<property name="icon-name">airplane-mode-symbolic</property>
<property name="title" translatable="yes">Hardware Airplane Mode is On</property>
<property name="description" translatable="yes">Turn off the Airplane mode switch to enable Bluetooth</property>
<property name="description" translatable="yes">Turn off the Airplane mode switch to enable Bluetooth.</property>
</object>
</child>
<child>

View File

@@ -20,7 +20,6 @@
#include "cc-common-resources.h"
#include "cc-hostname.h"
#include "cc-hostname-entry.h"
#include "hostname-helper.h"
@@ -30,6 +29,7 @@ struct _CcHostnameEntry
{
AdwEntryRow parent;
GDBusProxy *hostnamed_proxy;
guint set_hostname_timeout_source_id;
};
@@ -37,23 +37,119 @@ G_DEFINE_TYPE (CcHostnameEntry, cc_hostname_entry, ADW_TYPE_ENTRY_ROW)
#define SET_HOSTNAME_TIMEOUT 1
static void
cc_hostname_entry_set_hostname (CcHostnameEntry *self)
{
g_autofree gchar *hostname = NULL;
g_autoptr(GVariant) pretty_result = NULL;
g_autoptr(GVariant) static_result = NULL;
g_autoptr(GError) pretty_error = NULL;
g_autoptr(GError) static_error = NULL;
const gchar *text;
text = gtk_editable_get_text (GTK_EDITABLE (self));
g_debug ("Setting PrettyHostname to '%s'", text);
pretty_result = g_dbus_proxy_call_sync (self->hostnamed_proxy,
"SetPrettyHostname",
g_variant_new ("(sb)", text, FALSE),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &pretty_error);
if (pretty_result == NULL)
g_warning ("Could not set PrettyHostname: %s", pretty_error->message);
/* Set the static hostname */
hostname = pretty_hostname_to_static (text, FALSE);
g_assert (hostname);
g_debug ("Setting StaticHostname to '%s'", hostname);
static_result = g_dbus_proxy_call_sync (self->hostnamed_proxy,
"SetStaticHostname",
g_variant_new ("(sb)", hostname, FALSE),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &static_error);
if (static_result == NULL)
g_warning ("Could not set StaticHostname: %s", static_error->message);
}
static char *
get_hostname_property (CcHostnameEntry *self,
const char *property)
{
g_autoptr(GVariant) variant = NULL;
if (!self->hostnamed_proxy)
return g_strdup ("");
variant = g_dbus_proxy_get_cached_property (self->hostnamed_proxy,
property);
if (!variant)
{
g_autoptr(GError) error = NULL;
g_autoptr(GVariant) inner = NULL;
/* Work around systemd-hostname not sending us back
* the property value when changing values */
variant = g_dbus_proxy_call_sync (self->hostnamed_proxy,
"org.freedesktop.DBus.Properties.Get",
g_variant_new ("(ss)", "org.freedesktop.hostname1", property),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (variant == NULL)
{
g_warning ("Failed to get property '%s': %s", property, error->message);
return NULL;
}
g_variant_get (variant, "(v)", &inner);
return g_variant_dup_string (inner, NULL);
}
else
{
return g_variant_dup_string (variant, NULL);
}
}
static char *
cc_hostname_entry_get_display_hostname (CcHostnameEntry *self)
{
g_autofree gchar *str = NULL;
str = get_hostname_property (self, "PrettyHostname");
/* Empty strings means that we need to fallback */
if (str != NULL &&
*str == '\0')
return get_hostname_property (self, "Hostname");
return g_steal_pointer (&str);
}
static gboolean
set_hostname_timeout (CcHostnameEntry *self)
{
const gchar *text = NULL;
self->set_hostname_timeout_source_id = 0;
text = gtk_editable_get_text (GTK_EDITABLE (self));
cc_hostname_set_hostname (cc_hostname_get_default (), text);
cc_hostname_entry_set_hostname (self);
return FALSE;
}
static void
remove_hostname_timeout (CcHostnameEntry *self)
{
if (self->set_hostname_timeout_source_id)
g_source_remove (self->set_hostname_timeout_source_id);
self->set_hostname_timeout_source_id = 0;
}
static void
reset_hostname_timeout (CcHostnameEntry *self)
{
g_clear_handle_id (&self->set_hostname_timeout_source_id, g_source_remove);
remove_hostname_timeout (self);
self->set_hostname_timeout_source_id = g_timeout_add_seconds (SET_HOSTNAME_TIMEOUT,
(GSourceFunc) set_hostname_timeout,
@@ -73,10 +169,12 @@ cc_hostname_entry_dispose (GObject *object)
if (self->set_hostname_timeout_source_id)
{
g_clear_handle_id (&self->set_hostname_timeout_source_id, g_source_remove);
remove_hostname_timeout (self);
set_hostname_timeout (self);
}
g_clear_object (&self->hostnamed_proxy);
G_OBJECT_CLASS (cc_hostname_entry_parent_class)->dispose (object);
}
@@ -109,7 +207,25 @@ cc_hostname_entry_constructed (GObject *object)
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
}
str = cc_hostname_get_display_hostname (cc_hostname_get_default ());
self->hostnamed_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
NULL,
&error);
/* This could only happen if the policy file was installed
* but not hostnamed, which points to a system bug */
if (self->hostnamed_proxy == NULL)
{
g_debug ("Couldn't get hostnamed to start, bailing: %s", error->message);
return;
}
str = cc_hostname_entry_get_display_hostname (CC_HOSTNAME_ENTRY (self));
if (str != NULL)
gtk_editable_set_text (GTK_EDITABLE (self), str);
else
@@ -140,3 +256,9 @@ cc_hostname_entry_new (void)
{
return g_object_new (CC_TYPE_HOSTNAME_ENTRY, NULL);
}
gchar*
cc_hostname_entry_get_hostname (CcHostnameEntry *entry)
{
return get_hostname_property (entry, "Hostname");
}

View File

@@ -28,5 +28,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CcHostnameEntry, cc_hostname_entry, CC, HOSTNAME_ENTRY, AdwEntryRow)
CcHostnameEntry *cc_hostname_entry_new (void);
gchar* cc_hostname_entry_get_hostname (CcHostnameEntry *entry);
G_END_DECLS

View File

@@ -1,211 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* cc-hostname.c
*
* Copyright 2023 Red Hat Inc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author(s):
* Felipe Borges <felipeborges@gnome.org>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "cc-hostname"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cc-hostname.h"
#include "hostname-helper.h"
#include "shell/cc-object-storage.h"
#define HOSTNAME_BUS_NAME "org.freedesktop.hostname1"
#define HOSTNAME_OBJECT_PATH "/org/freedesktop/hostname1"
struct _CcHostname
{
GObject parent_instance;
GDBusProxy *proxy;
};
G_DEFINE_TYPE (CcHostname, cc_hostname, G_TYPE_OBJECT)
static void
cc_hostname_dispose (GObject *object)
{
CcHostname *self = CC_HOSTNAME (object);
g_clear_object (&self->proxy);
G_OBJECT_CLASS (cc_hostname_parent_class)->dispose (object);
}
static void
cc_hostname_constructed (GObject *object)
{
CcHostname *self = CC_HOSTNAME (object);
g_autoptr(GError) error = NULL;
self->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
HOSTNAME_BUS_NAME,
HOSTNAME_OBJECT_PATH,
HOSTNAME_BUS_NAME,
NULL,
&error);
if (self->proxy == NULL) {
g_critical ("Couldn't connect to hostnamed: %s", error->message);
return;
}
}
static void
cc_hostname_init (CcHostname *self)
{
}
static void
cc_hostname_class_init (CcHostnameClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = cc_hostname_constructed;
object_class->dispose = cc_hostname_dispose;
}
CcHostname *
cc_hostname_get_default (void)
{
g_autoptr(CcHostname) self = NULL;
if (cc_object_storage_has_object (CC_OBJECT_HOSTNAME)) {
self = cc_object_storage_get_object (CC_OBJECT_HOSTNAME);
} else {
self = g_object_new (CC_TYPE_HOSTNAME, NULL);
cc_object_storage_add_object (CC_OBJECT_HOSTNAME, self);
}
return self;
}
gchar *
cc_hostname_get_property (CcHostname *self,
const gchar *property)
{
g_autoptr(GVariant) variant = NULL;
g_autoptr(GVariant) inner = NULL;
g_autoptr(GError) error = NULL;
g_return_val_if_fail (CC_IS_HOSTNAME (self), NULL);
g_return_val_if_fail (property != NULL, NULL);
if (!self->proxy)
return g_strdup ("");
variant = g_dbus_proxy_get_cached_property (self->proxy, property);
if (variant)
return g_variant_dup_string (variant, NULL);
variant = g_dbus_proxy_call_sync (self->proxy,
"org.freedesktop.DBus.Properties.Get",
g_variant_new ("(ss)", HOSTNAME_BUS_NAME, property),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (variant == NULL) {
g_warning ("Failed to get property '%s': %s", property, error->message);
return NULL;
}
g_variant_get (variant, "(v)", &inner);
return g_variant_dup_string (inner, NULL);
}
gchar *
cc_hostname_get_display_hostname (CcHostname *self)
{
g_autofree gchar *str = NULL;
g_return_val_if_fail (CC_IS_HOSTNAME (self), NULL);
str = cc_hostname_get_property (self, "PrettyHostname");
/* Empty strings means that we need to fallback */
if (str != NULL && *str == '\0')
return cc_hostname_get_property (self, "Hostname");
return g_steal_pointer (&str);
}
void
cc_hostname_set_hostname (CcHostname *self,
const gchar *hostname)
{
g_autofree gchar *static_hostname = NULL;
g_autoptr(GVariant) pretty_result = NULL;
g_autoptr(GVariant) static_result = NULL;
g_autoptr(GError) pretty_error = NULL;
g_autoptr(GError) static_error = NULL;
g_return_if_fail (CC_IS_HOSTNAME (self));
g_return_if_fail (hostname != NULL);
g_debug ("Setting PrettyHostname to '%s'", hostname);
pretty_result = g_dbus_proxy_call_sync (self->proxy,
"SetPrettyHostname",
g_variant_new ("(sb)", hostname, FALSE),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &pretty_error);
if (pretty_result == NULL)
g_warning ("Could not set PrettyHostname: %s", pretty_error->message);
/* Set the static hostname */
static_hostname = pretty_hostname_to_static (hostname, FALSE);
g_assert (hostname);
g_debug ("Setting StaticHostname to '%s'", static_hostname);
static_result = g_dbus_proxy_call_sync (self->proxy,
"SetStaticHostname",
g_variant_new ("(sb)", static_hostname, FALSE),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &static_error);
if (static_result == NULL)
g_warning ("Could not set StaticHostname: %s", static_error->message);
}
gchar *
cc_hostname_get_chassis_type (CcHostname *self)
{
g_return_val_if_fail (CC_IS_HOSTNAME (self), NULL);
return cc_hostname_get_property (self, "Chassis");
}
gboolean
cc_hostname_is_vm_chassis (CcHostname *self)
{
g_autofree gchar *chassis_type = NULL;
g_return_val_if_fail (CC_IS_HOSTNAME (self), FALSE);
chassis_type = cc_hostname_get_chassis_type (self);
return g_strcmp0 (chassis_type, "vm") == 0;
}

View File

@@ -1,48 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* cc-hostname.h
*
* Copyright 2023 Red Hat Inc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author(s):
* Felipe Borges <felipeborges@gnome.org>
*
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <glib-object.h>
#include <gio/gio.h>
G_BEGIN_DECLS
#define CC_TYPE_HOSTNAME (cc_hostname_get_type())
G_DECLARE_FINAL_TYPE (CcHostname, cc_hostname, CC, HOSTNAME, GObject)
CcHostname *cc_hostname_get_default (void);
gchar *cc_hostname_get_display_hostname (CcHostname *self);
void cc_hostname_set_hostname (CcHostname *self, const gchar *hostname);
gchar *cc_hostname_get_property (CcHostname *self, const gchar *property);
gchar *cc_hostname_get_chassis_type (CcHostname *self);
gboolean cc_hostname_is_vm_chassis (CcHostname *self);
G_END_DECLS

View File

@@ -3,11 +3,13 @@
<template class="CcListRowInfoButton" parent="GtkWidget">
<child>
<object class="GtkMenuButton" id="button">
<property name="tooltip-text" translatable="yes">More Information</property>
<property name="icon-name">info-symbolic</property>
<style>
<class name="flat"/>
</style>
<accessibility>
<property name="label" translatable="yes">More information</property>
</accessibility>
<property name="popover">
<object class="GtkPopover" id="popover">
<child>

View File

@@ -2,7 +2,6 @@
<interface>
<template class="CcListRow" parent="AdwActionRow">
<property name="activatable">True</property>
<property name="use-underline">True</property>
<!-- Secondary Label -->
<child type="suffix">

View File

@@ -60,7 +60,6 @@
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="use-underline">True</property>
<property name="xalign">0.0</property>
<property name="wrap">True</property>
<property name="wrap-mode">word-char</property>
@@ -143,7 +142,6 @@
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="use-underline">True</property>
<property name="xalign">0.0</property>
<property name="wrap">True</property>
<property name="wrap-mode">word-char</property>

View File

@@ -114,6 +114,9 @@ cc_util_get_smart_date (GDateTime *date)
g_autoptr(GDateTime) local = NULL;
GTimeSpan span;
if (date == NULL)
return NULL;
/* Set today date */
local = g_date_time_new_now_local ();
today = g_date_time_new_local (g_date_time_get_year (local),
@@ -135,7 +138,6 @@ cc_util_get_smart_date (GDateTime *date)
if (g_date_time_get_year (date) == g_date_time_get_year (today))
{
/* Translators: This is a date format string in the style of "Feb 24". */
/* xgettext:no-c-format */
return g_date_time_format (date, _("%b %e"));
}
else

View File

@@ -11,7 +11,4 @@
<file preprocess="xml-stripblanks">cc-split-row.ui</file>
<file preprocess="xml-stripblanks">cc-vertical-row.ui</file>
</gresource>
<gresource prefix="/org/gnome/Settings/icons/scalable/actions">
<file preprocess="xml-stripblanks">info-symbolic.svg</file>
</gresource>
</gresources>

View File

@@ -31,7 +31,6 @@
#ifdef GDK_WINDOWING_X11
#include <gdk/x11/gdkx.h>
#include <X11/extensions/XInput2.h>
#endif
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/wayland/gdkwayland.h>
@@ -313,27 +312,8 @@ gsd_device_manager_real_lookup_device (GsdDeviceManager *manager,
GsdDevice *device;
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (display)) {
XIDeviceInfo *info;
int n_infos, i, source_id = 0;
gdk_x11_display_error_trap_push (display);
info = XIQueryDevice (gdk_x11_display_get_xdisplay (display),
gdk_x11_device_get_id (gdk_device),
&n_infos);
if (gdk_x11_display_error_trap_pop (display) != 0)
return NULL;
if (!info || n_infos != 1)
return NULL;
for (i = 0; i < info->num_classes; i++) {
if (info->classes[i]->type == XIValuatorClass)
source_id = info->classes[i]->sourceid;
}
if (source_id != 0)
node_path = xdevice_get_device_node (source_id);
}
if (GDK_IS_X11_DISPLAY (display))
node_path = xdevice_get_device_node (gdk_x11_device_get_id (gdk_device));
#endif
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (display))

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 8 1 c -3.855469 0 -7 3.144531 -7 7 s 3.144531 7 7 7 s 7 -3.144531 7 -7 s -3.144531 -7 -7 -7 z m 0 2.875 c 0.621094 0 1.125 0.503906 1.125 1.125 s -0.503906 1.125 -1.125 1.125 s -1.125 -0.503906 -1.125 -1.125 s 0.503906 -1.125 1.125 -1.125 z m 1 3.125 v 5 h -2 v -5 z m 0 0" fill="#222222"/>
</svg>

Before

Width:  |  Height:  |  Size: 440 B

View File

@@ -54,7 +54,6 @@ libwidgets_dep = declare_dependency(
sources = common_sources + files(
'cc-common-language.c',
'cc-hostname.c',
'cc-illustrated-row.c',
'cc-language-chooser.c',
'cc-language-row.c',

View File

@@ -1,9 +1,6 @@
/*
* cc-datetime-page.c
*
* Copyright (C) 2010 Intel, Inc
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
* Copyright 2023 Gotam Gorabh <gautamy672@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,12 +15,16 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#include "config.h"
#include "cc-list-row.h"
#include "cc-time-editor.h"
#include "cc-datetime-page.h"
#include "cc-datetime-panel.h"
#include "cc-datetime-resources.h"
#include "cc-list-row.h"
#include <langinfo.h>
#include <sys/time.h>
@@ -66,9 +67,9 @@
#define DATETIME_SCHEMA "org.gnome.desktop.datetime"
#define AUTO_TIMEZONE_KEY "automatic-timezone"
struct _CcDateTimePage
struct _CcDateTimePanel
{
AdwNavigationPage parent_instance;
CcPanel parent_instance;
GList *toplevels;
@@ -84,29 +85,32 @@ struct _CcDateTimePage
GSettings *filechooser_settings;
GDesktopClockFormat clock_format;
AdwActionRow *auto_datetime_row;
AdwSwitchRow *auto_timezone_row;
AdwActionRow *auto_timezone_row;
GtkSwitch *auto_timezone_switch;
AdwActionRow *datetime_row;
GtkWindow *datetime_dialog;
GtkLabel *datetime_label;
AdwSpinRow *day_spin_row;
GtkToggleButton *twentyfour_format_button;
GtkToggleButton *ampm_format_button;
GtkSpinButton *day_spinbutton;
AdwComboRow *timeformat_row;
GtkSpinButton *h_spinbutton;
AdwSwitchRow *weekday_row;
AdwSwitchRow *date_row;
AdwSwitchRow *seconds_row;
AdwSwitchRow *week_numbers_row;
GtkWidget *weekday_row;
GtkWidget *weekday_switch;
GtkWidget *date_switch;
GtkWidget *seconds_switch;
GtkWidget *week_numbers_switch;
GtkLockButton *lock_button;
GtkListBox *date_box;
AdwActionRow *day_row;
GtkSingleSelection *month_model;
GtkPopover *month_popover;
CcListRow *month_row;
AdwActionRow *year_row;
GtkSwitch *network_time_switch;
CcTimeEditor *time_editor;
AdwActionRow *timezone_row;
CcTzDialog *timezone_dialog;
GtkLabel *timezone_label;
AdwSpinRow *year_spin_row;
GtkSpinButton *year_spinbutton;
GnomeWallClock *clock_tracker;
@@ -122,14 +126,19 @@ struct _CcDateTimePage
int month; /* index starts from 1 */
};
G_DEFINE_TYPE (CcDateTimePage, cc_date_time_page, ADW_TYPE_NAVIGATION_PAGE)
CC_PANEL_REGISTER (CcDateTimePanel, cc_date_time_panel)
static void update_time (CcDateTimePage *self);
static void update_time (CcDateTimePanel *self);
static void on_month_selection_changed_cb (CcDateTimePanel *self);
static void time_changed_cb (CcDateTimePanel *self,
CcTimeEditor *editor);
static void
cc_date_time_page_dispose (GObject *object)
cc_date_time_panel_dispose (GObject *object)
{
CcDateTimePage *self = CC_DATE_TIME_PAGE (object);
CcDateTimePanel *self = CC_DATE_TIME_PANEL (object);
if (self->cancellable)
{
@@ -155,24 +164,45 @@ cc_date_time_page_dispose (GObject *object)
g_clear_pointer (&self->date, g_date_time_unref);
G_OBJECT_CLASS (cc_date_time_page_parent_class)->dispose (object);
G_OBJECT_CLASS (cc_date_time_panel_parent_class)->dispose (object);
}
static void clock_settings_changed_cb (CcDateTimePage *self,
gchar *key);
static const char *
cc_date_time_panel_get_help_uri (CcPanel *panel)
{
return "help:gnome-help/clock";
}
static void clock_settings_changed_cb (CcDateTimePanel *self,
gchar *key);
static char *
format_clock_name_cb (AdwEnumListItem *item,
gpointer user_data)
{
switch (adw_enum_list_item_get_value (item))
{
case G_DESKTOP_CLOCK_FORMAT_24H:
return g_strdup (_("24-hour"));
case G_DESKTOP_CLOCK_FORMAT_12H:
return g_strdup (_("AM / PM"));
default:
return NULL;
}
}
static void
change_clock_settings (CcDateTimePage *self)
change_clock_settings (CcDateTimePanel *self)
{
GDesktopClockFormat value;
AdwEnumListItem *item;
g_signal_handlers_block_by_func (self->clock_settings, clock_settings_changed_cb,
self);
if (gtk_toggle_button_get_active (self->twentyfour_format_button))
value = G_DESKTOP_CLOCK_FORMAT_24H;
else
value = G_DESKTOP_CLOCK_FORMAT_12H;
item = ADW_ENUM_LIST_ITEM (adw_combo_row_get_selected_item (self->timeformat_row));
value = adw_enum_list_item_get_value (item);
g_settings_set_enum (self->clock_settings, CLOCK_FORMAT_KEY, value);
g_settings_set_enum (self->filechooser_settings, CLOCK_FORMAT_KEY, value);
@@ -185,33 +215,29 @@ change_clock_settings (CcDateTimePage *self)
}
static void
clock_settings_changed_cb (CcDateTimePage *self,
gchar *key)
clock_settings_changed_cb (CcDateTimePanel *self,
gchar *key)
{
GDesktopClockFormat value;
value = g_settings_get_enum (self->clock_settings, CLOCK_FORMAT_KEY);
self->clock_format = value;
g_signal_handlers_block_by_func (self->ampm_format_button, change_clock_settings, self);
g_signal_handlers_block_by_func (self->twentyfour_format_button, change_clock_settings, self);
g_signal_handlers_block_by_func (self->timeformat_row, change_clock_settings, self);
adw_combo_row_set_selected (self->timeformat_row, value);
gtk_toggle_button_set_active (self->twentyfour_format_button,
value == G_DESKTOP_CLOCK_FORMAT_24H);
gtk_toggle_button_set_active (self->ampm_format_button,
value == G_DESKTOP_CLOCK_FORMAT_12H);
cc_time_editor_set_am_pm (self->time_editor,
value == G_DESKTOP_CLOCK_FORMAT_12H);
update_time (self);
g_signal_handlers_unblock_by_func (self->twentyfour_format_button, change_clock_settings, self);
g_signal_handlers_unblock_by_func (self->ampm_format_button, change_clock_settings, self);
g_signal_handlers_unblock_by_func (self->timeformat_row, change_clock_settings, self);
}
/* Update the widgets based on the system time */
static void
update_time (CcDateTimePage *self)
update_time (CcDateTimePanel *self)
{
g_autofree gchar *label = NULL;
gboolean use_ampm;
@@ -221,9 +247,11 @@ update_time (CcDateTimePage *self)
else
use_ampm = FALSE;
g_signal_handlers_block_by_func (self->time_editor, time_changed_cb, self);
cc_time_editor_set_time (self->time_editor,
g_date_time_get_hour (self->date),
g_date_time_get_minute (self->date));
g_signal_handlers_unblock_by_func (self->time_editor, time_changed_cb, self);
/* Update the time on the listbow row */
if (use_ampm)
@@ -238,7 +266,9 @@ update_time (CcDateTimePage *self)
}
self->month = g_date_time_get_month (self->date);
g_signal_handlers_block_by_func (self->month_model, on_month_selection_changed_cb, self);
gtk_single_selection_set_selected (self->month_model, self->month - 1);
g_signal_handlers_unblock_by_func (self->month_model, on_month_selection_changed_cb, self);
gtk_label_set_text (self->datetime_label, label);
}
@@ -247,7 +277,7 @@ set_time_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
{
CcDateTimePage *self = user_data;
CcDateTimePanel *self = user_data;
g_autoptr(GError) error = NULL;
if (!timedate1_call_set_time_finish (self->dtm,
@@ -268,7 +298,7 @@ set_timezone_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
{
CcDateTimePage *self = user_data;
CcDateTimePanel *self = user_data;
g_autoptr(GError) error = NULL;
if (!timedate1_call_set_timezone_finish (self->dtm,
@@ -285,7 +315,7 @@ set_using_ntp_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
{
CcDateTimePage *self = user_data;
CcDateTimePanel *self = user_data;
g_autoptr(GError) error = NULL;
if (!timedate1_call_set_ntp_finish (self->dtm,
@@ -302,7 +332,7 @@ set_using_ntp_cb (GObject *source,
}
static void
queue_set_datetime (CcDateTimePage *self)
queue_set_datetime (CcDateTimePanel *self)
{
gint64 unixtime;
@@ -319,8 +349,8 @@ queue_set_datetime (CcDateTimePage *self)
}
static void
queue_set_ntp (CcDateTimePage *self,
gboolean using_ntp)
queue_set_ntp (CcDateTimePanel *self,
gboolean using_ntp)
{
self->pending_ntp_state = using_ntp;
timedate1_call_set_ntp (self->dtm,
@@ -332,7 +362,7 @@ queue_set_ntp (CcDateTimePage *self,
}
static void
queue_set_timezone (CcDateTimePage *self)
queue_set_timezone (CcDateTimePanel *self)
{
/* for now just do it */
if (self->current_location)
@@ -347,22 +377,24 @@ queue_set_timezone (CcDateTimePage *self)
}
static void
change_date (CcDateTimePage *self)
change_date (CcDateTimePanel *self)
{
guint y, d;
g_autoptr(GDateTime) old_date = NULL;
y = (guint)adw_spin_row_get_value (self->year_spin_row);
d = (guint)adw_spin_row_get_value (self->day_spin_row);
y = gtk_spin_button_get_value_as_int (self->year_spinbutton);
d = gtk_spin_button_get_value_as_int (self->day_spinbutton);
old_date = self->date;
self->date = g_date_time_new_local (y, self->month, d,
g_date_time_get_hour (old_date),
g_date_time_get_minute (old_date),
g_date_time_get_second (old_date));
g_signal_handlers_block_by_func (self->time_editor, time_changed_cb, self);
cc_time_editor_set_time (self->time_editor,
g_date_time_get_hour (self->date),
g_date_time_get_minute (self->date));
g_signal_handlers_unblock_by_func (self->time_editor, time_changed_cb, self);
queue_set_datetime (self);
}
@@ -395,7 +427,7 @@ translated_city_name (TzLocation *loc)
}
static void
update_timezone (CcDateTimePage *self)
update_timezone (CcDateTimePanel *self)
{
g_autofree gchar *city_country = NULL;
g_autofree gchar *label = NULL;
@@ -411,7 +443,7 @@ update_timezone (CcDateTimePage *self)
}
static void
get_initial_timezone (CcDateTimePage *self)
get_initial_timezone (CcDateTimePanel *self)
{
const gchar *timezone;
@@ -429,48 +461,48 @@ get_initial_timezone (CcDateTimePage *self)
}
static void
day_changed (CcDateTimePage *self)
day_changed (CcDateTimePanel *self)
{
change_date (self);
}
static void
month_year_changed (CcDateTimePage *self)
month_year_changed (CcDateTimePanel *self)
{
guint y;
guint num_days;
GtkAdjustment *adj;
y = (guint)adw_spin_row_get_value (self->year_spin_row);
y = gtk_spin_button_get_value_as_int (self->year_spinbutton);
/* Check the number of days in that month */
num_days = g_date_get_days_in_month (self->month, y);
adj = GTK_ADJUSTMENT (adw_spin_row_get_adjustment (self->day_spin_row));
adj = GTK_ADJUSTMENT (gtk_spin_button_get_adjustment (self->day_spinbutton));
gtk_adjustment_set_upper (adj, num_days + 1);
if ((guint)adw_spin_row_get_value (self->day_spin_row) > num_days)
adw_spin_row_set_value (self->day_spin_row, num_days);
if (gtk_spin_button_get_value_as_int (self->day_spinbutton) > num_days)
gtk_spin_button_set_value (self->day_spinbutton, num_days);
change_date (self);
}
static void
on_date_box_row_activated_cb (CcDateTimePage *self,
GtkListBoxRow *row)
on_date_box_row_activated_cb (CcDateTimePanel *self,
GtkListBoxRow *row)
{
g_assert (CC_IS_DATE_TIME_PAGE (self));
g_assert (CC_IS_DATE_TIME_PANEL (self));
if (row == GTK_LIST_BOX_ROW (self->month_row))
gtk_popover_popup (self->month_popover);
}
static void
on_month_selection_changed_cb (CcDateTimePage *self)
on_month_selection_changed_cb (CcDateTimePanel *self)
{
guint i;
g_assert (CC_IS_DATE_TIME_PAGE (self));
g_assert (CC_IS_DATE_TIME_PANEL (self));
i = gtk_single_selection_get_selected (self->month_model);
g_assert (i >= 0 && i < 12);
@@ -482,8 +514,8 @@ on_month_selection_changed_cb (CcDateTimePage *self)
}
static void
on_clock_changed (CcDateTimePage *self,
GParamSpec *pspec)
on_clock_changed (CcDateTimePanel *self,
GParamSpec *pspec)
{
g_date_time_unref (self->date);
self->date = g_date_time_new_now_local ();
@@ -492,8 +524,8 @@ on_clock_changed (CcDateTimePage *self,
}
static gboolean
change_ntp (CcDateTimePage *self,
gboolean state)
change_ntp (CcDateTimePanel *self,
gboolean state)
{
queue_set_ntp (self, state);
@@ -502,7 +534,7 @@ change_ntp (CcDateTimePage *self,
}
static gboolean
is_ntp_available (CcDateTimePage *self)
is_ntp_available (CcDateTimePanel *self)
{
g_autoptr(GVariant) value = NULL;
gboolean ntp_available = TRUE;
@@ -521,7 +553,7 @@ is_ntp_available (CcDateTimePage *self)
}
static void
on_permission_changed (CcDateTimePage *self)
on_permission_changed (CcDateTimePanel *self)
{
gboolean allowed, location_allowed, tz_allowed, auto_timezone, using_ntp;
@@ -529,7 +561,7 @@ on_permission_changed (CcDateTimePage *self)
location_allowed = g_settings_get_boolean (self->location_settings, LOCATION_ENABLED);
tz_allowed = (self->tz_permission != NULL && g_permission_get_allowed (self->tz_permission));
using_ntp = gtk_switch_get_active (self->network_time_switch);
auto_timezone = adw_switch_row_get_active (self->auto_timezone_row);
auto_timezone = gtk_switch_get_active (self->auto_timezone_switch);
/* All the widgets but the lock button and the 24h setting */
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_datetime_row), allowed);
@@ -545,26 +577,26 @@ on_permission_changed (CcDateTimePage *self)
}
static void
on_location_settings_changed (CcDateTimePage *self)
on_location_settings_changed (CcDateTimePanel *self)
{
on_permission_changed (self);
}
static void
on_can_ntp_changed (CcDateTimePage *self)
on_can_ntp_changed (CcDateTimePanel *self)
{
gtk_widget_set_visible (GTK_WIDGET (self->auto_datetime_row), is_ntp_available (self));
}
static void
on_timezone_changed (CcDateTimePage *self)
on_timezone_changed (CcDateTimePanel *self)
{
get_initial_timezone (self);
}
static void
on_timedated_properties_changed (CcDateTimePage *self,
GVariant *changed_properties,
on_timedated_properties_changed (CcDateTimePanel *self,
GVariant *changed_properties,
const gchar **invalidated_properties)
{
guint i;
@@ -594,22 +626,22 @@ on_timedated_properties_changed (CcDateTimePage *self,
}
static void
present_window (CcDateTimePage *self,
GtkWindow *window)
present_window (CcDateTimePanel *self,
GtkWindow *window)
{
GtkNative *native;
GtkWidget *parent;
native = gtk_widget_get_native (GTK_WIDGET (self));
parent = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)));
gtk_window_set_transient_for (window, GTK_WINDOW (native));
gtk_window_set_transient_for (window, GTK_WINDOW (parent));
gtk_window_present (window);
}
static gboolean
tz_switch_to_row_transform_func (GBinding *binding,
const GValue *source_value,
GValue *target_value,
CcDateTimePage *self)
tz_switch_to_row_transform_func (GBinding *binding,
const GValue *source_value,
GValue *target_value,
CcDateTimePanel *self)
{
gboolean active;
gboolean allowed;
@@ -626,10 +658,10 @@ tz_switch_to_row_transform_func (GBinding *binding,
}
static gboolean
switch_to_row_transform_func (GBinding *binding,
const GValue *source_value,
GValue *target_value,
CcDateTimePage *self)
switch_to_row_transform_func (GBinding *binding,
const GValue *source_value,
GValue *target_value,
CcDateTimePanel *self)
{
gboolean active;
gboolean allowed;
@@ -643,9 +675,9 @@ switch_to_row_transform_func (GBinding *binding,
}
static void
bind_switch_to_row (CcDateTimePage *self,
GtkSwitch *gtkswitch,
GtkWidget *listrow)
bind_switch_to_row (CcDateTimePanel *self,
GtkSwitch *gtkswitch,
GtkWidget *listrow)
{
g_object_bind_property_full (gtkswitch, "active",
listrow, "sensitive",
@@ -655,17 +687,17 @@ bind_switch_to_row (CcDateTimePage *self,
}
static void
panel_tz_selection_changed_cb (CcDateTimePage *self)
panel_tz_selection_changed_cb (CcDateTimePanel *self)
{
g_assert (CC_IS_DATE_TIME_PAGE (self));
g_assert (CC_IS_DATE_TIME_PANEL (self));
self->current_location = cc_tz_dialog_get_selected_location (self->timezone_dialog);
queue_set_timezone (self);
}
static void
list_box_row_activated (CcDateTimePage *self,
GtkListBoxRow *row)
list_box_row_activated (CcDateTimePanel *self,
GtkListBoxRow *row)
{
if (row == GTK_LIST_BOX_ROW (self->datetime_row))
@@ -679,12 +711,12 @@ list_box_row_activated (CcDateTimePage *self,
}
static void
time_changed_cb (CcDateTimePage *self,
CcTimeEditor *editor)
time_changed_cb (CcDateTimePanel *self,
CcTimeEditor *editor)
{
g_autoptr(GDateTime) old_date = NULL;
g_assert (CC_IS_DATE_TIME_PAGE (self));
g_assert (CC_IS_DATE_TIME_PANEL (self));
g_assert (CC_IS_TIME_EDITOR (editor));
old_date = self->date;
@@ -700,7 +732,7 @@ time_changed_cb (CcDateTimePage *self,
}
static void
setup_datetime_dialog (CcDateTimePage *self)
setup_datetime_dialog (CcDateTimePanel *self)
{
GtkAdjustment *adjustment;
GdkDisplay *display;
@@ -730,35 +762,37 @@ setup_datetime_dialog (CcDateTimePage *self)
g_date_time_get_year (self->date));
adjustment = (GtkAdjustment*) gtk_adjustment_new (g_date_time_get_day_of_month (self->date), 1,
num_days + 1, 1, 10, 1);
adw_spin_row_set_adjustment (self->day_spin_row, adjustment);
g_signal_connect_object (G_OBJECT (self->day_spin_row), "changed",
gtk_spin_button_set_adjustment (self->day_spinbutton, adjustment);
g_signal_connect_object (G_OBJECT (self->day_spinbutton), "value-changed",
G_CALLBACK (day_changed), self, G_CONNECT_SWAPPED);
/* Year */
adjustment = (GtkAdjustment*) gtk_adjustment_new (g_date_time_get_year (self->date),
1, G_MAXDOUBLE, 1,
10, 1);
adw_spin_row_set_adjustment (self->year_spin_row, adjustment);
g_signal_connect_object (G_OBJECT (self->year_spin_row), "changed",
gtk_spin_button_set_adjustment (self->year_spinbutton, adjustment);
g_signal_connect_object (G_OBJECT (self->year_spinbutton), "value-changed",
G_CALLBACK (month_year_changed), self, G_CONNECT_SWAPPED);
/* Month */
self->month = g_date_time_get_month (self->date);
g_signal_handlers_block_by_func (self->month_model, on_month_selection_changed_cb, self);
gtk_single_selection_set_selected (self->month_model, self->month - 1);
g_signal_handlers_unblock_by_func (self->month_model, on_month_selection_changed_cb, self);
}
static int
sort_date_box (GtkListBoxRow *a,
GtkListBoxRow *b,
CcDateTimePage *self)
sort_date_box (GtkListBoxRow *a,
GtkListBoxRow *b,
CcDateTimePanel *self)
{
GtkListBoxRow *day_row, *month_row, *year_row;
g_assert (CC_IS_DATE_TIME_PAGE (self));
g_assert (CC_IS_DATE_TIME_PANEL (self));
day_row = GTK_LIST_BOX_ROW (self->day_spin_row);
day_row = GTK_LIST_BOX_ROW (self->day_row);
month_row = GTK_LIST_BOX_ROW (self->month_row);
year_row = GTK_LIST_BOX_ROW (self->year_spin_row);
year_row = GTK_LIST_BOX_ROW (self->year_row);
switch (date_endian_get_default (FALSE)) {
case DATE_ENDIANESS_BIG:
@@ -794,60 +828,68 @@ sort_date_box (GtkListBoxRow *a,
}
static void
cc_date_time_page_class_init (CcDateTimePageClass *klass)
cc_date_time_panel_class_init (CcDateTimePanelClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
object_class->dispose = cc_date_time_page_dispose;
object_class->dispose = cc_date_time_panel_dispose;
panel_class->get_help_uri = cc_date_time_panel_get_help_uri;
g_type_ensure (CC_TYPE_LIST_ROW);
g_type_ensure (CC_TYPE_TIME_EDITOR);
g_type_ensure (CC_TYPE_TZ_DIALOG);
g_type_ensure (G_DESKTOP_TYPE_DESKTOP_CLOCK_FORMAT);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/system/datetime/cc-datetime-page.ui");
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/datetime/cc-datetime-panel.ui");
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, auto_datetime_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, auto_timezone_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, auto_timezone_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, date_box);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, datetime_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, datetime_dialog);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, datetime_label);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, day_spin_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, twentyfour_format_button);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, ampm_format_button);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, weekday_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, date_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, seconds_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, week_numbers_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, lock_button);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, month_model);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, month_popover);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, month_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, network_time_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, time_editor);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, timezone_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, timezone_dialog);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, timezone_label);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, year_spin_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_datetime_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_timezone_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_timezone_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, date_box);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_dialog);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_label);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, day_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, day_spinbutton);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timeformat_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, weekday_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, date_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, seconds_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, week_numbers_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, lock_button);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_model);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_popover);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, network_time_switch);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, time_editor);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_dialog);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_label);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, year_row);
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, year_spinbutton);
gtk_widget_class_bind_template_callback (widget_class, panel_tz_selection_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, list_box_row_activated);
gtk_widget_class_bind_template_callback (widget_class, time_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, change_clock_settings);
gtk_widget_class_bind_template_callback (widget_class, format_clock_name_cb);
gtk_widget_class_bind_template_callback (widget_class, on_date_box_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_month_selection_changed_cb);
bind_textdomain_codeset (GETTEXT_PACKAGE_TIMEZONES, "UTF-8");
g_type_ensure (CC_TYPE_TIME_EDITOR);
}
static void
cc_date_time_page_init (CcDateTimePage *self)
cc_date_time_panel_init (CcDateTimePanel *self)
{
g_autoptr(GError) error = NULL;
g_resources_register (cc_datetime_get_resource ());
gtk_widget_init_template (GTK_WIDGET (self));
self->cancellable = g_cancellable_new ();
@@ -911,7 +953,7 @@ cc_date_time_page_init (CcDateTimePage *self)
gtk_widget_set_visible (GTK_WIDGET (self->auto_datetime_row), is_ntp_available (self));
/* Timezone settings */
g_object_bind_property_full (self->auto_timezone_row, "active",
g_object_bind_property_full (self->auto_timezone_switch, "active",
self->timezone_row, "sensitive",
G_BINDING_SYNC_CREATE,
(GBindingTransformFunc) tz_switch_to_row_transform_func,
@@ -919,7 +961,7 @@ cc_date_time_page_init (CcDateTimePage *self)
self->datetime_settings = g_settings_new (DATETIME_SCHEMA);
g_settings_bind (self->datetime_settings, AUTO_TIMEZONE_KEY,
self->auto_timezone_row, "active",
self->auto_timezone_switch, "active",
G_SETTINGS_BIND_DEFAULT);
/* Clock settings */
@@ -935,22 +977,22 @@ cc_date_time_page_init (CcDateTimePage *self)
/* setup top bar clock setting switches */
g_settings_bind (self->clock_settings, CLOCK_SHOW_WEEKDAY_KEY,
self->weekday_row, "active",
self->weekday_switch, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (self->clock_settings, CLOCK_SHOW_DATE_KEY,
self->date_row, "active",
self->date_switch, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (self->clock_settings, CLOCK_SHOW_SECONDS_KEY,
self->seconds_row, "active",
self->seconds_switch, "active",
G_SETTINGS_BIND_DEFAULT);
/* Calendar settings */
self->calendar_settings = g_settings_new (CALENDAR_SCHEMA);
g_settings_bind (self->calendar_settings, CALENDAR_SHOW_WEEK_NUMBERS_KEY,
self->week_numbers_row, "active",
self->week_numbers_switch, "active",
G_SETTINGS_BIND_DEFAULT);
update_time (self);

View File

@@ -1,6 +1,4 @@
/*
* cc-region-page.h
*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
@@ -16,19 +14,17 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Sergey Udaltsov <svu@gnome.org>
* Gotam Gorabh <gautamy672@gmail.com>
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#pragma once
#include <adwaita.h>
#include <shell/cc-panel.h>
G_BEGIN_DECLS
#define CC_TYPE_REGION_PAGE (cc_region_page_get_type ())
G_DECLARE_FINAL_TYPE (CcRegionPage, cc_region_page, CC, REGION_PAGE, AdwNavigationPage)
#define CC_TYPE_DATE_TIME_PANEL (cc_date_time_panel_get_type ())
G_DECLARE_FINAL_TYPE (CcDateTimePanel, cc_date_time_panel, CC, DATE_TIME_PANEL, CcPanel)
G_END_DECLS

View File

@@ -56,19 +56,24 @@
<!-- Year row -->
<child>
<object class="AdwSpinRow" id="year_spin_row">
<property name="title" translatable="yes">_Year</property>
<property name="use-underline">True</property>
<property name="valign">center</property>
<property name="width-chars">4</property>
<property name="numeric">True</property>
<object class="AdwActionRow" id="year_row">
<property name="title" translatable="yes">Year</property>
<property name="activatable-widget">year_spinbutton</property>
<child>
<object class="GtkSpinButton" id="year_spinbutton">
<property name="valign">center</property>
<property name="width-chars">4</property>
<property name="numeric">True</property>
</object>
</child>
</object>
</child>
<!-- Month row -->
<child>
<object class="CcListRow" id="month_row">
<property name="title" translatable="yes">_Month</property>
<property name="title" translatable="yes">Month</property>
<binding name="secondary-label">
<lookup name="string" type="GtkStringObject">
<lookup name="selected-item">month_model</lookup>
@@ -94,12 +99,16 @@
<!-- Day row -->
<child>
<object class="AdwSpinRow" id="day_spin_row">
<property name="title" translatable="yes">_Day</property>
<property name="use-underline">True</property>
<property name="valign">center</property>
<property name="width-chars">3</property>
<property name="numeric">True</property>
<object class="AdwActionRow" id="day_row">
<property name="title" translatable="yes">Day</property>
<property name="activatable-widget">day_spinbutton</property>
<child>
<object class="GtkSpinButton" id="day_spinbutton">
<property name="valign">center</property>
<property name="width-chars">3</property>
<property name="numeric">True</property>
</object>
</child>
</object>
</child>
@@ -113,9 +122,7 @@
</object>
</property>
</object>
<template class="CcDateTimePage" parent="AdwNavigationPage">
<property name="title" translatable="yes">Date &amp; Time</property>
<property name="tag">system-date-time-page</property>
<template class="CcDateTimePanel" parent="CcPanel">
<property name="child">
<object class="AdwToolbarView">
<child type="top">
@@ -170,10 +177,16 @@
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwSwitchRow" id="auto_timezone_row">
<object class="AdwActionRow" id="auto_timezone_row">
<property name="title" translatable="yes">Automatic Time _Zone</property>
<property name="subtitle" translatable="yes">Requires location services enabled and internet access</property>
<property name="use_underline">True</property>
<property name="activatable_widget">auto_timezone_switch</property>
<child>
<object class="GtkSwitch" id="auto_timezone_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
@@ -202,33 +215,18 @@
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<object class="AdwComboRow" id="timeformat_row">
<property name="title" translatable="yes">Time _Format</property>
<property name="use_underline">True</property>
<child type="suffix">
<object class="GtkBox">
<property name="valign">center</property>
<property name="homogeneous">True</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="twentyfour_format_button">
<property name="label" translatable="yes">_24-hour</property>
<property name="use-underline">True</property>
<property name="group">ampm_format_button</property>
<signal name="toggled" handler="change_clock_settings" object="CcDateTimePage" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="ampm_format_button">
<property name="label" translatable="yes">AM / _PM</property>
<property name="use-underline">True</property>
<signal name="toggled" handler="change_clock_settings" object="CcDateTimePage" swapped="yes"/>
</object>
</child>
<signal name="notify::selected-item" handler="change_clock_settings" object="CcDateTimePanel" swapped="yes"/>
<property name="model">
<object class="AdwEnumListModel">
<property name="enum-type">GDesktopClockFormat</property>
</object>
</child>
</property>
<property name="expression">
<closure type="gchararray" function="format_clock_name_cb"/>
</property>
</object>
</child>
</object>
@@ -238,28 +236,51 @@
<property name="title" translatable="yes">Clock &amp;amp; Calendar</property>
<property name="description" translatable="yes">Control how the time and date is shown in the top bar</property>
<child>
<object class="AdwSwitchRow" id="weekday_row">
<property name="title" translatable="yes">_Week Day</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Week Day</property>
<property name="use_underline">True</property>
<property name="activatable_widget">weekday_switch</property>
<child>
<object class="GtkSwitch" id="weekday_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="date_row">
<property name="title" translatable="yes">D_ate</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Date</property>
<property name="use_underline">True</property>
<property name="activatable_widget">date_switch</property>
<child>
<object class="GtkSwitch" id="date_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="seconds_row">
<property name="title" translatable="yes">_Seconds</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Seconds</property>
<property name="use_underline">True</property>
<property name="activatable_widget">seconds_switch</property>
<child>
<object class="GtkSwitch" id="seconds_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwSwitchRow" id="week_numbers_row">
<property name="title" translatable="yes">Week _Numbers</property>
<property name="subtitle" translatable="yes">Shown in the dropdown calendar</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Week Numbers</property>
<property name="use_underline">True</property>
<property name="activatable_widget">week_numbers_switch</property>
<child>
<object class="GtkSwitch" id="week_numbers_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
@@ -285,7 +306,7 @@
</style>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/org/gnome/control-center/system/datetime/cc-month-row.ui</property>
<property name="resource">/org/gnome/control-center/datetime/cc-month-row.ui</property>
</object>
</property>
<property name="model">

View File

@@ -168,18 +168,6 @@ tz_dialog_search_changed_cb (CcTzDialog *self)
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
}
static void
tz_dialog_search_stopped_cb (CcTzDialog *self)
{
const char *search_text;
search_text = gtk_editable_get_text (GTK_EDITABLE (self->location_entry));
if (search_text && g_strcmp0 (search_text, "") != 0)
gtk_editable_set_text (GTK_EDITABLE (self->location_entry), "");
else
gtk_window_close (GTK_WINDOW (self));
}
static void
tz_dialog_row_activated_cb (CcTzDialog *self,
guint position)
@@ -240,7 +228,7 @@ cc_tz_dialog_class_init (CcTzDialogClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/"
"system/datetime/cc-tz-dialog.ui");
"datetime/cc-tz-dialog.ui");
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, location_entry);
@@ -250,8 +238,9 @@ cc_tz_dialog_class_init (CcTzDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, tz_view);
gtk_widget_class_bind_template_callback (widget_class, tz_dialog_search_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, tz_dialog_search_stopped_cb);
gtk_widget_class_bind_template_callback (widget_class, tz_dialog_row_activated_cb);
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_Escape, 0, "window.close", NULL);
}
static void

View File

@@ -5,9 +5,8 @@
<property name="hide-on-close">True</property>
<property name="title" translatable="yes">Select Time Zone</property>
<property name="width-request">360</property>
<property name="height-request">294</property>
<property name="height-request">300</property>
<property name="default-height">540</property>
<property name="default-width">400</property>
<style>
<class name="view"/>
</style>
@@ -32,7 +31,6 @@
<property name="halign">center</property>
<property name="width-chars">24</property>
<signal name="search-changed" handler="tz_dialog_search_changed_cb" swapped="yes"/>
<signal name="stop-search" handler="tz_dialog_search_stopped_cb" swapped="yes"/>
</object>
</child>
</object>
@@ -61,7 +59,7 @@
<signal name="activate" handler="tz_dialog_row_activated_cb" swapped="yes"/>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/org/gnome/control-center/system/datetime/cc-tz-row.ui</property>
<property name="resource">/org/gnome/control-center/datetime/cc-tz-row.ui</property>
</object>
</property>
</object>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
@@ -68,7 +67,6 @@
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="ellipsize">end</property>
<binding name="label">
<lookup name="zone" type="CcTzItem">
<lookup name="item">GtkListItem</lookup>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/control-center/datetime">
<file preprocess="xml-stripblanks">cc-datetime-panel.ui</file>
<file preprocess="xml-stripblanks">cc-month-row.ui</file>
<file preprocess="xml-stripblanks">cc-tz-dialog.ui</file>
<file preprocess="xml-stripblanks">cc-tz-row.ui</file>
<file>backward</file>
</gresource>
</gresources>

View File

@@ -0,0 +1,16 @@
[Desktop Entry]
Name=Date & Time
Comment=Change the date and time, including time zone
Exec=gnome-control-center datetime
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=org.gnome.Settings-time-symbolic
Terminal=false
Type=Application
NoDisplay=true
StartupNotify=true
Categories=GNOME;GTK;Settings;X-GNOME-Settings-Panel;X-GNOME-DetailsSettings;
OnlyShowIn=GNOME;
# Translators: Search terms to find the Date and Time panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
Keywords=Clock;Timezone;Location;
# Notifications are emitted by gnome-settings-daemon
X-GNOME-UsesNotifications=true

View File

@@ -1,4 +1,4 @@
install_data(
'org.gnome.Settings-region-symbolic.svg',
'scalable/org.gnome.Settings-time-symbolic.svg',
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
)

View File

Before

Width:  |  Height:  |  Size: 820 B

After

Width:  |  Height:  |  Size: 820 B

123
panels/datetime/meson.build Normal file
View File

@@ -0,0 +1,123 @@
panels_list += cappletname
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
i18n.merge_file(
type: 'desktop',
input: desktop + '.in',
output: desktop,
po_dir: po_dir,
install: true,
install_dir: control_center_desktopdir
)
polkit = 'org.gnome.controlcenter.@0@.policy'.format(cappletname)
i18n.merge_file(
input: polkit + '.in',
output: polkit,
po_dir: po_dir,
install: true,
install_dir: join_paths(control_center_datadir, 'polkit-1', 'actions')
)
resources = gnome.compile_resources(
'cc-' + cappletname + '-resources',
cappletname + '.gresource.xml',
c_name: 'cc_' + cappletname,
export: true
)
sources = files(
'cc-datetime-panel.c',
'cc-tz-item.c',
'cc-tz-dialog.c',
'date-endian.c',
'tz.c'
)
enums = 'gdesktop-enums-types'
enums_header = files(
gsettings_desktop_dep.get_variable(pkgconfig: 'prefix') + '/include/gsettings-desktop-schemas/gdesktop-enums.h',
'cc-datetime-panel.h'
)
sources += gnome.mkenums(
enums + '.h',
sources: enums_header,
fhead: '#pragma once\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n',
fprod: '/* enumerations from "@filename@" */\n',
vhead: 'GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define G_DESKTOP_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n',
ftail: 'G_END_DECLS\n'
)
sources += gnome.mkenums(
enums + '.c',
sources: enums_header,
fhead: '#include <gdesktop-enums.h>\n#include "gdesktop-enums-types.h"\n#include "cc-datetime-panel.h"',
fprod: '\n/* enumerations from "@filename@" */',
vhead: 'GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {',
vprod: ' { @VALUENAME@, "@VALUENAME@", "@valuenick@" },',
vtail: ' { 0, NULL, NULL }\n };\n etype = g_@type@_register_static ("@EnumName@", values);\n }\n return etype;\n}\n'
)
gdbus = 'timedated'
gdbus_iface_xml = gdbus + '1-interface.xml'
# This requires running d-bus session and accessible timedate1 daemon
# FIXME: need to find a way how to filter out unnecessary d-bus stuff (introspectable, properties)
#timedated1-interface.xml:
# gdbus introspect \
# --xml \
# --system \
# --dest org.freedesktop.timedate1 \
# --object-path /org/freedesktop/timedate1 \
# > timedated1-interface.xml
'''
gdbus_iface = custom_target(
gdbus_iface_xml,
output: gdbus_iface_xml,
capture: true,
command: [
find_program('gdbus'),
'introspect',
'--xml',
'--system',
'--dest', 'org.freedesktop.timedate1',
'--object-path', '/org/freedesktop/timedate1'
],
)
'''
sources += gnome.gdbus_codegen(
gdbus,
gdbus_iface_xml,
interface_prefix: 'org.freedesktop.'
)
deps = common_deps + [
gdk_pixbuf_dep,
gnome_desktop_dep,
polkit_gobject_dep
]
cflags += [
'-DGNOMECC_DATA_DIR="@0@"'.format(control_center_pkgdatadir)
]
datetime_panel_lib = static_library(
cappletname,
sources: sources + resources,
include_directories: [ top_inc, common_inc ],
dependencies: deps,
c_args: cflags
)
panels_libs += datetime_panel_lib
datetime_panel_lib_dep = declare_dependency(
sources : resources,
include_directories : [top_inc, include_directories('.')],
link_with : datetime_panel_lib
)
subdir('po-timezones')
subdir('icons')

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