Compare commits
128 Commits
wip/ssh-so
...
45.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a7808272f | ||
|
|
907e5cf2c2 | ||
|
|
196ca6ce86 | ||
|
|
f811bac8a8 | ||
|
|
2bec32d482 | ||
|
|
967b4d3ce9 | ||
|
|
42b05525b4 | ||
|
|
bfa3a1ce80 | ||
|
|
b4609b661c | ||
|
|
7f350031c2 | ||
|
|
4adec45df7 | ||
|
|
d00302f518 | ||
|
|
60316c0fe8 | ||
|
|
eabdb0d758 | ||
|
|
2d3ac85730 | ||
|
|
23c57ccda2 | ||
|
|
7cdfba94a5 | ||
|
|
f4c430e7e1 | ||
|
|
ee87c36201 | ||
|
|
769c790ff8 | ||
|
|
afa9438155 | ||
|
|
d64153160d | ||
|
|
dd13023893 | ||
|
|
cc00aa9a9a | ||
|
|
9814dae52a | ||
|
|
9605ac5785 | ||
|
|
7b10a54d58 | ||
|
|
c2958255e0 | ||
|
|
4e107fa212 | ||
|
|
bc52ef0e52 | ||
|
|
87fcec6529 | ||
|
|
f628a1ada3 | ||
|
|
c6611f1cb8 | ||
|
|
b362343b04 | ||
|
|
1d723270ff | ||
|
|
e0fbbd6279 | ||
|
|
c90adb673e | ||
|
|
65f151dfec | ||
|
|
42e994c6d5 | ||
|
|
25194046e7 | ||
|
|
9670d032e7 | ||
|
|
0a8e61c9eb | ||
|
|
4ef09d387a | ||
|
|
1c83dcf37a | ||
|
|
a57a45ae18 | ||
|
|
4a1b9b2a2c | ||
|
|
6d11167a3a | ||
|
|
92acbff00a | ||
|
|
88b0ab9204 | ||
|
|
649d06d954 | ||
|
|
cc5da95fec | ||
|
|
84a69d0289 | ||
|
|
2a104f26d8 | ||
|
|
8aa48007a1 | ||
|
|
77ab990e12 | ||
|
|
5a93a42041 | ||
|
|
64537f6bc3 | ||
|
|
0efaa27bea | ||
|
|
22956cba01 | ||
|
|
a8f74e39f1 | ||
|
|
e736e1b259 | ||
|
|
3250055ebf | ||
|
|
1aa75612e9 | ||
|
|
318f87cdbc | ||
|
|
9a5e225752 | ||
|
|
cc529478dc | ||
|
|
2a409e7872 | ||
|
|
8c6e673c94 | ||
|
|
9d57e857cf | ||
|
|
3cc13bf47f | ||
|
|
ad47ec14c3 | ||
|
|
b3afa91f1a | ||
|
|
39f12a7d1b | ||
|
|
f6215b0c0c | ||
|
|
bd328beba4 | ||
|
|
ff0052ceff | ||
|
|
6f19ba27e0 | ||
|
|
295c5f7916 | ||
|
|
b5c7708093 | ||
|
|
d92c5bc9a6 | ||
|
|
80772d947b | ||
|
|
1307efed3a | ||
|
|
cc0630b39e | ||
|
|
c47512abf4 | ||
|
|
f14eef644e | ||
|
|
2af7116f59 | ||
|
|
5d6447b0b9 | ||
|
|
b7309b1f19 | ||
|
|
076e4f46f0 | ||
|
|
a95ab55060 | ||
|
|
0d01819cbd | ||
|
|
b083248538 | ||
|
|
f2df7c50ab | ||
|
|
7397765226 | ||
|
|
c0cbf0b566 | ||
|
|
41ad0d9471 | ||
|
|
1bdb56b1d6 | ||
|
|
55774c6e44 | ||
|
|
f565c9b4c4 | ||
|
|
74dfd288a3 | ||
|
|
454955aada | ||
|
|
30eda57465 | ||
|
|
b7b56e65c2 | ||
|
|
e9ffde0036 | ||
|
|
3f2488d553 | ||
|
|
98d52f881d | ||
|
|
2e59005b6f | ||
|
|
c7684fec5c | ||
|
|
130c4ecbae | ||
|
|
ee7058adc2 | ||
|
|
38b0bc5667 | ||
|
|
cef09dfa7d | ||
|
|
a9d37c85d1 | ||
|
|
8922e6220c | ||
|
|
a8be38080b | ||
|
|
aacba75357 | ||
|
|
538201116f | ||
|
|
59cfa336ab | ||
|
|
63818b7ae0 | ||
|
|
165fd55ec2 | ||
|
|
b01cba0a82 | ||
|
|
8cfd9bb72c | ||
|
|
43ca1672c8 | ||
|
|
47e856a4cf | ||
|
|
b364cc063f | ||
|
|
d0668ffcde | ||
|
|
009b2fc1be | ||
|
|
234390e803 |
@@ -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
|
||||
@@ -32,7 +32,7 @@ stages:
|
||||
.Build procedure: &build_procedure
|
||||
echo "== Building ==" &&
|
||||
dnf install -y dnf5-plugins &&
|
||||
git clone https://gitlab.gnome.org/GNOME/gtk.git &&
|
||||
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 &&
|
||||
@@ -59,8 +59,8 @@ stages:
|
||||
# stable branch.
|
||||
# Could probably also switch away from rawhide,
|
||||
# to stable fedora branch as well.
|
||||
FDO_DISTRIBUTION_TAG: '2023-06-07.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: rawhide
|
||||
FDO_DISTRIBUTION_TAG: '2024-04-16.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: 39
|
||||
|
||||
#############################################
|
||||
# Create CI Docker Images #
|
||||
@@ -131,8 +131,8 @@ build.container.fedora@x86_64:
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
libsecret-devel
|
||||
libgweather4-devel
|
||||
geocode-glib2-devel
|
||||
libgweather-devel
|
||||
lcms2-devel
|
||||
geoclue2-devel
|
||||
libnotify-devel
|
||||
@@ -184,7 +184,8 @@ build.container.fedora@x86_64:
|
||||
meson . _build --prefix=/usr && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd ..
|
||||
cd .. && \
|
||||
dnf remove -y systemtap-runtime
|
||||
|
||||
##
|
||||
# Stage: Build
|
||||
@@ -221,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'
|
||||
|
||||
@@ -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()
|
||||
@@ -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 we’re 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 "Couldn’t 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 GGNOME 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. That’s why this CI check is OK
|
||||
# to fail: the idea is that people can look through the output and ignore it if
|
||||
# it’s wrong. (That situation can also happen if someone touches pre-existing
|
||||
# badly formatted code and it doesn’t make sense to tidy up the wider coding
|
||||
# style with the changes they’re 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}
|
||||
99
NEWS
99
NEWS
@@ -1,3 +1,102 @@
|
||||
============
|
||||
Version 45.5
|
||||
============
|
||||
|
||||
- Translation updates
|
||||
|
||||
Display
|
||||
- Fix crash when closing laptop lid
|
||||
|
||||
============
|
||||
Version 45.4
|
||||
============
|
||||
|
||||
- Various translation updates
|
||||
- CI fixes
|
||||
|
||||
Accessibility
|
||||
- Improve accessibility of "Typing" settings sliders
|
||||
|
||||
Datetime
|
||||
- Prevent unnecessary calls to auto time synchronization
|
||||
|
||||
Privacy
|
||||
- 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
|
||||
|
||||
============
|
||||
Version 45.3
|
||||
============
|
||||
|
||||
Datetime
|
||||
- Fix build with -Wincompatible-pointer-types
|
||||
|
||||
Region
|
||||
- Prevent preview crash from accessing invalid pointer
|
||||
|
||||
Wifi
|
||||
- Fix build with -Wincompatible-pointer-types
|
||||
|
||||
============
|
||||
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
|
||||
- Show tooltip information for the Avatar widget
|
||||
|
||||
============
|
||||
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
|
||||
============
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,49 +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
|
||||
|
||||
## 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
|
||||
@@ -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>
|
||||
|
||||
20
meson.build
20
meson.build
@@ -1,8 +1,8 @@
|
||||
project(
|
||||
'gnome-control-center', 'c',
|
||||
version : '46.alpha',
|
||||
version : '45.5',
|
||||
license : 'GPL2+',
|
||||
meson_version : '>= 0.58.0'
|
||||
meson_version : '>= 0.57.0'
|
||||
)
|
||||
|
||||
control_center_prefix = get_option('prefix')
|
||||
@@ -73,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
|
||||
@@ -176,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')
|
||||
@@ -255,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')
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
@@ -53,20 +53,12 @@
|
||||
struct _CcApplicationsPanel
|
||||
{
|
||||
CcPanel parent;
|
||||
CcDefaultAppsPage *default_apps_page;
|
||||
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,12 +80,14 @@ struct _CcApplicationsPanel
|
||||
GtkButton *view_details_button;
|
||||
|
||||
GDBusProxy *perm_store;
|
||||
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;
|
||||
@@ -116,7 +110,9 @@ struct _CcApplicationsPanel
|
||||
GtkWindow *builtin_dialog;
|
||||
AdwPreferencesPage *builtin_page;
|
||||
GtkListBox *builtin_list;
|
||||
#ifdef HAVE_SNAP
|
||||
GList *snap_permission_rows;
|
||||
#endif
|
||||
|
||||
GtkButton *handler_reset;
|
||||
GtkWindow *handler_dialog;
|
||||
@@ -703,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;
|
||||
@@ -714,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",
|
||||
@@ -737,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++;
|
||||
@@ -839,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 --- */
|
||||
@@ -941,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
|
||||
{
|
||||
@@ -976,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);
|
||||
}
|
||||
|
||||
@@ -1085,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;
|
||||
|
||||
@@ -1096,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");
|
||||
@@ -1208,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)
|
||||
{
|
||||
@@ -1395,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);
|
||||
@@ -1426,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;
|
||||
@@ -1480,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);
|
||||
|
||||
@@ -1534,6 +1532,7 @@ row_activated_cb (CcApplicationsPanel *self,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
update_panel (self, row);
|
||||
g_signal_emit_by_name (self, "sidebar-activated");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1556,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
|
||||
@@ -1569,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))
|
||||
{
|
||||
@@ -1577,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;
|
||||
@@ -1604,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
|
||||
@@ -1725,33 +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, builtin);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin_page);
|
||||
@@ -1760,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);
|
||||
@@ -1774,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);
|
||||
@@ -1783,11 +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, 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);
|
||||
@@ -1811,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)
|
||||
@@ -1843,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,
|
||||
@@ -1852,20 +1909,13 @@ 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");
|
||||
|
||||
@@ -2,403 +2,335 @@
|
||||
<interface>
|
||||
<template class="CcApplicationsPanel" parent="CcPanel">
|
||||
<property name="child">
|
||||
<object class="AdwNavigationView" id="navigation_view">
|
||||
|
||||
<!-- 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"/>
|
||||
</child>
|
||||
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage" id="app_search_stack_page">
|
||||
<!-- Searchbar -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<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>
|
||||
</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="use-underline">True</property>
|
||||
<property name="show-arrow">True</property>
|
||||
<property name="action-name">navigation.push</property>
|
||||
<property name="action-target">'default-apps'</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Apps List -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkStack" id="app_listbox_stack">
|
||||
<property name="vhomogeneous">False</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>
|
||||
<style>
|
||||
<class name="boxed-list" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</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="GtkStack" id="stack">
|
||||
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<!-- Default Apps Settings -->
|
||||
<child>
|
||||
<object class="CcDefaultAppsPage" id="default_apps_page" />
|
||||
</child>
|
||||
<!-- This "fake" empty box is there to show instead of the AdwStatusPage before the panel is initialized -->
|
||||
<child>
|
||||
<object class="GtkBox"/>
|
||||
</child>
|
||||
|
||||
<!-- Removable Media Settings -->
|
||||
<child>
|
||||
<object class="CcRemovableMediaSettings" id="removable_media_settings" />
|
||||
</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>
|
||||
</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>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesPage" id="settings_box">
|
||||
|
||||
<!-- App icon & buttons -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage" id="settings_box">
|
||||
<!-- App icon & buttons -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<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="orientation">vertical</property>
|
||||
<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="GtkImage" id="app_icon_image">
|
||||
<property name="icon-name">org.gnome.Software</property>
|
||||
<property name="pixel-size">96</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="icon-dropshadow" />
|
||||
<class name="pill" />
|
||||
<class name="suggested-action" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel" id="app_name_label">
|
||||
<property name="wrap">True</property>
|
||||
<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="title" />
|
||||
<class name="title-1" />
|
||||
<class name="pill" />
|
||||
</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">
|
||||
<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>
|
||||
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="integration_section">
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="usage_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>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="handler_row">
|
||||
<property name="title" translatable="yes">_File &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 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="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>
|
||||
</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; 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>
|
||||
</template>
|
||||
</object>
|
||||
|
||||
<!-- Built-in Permissions dialog -->
|
||||
<object class="AdwWindow" id="builtin_dialog">
|
||||
@@ -493,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>
|
||||
@@ -519,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>
|
||||
@@ -572,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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcDefaultAppsPage" parent="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Links &amp; Files</property>
|
||||
<property name="description" translatable="yes">Apps which are used to open common links and files</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>
|
||||
@@ -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>
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcRemovableMediaSettings" parent="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Removable Media</property>
|
||||
<property name="description" translatable="yes">Apps which are launched when media or drives are connected</property>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="disable_autostart_row">
|
||||
<property name="title" translatable="yes">D_isable Autostart</property>
|
||||
<property name="subtitle" translatable="yes">Never prompt or start apps on media insertion</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">autorun_never_switch</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="autorun_never_switch">
|
||||
<property name="receives_default">False</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<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="use_underline">True</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="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="hide-on-close">True</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="GtkBox">
|
||||
<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="spacing">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">6</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="other_type_combo_box">
|
||||
<property name="model">other_type_list_store</property>
|
||||
<signal name="changed" handler="on_other_type_combo_box_changed" object="CcRemovableMediaSettings" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="other_action_label">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Action:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="other_action_box">
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Type:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">other_type_combo_box</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -2,13 +2,3 @@ install_data(
|
||||
'scalable/org.gnome.Settings-applications-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-default-apps-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-removable-media-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -143,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),
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<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"/>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
CcSystemPage parent_instance;
|
||||
CcPanel parent_instance;
|
||||
|
||||
GList *toplevels;
|
||||
|
||||
@@ -89,9 +90,8 @@ struct _CcDateTimePage
|
||||
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;
|
||||
GtkWidget *weekday_row;
|
||||
GtkWidget *weekday_switch;
|
||||
@@ -100,15 +100,17 @@ struct _CcDateTimePage
|
||||
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;
|
||||
|
||||
@@ -124,14 +126,19 @@ struct _CcDateTimePage
|
||||
int month; /* index starts from 1 */
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcDateTimePage, cc_date_time_page, CC_TYPE_SYSTEM_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)
|
||||
{
|
||||
@@ -157,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);
|
||||
@@ -187,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;
|
||||
@@ -223,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)
|
||||
@@ -240,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);
|
||||
}
|
||||
|
||||
@@ -249,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,
|
||||
@@ -270,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,
|
||||
@@ -287,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,
|
||||
@@ -304,7 +332,7 @@ set_using_ntp_cb (GObject *source,
|
||||
}
|
||||
|
||||
static void
|
||||
queue_set_datetime (CcDateTimePage *self)
|
||||
queue_set_datetime (CcDateTimePanel *self)
|
||||
{
|
||||
gint64 unixtime;
|
||||
|
||||
@@ -321,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,
|
||||
@@ -334,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)
|
||||
@@ -349,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);
|
||||
}
|
||||
@@ -397,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;
|
||||
@@ -413,7 +443,7 @@ update_timezone (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
get_initial_timezone (CcDateTimePage *self)
|
||||
get_initial_timezone (CcDateTimePanel *self)
|
||||
{
|
||||
const gchar *timezone;
|
||||
|
||||
@@ -431,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);
|
||||
@@ -484,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 ();
|
||||
@@ -494,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);
|
||||
|
||||
@@ -504,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;
|
||||
@@ -523,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;
|
||||
|
||||
@@ -547,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;
|
||||
@@ -596,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;
|
||||
@@ -628,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;
|
||||
@@ -645,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",
|
||||
@@ -657,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))
|
||||
@@ -681,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;
|
||||
@@ -702,7 +732,7 @@ time_changed_cb (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
setup_datetime_dialog (CcDateTimePage *self)
|
||||
setup_datetime_dialog (CcDateTimePanel *self)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
GdkDisplay *display;
|
||||
@@ -732,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:
|
||||
@@ -796,72 +828,68 @@ sort_date_box (GtkListBoxRow *a,
|
||||
}
|
||||
|
||||
static void
|
||||
update_page_summary (CcDateTimePage *self)
|
||||
{
|
||||
gboolean enabled =
|
||||
gtk_switch_get_active (GTK_SWITCH (self->network_time_switch));
|
||||
|
||||
cc_system_page_set_summary (CC_SYSTEM_PAGE (self), enabled ?
|
||||
_("Automatic date and time") :
|
||||
gtk_label_get_text (self->timezone_label));
|
||||
}
|
||||
|
||||
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_switch);
|
||||
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_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, date_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, seconds_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, week_numbers_switch);
|
||||
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);
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_page_summary);
|
||||
|
||||
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,8 +939,6 @@ cc_date_time_page_init (CcDateTimePage *self)
|
||||
/* setup_timezone_dialog (self); */
|
||||
setup_datetime_dialog (self);
|
||||
|
||||
update_page_summary (self);
|
||||
|
||||
/* set up network time switch */
|
||||
bind_switch_to_row (self,
|
||||
self->network_time_switch,
|
||||
@@ -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,20 +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 "cc-system-page.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, CcSystemPage)
|
||||
#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
|
||||
@@ -56,20 +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="use-underline">True</property>
|
||||
<property name="title" translatable="yes">Month</property>
|
||||
<binding name="secondary-label">
|
||||
<lookup name="string" type="GtkStringObject">
|
||||
<lookup name="selected-item">month_model</lookup>
|
||||
@@ -95,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>
|
||||
|
||||
@@ -114,9 +122,7 @@
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
<template class="CcDateTimePage" parent="CcSystemPage">
|
||||
<property name="title" translatable="yes">Date & Time</property>
|
||||
<property name="tag">system-date-time-page</property>
|
||||
<template class="CcDateTimePanel" parent="CcPanel">
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
@@ -142,7 +148,6 @@
|
||||
<child>
|
||||
<object class="GtkSwitch" id="network_time_switch">
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::active" handler="update_page_summary" object="CcDateTimePage" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -210,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>
|
||||
@@ -247,7 +237,7 @@
|
||||
<property name="description" translatable="yes">Control how the time and date is shown in the top bar</property>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">_Week Day</property>
|
||||
<property name="title" translatable="yes">Week Day</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">weekday_switch</property>
|
||||
<child>
|
||||
@@ -259,7 +249,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">D_ate</property>
|
||||
<property name="title" translatable="yes">Date</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">date_switch</property>
|
||||
<child>
|
||||
@@ -271,7 +261,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">_Seconds</property>
|
||||
<property name="title" translatable="yes">Seconds</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">seconds_switch</property>
|
||||
<child>
|
||||
@@ -283,8 +273,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Week _Numbers</property>
|
||||
<property name="subtitle" translatable="yes">Shown in the dropdown calendar</property>
|
||||
<property name="title" translatable="yes">Week Numbers</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">week_numbers_switch</property>
|
||||
<child>
|
||||
@@ -317,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">
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
10
panels/datetime/datetime.gresource.xml
Normal file
10
panels/datetime/datetime.gresource.xml
Normal 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>
|
||||
16
panels/datetime/gnome-datetime-panel.desktop.in
Normal file
16
panels/datetime/gnome-datetime-panel.desktop.in
Normal 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
|
||||
@@ -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')
|
||||
)
|
||||
|
Before Width: | Height: | Size: 820 B After Width: | Height: | Size: 820 B |
123
panels/datetime/meson.build
Normal file
123
panels/datetime/meson.build
Normal 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
Reference in New Issue
Block a user