Compare commits
123 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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,6 +32,13 @@ stages:
|
||||
.Build procedure: &build_procedure
|
||||
echo "== Building ==" &&
|
||||
dnf install -y dnf5-plugins &&
|
||||
git clone --depth 1 --branch 4.12.5 https://gitlab.gnome.org/GNOME/gtk.git &&
|
||||
cd gtk &&
|
||||
dnf5 builddep -y gtk4 &&
|
||||
meson setup . _build -Dprefix=/usr -Dlibdir=lib64 &&
|
||||
ninja -C _build install &&
|
||||
cd .. &&
|
||||
rm -rf _build/ &&
|
||||
meson . _build ${BUILD_OPTS} -Dprofile=development &&
|
||||
ninja -C _build 2>&1 | tee compilation.log
|
||||
|
||||
@@ -52,8 +59,8 @@ stages:
|
||||
# stable branch.
|
||||
# Could probably also switch away from rawhide,
|
||||
# to stable fedora branch as well.
|
||||
FDO_DISTRIBUTION_TAG: '2024-02-08.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: rawhide
|
||||
FDO_DISTRIBUTION_TAG: '2024-04-16.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: 39
|
||||
|
||||
#############################################
|
||||
# Create CI Docker Images #
|
||||
@@ -80,7 +87,6 @@ build.container.fedora@x86_64:
|
||||
accountsservice-devel
|
||||
cheese-libs-devel
|
||||
chrpath
|
||||
clang-tools-extra
|
||||
colord-devel colord-gtk-devel
|
||||
cups-devel
|
||||
desktop-file-utils
|
||||
@@ -92,6 +98,7 @@ build.container.fedora@x86_64:
|
||||
gobject-introspection-devel
|
||||
gnome-bluetooth-libs-devel
|
||||
gnome-desktop3-devel
|
||||
gnome-online-accounts-devel
|
||||
grilo-devel
|
||||
gsettings-desktop-schemas-devel
|
||||
gsound-devel
|
||||
@@ -124,13 +131,14 @@ build.container.fedora@x86_64:
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
libsecret-devel
|
||||
geocode-glib2-devel
|
||||
libgweather4-devel
|
||||
geocode-glib2-devel
|
||||
lcms2-devel
|
||||
geoclue2-devel
|
||||
libnotify-devel
|
||||
alsa-lib-devel
|
||||
nss-devel
|
||||
gcr3-devel
|
||||
gcr-devel
|
||||
setxkbmap
|
||||
appstream-devel
|
||||
@@ -177,12 +185,6 @@ build.container.fedora@x86_64:
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-online-accounts.git && \
|
||||
cd gnome-online-accounts && \
|
||||
meson . _build --prefix=/usr -Dfedora=true && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
dnf remove -y systemtap-runtime
|
||||
|
||||
##
|
||||
@@ -220,21 +222,8 @@ build:
|
||||
##
|
||||
# Stage: Test
|
||||
#
|
||||
# Runs static checks.
|
||||
# Runs the unit tests.
|
||||
##
|
||||
style-check-diff:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
needs:
|
||||
- build.container.fedora@x86_64
|
||||
stage: test
|
||||
when: always
|
||||
allow_failure: true
|
||||
script:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
test:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
|
||||
@@ -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 GNOME Settings’ coding style: in particular, it cannot align
|
||||
# function arguments. The documented coding style for GNOME Settings takes priority over
|
||||
# clang-format suggestions. Hopefully we can eventually improve clang-format to
|
||||
# be configurable enough for our coding style. 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}
|
||||
287
NEWS
287
NEWS
@@ -1,231 +1,92 @@
|
||||
=================
|
||||
Version 46.beta.1
|
||||
=================
|
||||
============
|
||||
Version 45.4
|
||||
============
|
||||
|
||||
Exceptional release to fix translations
|
||||
https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2893
|
||||
|
||||
=================
|
||||
Version 46.beta.1
|
||||
=================
|
||||
|
||||
Exceptional release to include gnome-online-accounts changes
|
||||
(Freeze break exception https://gitlab.gnome.org/Teams/Releng/freeze-breaks/-/issues/164)
|
||||
|
||||
===============
|
||||
Version 46.beta
|
||||
===============
|
||||
|
||||
- Drop pkexec dependency
|
||||
- Bump gcr dependency to gcr4
|
||||
- Reorder sidebar/panel list
|
||||
- Use g_clear_handle_id with g_source_remove to remove GSources
|
||||
- Add CcHostname as a wrapper to interact with system-hostnamed
|
||||
- Remove periods in subtitles/descriptions/labels according to the HIG
|
||||
- Various string/sentence rewording (for clarity)
|
||||
- Various style changes in symbolic icons
|
||||
- Various ports of custom widgets to modern libadwaita alternatives
|
||||
- Various new mnemonics added
|
||||
- Various CI fixes
|
||||
- Various translation updates
|
||||
- CI fixes
|
||||
|
||||
Accessibility
|
||||
- Expose new "show-status-shapes" setting
|
||||
- Rephrase overamplification string in the "Hearing" settings
|
||||
- Stop tracking old GTK theme
|
||||
- Stop forcing HighContrast icon theme (The theme is considered deprecated)
|
||||
- Improve accessibility of "Typing" settings sliders
|
||||
|
||||
Apps
|
||||
- Tweak headings & descriptions from Default Apps sections
|
||||
- Tweak the autorun-never option design (inverting the autorun-never option logic)
|
||||
- Use modern libadwaita widgets in the Removable Media settings
|
||||
|
||||
Keyboard
|
||||
- Use AdwActionRow to show the key modifier options (improves accessibility)
|
||||
|
||||
Network
|
||||
- Fix missing VPN entries
|
||||
|
||||
Mouse
|
||||
- Add "Test Settings" button to the body of the panel
|
||||
- Modernize mouse test dialog (adds secondary-click test)
|
||||
|
||||
Printers
|
||||
- Add padding to the sidebar items from "Printer Options"
|
||||
- Add .suggested-action style class to "Test Page" button
|
||||
Datetime
|
||||
- Prevent unnecessary calls to auto time synchronization
|
||||
|
||||
Privacy
|
||||
- Hide non-functional microphone panel
|
||||
- Fix F1/Help link to panel's documentation
|
||||
- Fix issues with writting camera/location permission-store data
|
||||
- Fix issue with app listing as a result of flatpak permission-reset
|
||||
|
||||
Search
|
||||
- Add commandline parameter for opening the Search Locations dialog directly
|
||||
- Stop removing non-existent folders from tracker
|
||||
- Expose single directory setting
|
||||
- Add placeholder for custom locations
|
||||
- Set title for non-existent bookmarks
|
||||
- Always show switch for default/bookmarks
|
||||
- Handle unset XDG dirs
|
||||
- Tweak search locations labels
|
||||
============
|
||||
Version 45.3
|
||||
============
|
||||
|
||||
Sharing
|
||||
- Fix alignment of networks section in the File/Media sharing dialogs
|
||||
- Use edit-delete-symbolic in networks list rather than window-close-symbolic
|
||||
- Move main switches from dialog headerbars into the dialog's content area
|
||||
|
||||
Sound
|
||||
- Show radio buttons as prefix for the Alert Sound rows
|
||||
- Add tooltips to all speaker test buttons
|
||||
|
||||
System
|
||||
- Move "Remote Login" from sharing panel to System (now named "Secure Shell")
|
||||
- Use polkit to request permissions to enable/disable sshd
|
||||
- Create CcSystemDetailsWindow upon opening (speed up System panel startup time)
|
||||
- Fix crash in About page after dark mode switch
|
||||
- Don't show Remote Desktop settings when backend is not available
|
||||
- Show gnome-control-center version on the "GNOME Version" row in the About page
|
||||
- Fix language chooser dialog not closing in Users page
|
||||
|
||||
Wacom
|
||||
- Port some widgets to modern libadwaita alternatives
|
||||
- Switch to using a dialog for stylus button assignments
|
||||
- Highlight the currently active stylus
|
||||
- Give proper ids and classes to the stylus SVG components
|
||||
- Provide connector name for disambiguation
|
||||
- Drop list to handle pads
|
||||
- Pair only builtin pads with tablets
|
||||
- Prefer the stylus over the eraser
|
||||
- Don't call the standard styli "Standard stylus"
|
||||
|
||||
Wi-Fi
|
||||
- Show password when sharing QR Code
|
||||
- Fix crash with toast notifications in the Saved Networks dialog
|
||||
|
||||
================
|
||||
Version 46.alpha
|
||||
================
|
||||
|
||||
- Introduce the new "System" panel, grouping the settings of Region & Language, Date & Time, Users, Remote Desktop, and About.
|
||||
- Add an "About Settings" dialog
|
||||
- Various appdata improvements
|
||||
- Various mnemonics added
|
||||
- Various tooltips added
|
||||
- Various CI fixes
|
||||
- Various accessibility fixes
|
||||
- Make "gnome-control-center --version" work on non-supported environments
|
||||
- Bump meson dependency to >= 0.58
|
||||
- Disable "deprecated-declarations" by default for builds
|
||||
- Introduce -Ddeprecated-declarations=enabled meson build option
|
||||
- Add CODEOWNERS file
|
||||
|
||||
Accessibility
|
||||
- Rename "Overlay Scrollbars" to "Always Show Scrollbars" and invert this setting logic
|
||||
- Reword the "Accessibility Menu" row
|
||||
- Add description text to "Cursor Size" dialog
|
||||
- Port Cursor Size dialog to AdwWindow
|
||||
- Use AdwSpinRow in Zoom -> Magnification Factor row
|
||||
|
||||
Appearance
|
||||
- Improve overall load and resize performance of background thumbnails
|
||||
- Improve background chooser performance
|
||||
- Make background preview thumbnails sharpier
|
||||
|
||||
Apps
|
||||
- Drop sidebar by implementing a new mockup with a search bar inside the panel
|
||||
- Move "Default Apps" and "Removable Media" panels into the "Apps" panel
|
||||
- Add a banner indicating when an app isn't sandboxed
|
||||
- Separate the "Required Permissions" row into its own section
|
||||
- Add headings to rows from the app settings section
|
||||
- Port "Removable Media Settings" row to AdwSwitchRow
|
||||
- Ignore symlinks when measuring cache/data size to improve accuracy
|
||||
- Use "computer-fail-symbolic" icon instead of GNOME Software's icon
|
||||
- Fix "File & Link Associations" crash
|
||||
- Fix "File & Link Associations" UI not updating
|
||||
- Fix launching an app page from the command line (ex.: "gnome-control-center application $APP_ID)
|
||||
- Replace snapd-glib with a native implementation
|
||||
|
||||
Cellular
|
||||
- Various HIG compliance changes
|
||||
|
||||
Date & Time
|
||||
- Add description to "Week Numbers" row
|
||||
|
||||
Displays
|
||||
- Port custom switch rows to AdwSwitchRow
|
||||
|
||||
Keyboard
|
||||
- Add "Left Ctrl" key to Compose Key options
|
||||
- Add "Insert" key to Compose Key options
|
||||
- Port Shortcut Editor from deprecated GtkDialog to AdwWindow/AdwToolbarView
|
||||
- Fix showing window decoration buttons when showing the "Unsupported network daemon" status page
|
||||
- Show title buttons at the initial state of "Set Shortcuts" dialog
|
||||
- Add visual outline to shortcut graphic arrows
|
||||
|
||||
Mouse
|
||||
- Add "Secondary Click" option for Touchpads (aka "Click Method")
|
||||
- Add "Disable While Typing" setting to Touchpad page
|
||||
- Update edge-scroll animation to represent better dimensions of physical devices
|
||||
- Port custom switch rows to AdwSwitchRow
|
||||
- Split "Scroll Method" and "Direction" into separate row groups
|
||||
- Prevent test window arrows from interferingf with scrolling events
|
||||
- Fix illustrations looking blurry on small window sizes
|
||||
- Fix the linked-style of the primary mouse button setting to work on RTL languages
|
||||
|
||||
Network
|
||||
- Use period as thousands separator on network speed label
|
||||
- Avoid critical warning for floating reference in hotspot dialog
|
||||
- Various UI spacing and alignment changes in the connection editor pages
|
||||
- Share WPA3 (SAE) networks with QRCode
|
||||
- Hide QRCode icon when connection not successful
|
||||
- Handle bluetooth device connections ourselves (instead of depending on NM connection-editor)
|
||||
- Don't show "Saved Wi-Fi Networks" row when there's nothing to show
|
||||
- Use a "Undo" toast to allow users to undo forgetting a network in "Saved Wi-Fi Networks"
|
||||
- Make the "forget network" button show only an icon (instead of a icon+label)
|
||||
- Fix sensitivity of DNS and route configuration widgets
|
||||
- Warn user if both automatic and manual DNS is configured
|
||||
- Unset DNS entry errors when entry is empty
|
||||
- Disable Wi-Fi Hotspot row when Wi-Fi is not active
|
||||
|
||||
Notifications
|
||||
- Stop listing system services on the panel
|
||||
|
||||
Online Accounts
|
||||
- Various memory leak fixes
|
||||
|
||||
Power
|
||||
- Add mnemonics to help navigate the automatic suspend dialog
|
||||
- Modernize the Suspend dialog
|
||||
|
||||
Privacy & Security
|
||||
- Rename panel from "Privacy" to "Privacy & Security"
|
||||
- Update panel description text
|
||||
- Rename "Location Services" page to "Location"
|
||||
- Make icons larger in Location/Camera/Microphone pages
|
||||
- Make page visibility checks cancellable to avoid crashes
|
||||
- Fix crashes on Camera and Firmware Security pages
|
||||
- Rename location switch title to "Automatic Device Location"
|
||||
- Reword and re-style the "Privacy" policy text
|
||||
Datetime
|
||||
- Fix build with -Wincompatible-pointer-types
|
||||
|
||||
Region
|
||||
- Preview measurement format in current locale
|
||||
- Prevent preview crash from accessing invalid pointer
|
||||
|
||||
Remote Desktop
|
||||
- Use "rdp" instead of "ms-rd" for hostname URL
|
||||
- Add documentation link to instruct how to use remote desktop
|
||||
Wifi
|
||||
- Fix build with -Wincompatible-pointer-types
|
||||
|
||||
Sharing
|
||||
- Make panel adaptative
|
||||
- Use AdwPreferencesPage/AdwPreferencesGroup in all dialogs
|
||||
============
|
||||
Version 45.2
|
||||
============
|
||||
|
||||
Apps
|
||||
- Fix status page glitch on initialization
|
||||
- Fix "File and Link Association" interface not reflecting changes
|
||||
|
||||
Background
|
||||
- Improve background preview and chooser performance
|
||||
|
||||
Default Apps
|
||||
- Fix undesired resetting of default apps during startup
|
||||
|
||||
Mouse
|
||||
- Fix interference issue with scroll event in Mouse Test window
|
||||
|
||||
Network
|
||||
- Close network editor when using non-native nm-connection-editor
|
||||
- Show decoration buttons on empty-state (no network device found page)
|
||||
- Share WPA3 (SAE) networks with QR Code
|
||||
- Hide QR Code icon when connection is not successful
|
||||
- Remove deprecated 'wpa-none'
|
||||
- Fix route label alignments
|
||||
|
||||
Privacy
|
||||
- Fix crash from free bug in the Camera page
|
||||
- Fix potential crash on Bolt page visibility
|
||||
|
||||
Region
|
||||
- Show preview measurement format in current locale
|
||||
|
||||
Sound
|
||||
- Update mute state when setting mixer control for a stream
|
||||
|
||||
Users
|
||||
- Port to AdwNavigationView/Page widgets
|
||||
- Move into the "System" panel
|
||||
- Use AdwAvatar to generate default user icon and mark generated avatars as such
|
||||
- Show tooltip information for the Avatar widget
|
||||
|
||||
Wacom
|
||||
- Update illustration style
|
||||
- Generate a smooth pressure curve instead of just 7
|
||||
- Introduce mark indicating the center-point of the stylus pressure curve
|
||||
- Extend ther pressurecurve range by 25% in each direction
|
||||
- Use the ExpressKey Remote name for the EKR
|
||||
============
|
||||
Version 45.1
|
||||
============
|
||||
|
||||
About
|
||||
- Add more types of processor support
|
||||
|
||||
Accessibility
|
||||
- Make Cursor Size dialog close on Escape key
|
||||
|
||||
Keyboard
|
||||
- Allow closing Shortcuts dialog with Escape key
|
||||
|
||||
Mouse
|
||||
- Fix linked style of primary mouse button in RTL languages
|
||||
- Avoid making videos blurry
|
||||
|
||||
Network
|
||||
- Fix editing connections without a device
|
||||
- Revert "Disable DNS entry if automatic DNS option is enabled"
|
||||
|
||||
============
|
||||
Version 45.0
|
||||
|
||||
@@ -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,52 +0,0 @@
|
||||
# These are the people responsible for Settings panels and domain-specific
|
||||
# parts of the GNOME Settings codebase.
|
||||
#
|
||||
# If you open a merge request for files listed here, please add the following
|
||||
# people to the list of reviewers.
|
||||
|
||||
# The syntax of this file is defined by GitLab:
|
||||
# https://docs.gitlab.com/ee/user/project/code_owners.html
|
||||
# Which, in turn, is similar to the .gitignore and .gitattributes files:
|
||||
#
|
||||
# - comments start with `#`
|
||||
# - the first column contains paths and globs
|
||||
# - the second column contains GitLab user names or email addresses,
|
||||
# separated by spaces
|
||||
#
|
||||
# The last matching glob (rather than the union of *all* matching globs) gives
|
||||
# the owners of a piece of code.
|
||||
#
|
||||
# If you want to be responsible for code reviews in specific sections of
|
||||
# the GNOME Settings code base, add yourself here.
|
||||
|
||||
# General maintainers
|
||||
* @felipeborges @robert_ancell
|
||||
|
||||
# Panels
|
||||
## About
|
||||
panels/info-overview/* @cyberphantom52
|
||||
|
||||
## Accessibility
|
||||
panels/universal-access/* @pksadiq
|
||||
|
||||
## Appearance
|
||||
panels/background/* @velsinki
|
||||
|
||||
## Apps
|
||||
panels/applications/cc-default-apps-* @nishalkulkarni
|
||||
panels/applications/cc-removable-media-settings* @nishalkulkarni
|
||||
|
||||
## Bluetooth
|
||||
panels/bluetooth/* @hadess
|
||||
|
||||
## Printers
|
||||
panels/printers/* @mkasik
|
||||
|
||||
## Sound
|
||||
panels/sound/* @melix99
|
||||
|
||||
## Wacom
|
||||
panels/wacom/* @carlosg
|
||||
|
||||
## WWAN (Cellular)
|
||||
panels/wwan/* @pksadiq
|
||||
@@ -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>
|
||||
|
||||
27
meson.build
27
meson.build
@@ -1,8 +1,8 @@
|
||||
project(
|
||||
'gnome-control-center', 'c',
|
||||
version : '46.beta.2',
|
||||
version : '45.4',
|
||||
license : 'GPL2+',
|
||||
meson_version : '>= 0.58.0'
|
||||
meson_version : '>= 0.57.0'
|
||||
)
|
||||
|
||||
control_center_prefix = get_option('prefix')
|
||||
@@ -39,15 +39,12 @@ else
|
||||
endif
|
||||
application_id = 'org.gnome.Settings@0@'.format(profile)
|
||||
|
||||
version_split = meson.project_version().split('.')
|
||||
|
||||
# defines
|
||||
set_defines = [
|
||||
# package
|
||||
['PACKAGE', meson.project_name()],
|
||||
['PACKAGE_VERSION', meson.project_version()],
|
||||
['VERSION', meson.project_version()],
|
||||
['MAJOR_VERSION', version_split[0]],
|
||||
['PROFILE', get_option('profile')],
|
||||
# i18n
|
||||
['GETTEXT_PACKAGE', control_center_gettext]
|
||||
@@ -76,15 +73,6 @@ config_h.set('USER_DIR_MODE', '0700',
|
||||
# compiler flags
|
||||
common_flags = ['-DHAVE_CONFIG_H']
|
||||
|
||||
# We have so many deprecation warnings that it becomes impossible to notice any other useful
|
||||
# warning, thus making the compiler output completely useless. Ideally, we should fix all
|
||||
# of those but, until then, it's better to add this flag so that we avoid adding even more
|
||||
# warnings by accident. If you want to fix some of those, just build Settings with:
|
||||
# meson _build -Ddeprecated-declarions=enabled
|
||||
if get_option('deprecated-declarations').disabled()
|
||||
common_flags += '-Wno-deprecated-declarations'
|
||||
endif
|
||||
|
||||
# Only add this when optimizing is enabled (default)
|
||||
optimized_src = '''
|
||||
#if __OPTIMIZE__ == 0
|
||||
@@ -126,7 +114,7 @@ libgvc = subproject(
|
||||
)
|
||||
libgvc_dep = libgvc.get_variable('libgvc_dep')
|
||||
|
||||
goa_req_version = '>= 3.49.1'
|
||||
goa_req_version = '>= 3.25.3'
|
||||
pulse_req_version = '>= 2.0'
|
||||
|
||||
gtk_dep = dependency(
|
||||
@@ -179,7 +167,7 @@ accounts_dep = dependency('accountsservice', version: '>= 0.6.39')
|
||||
colord_dep = dependency('colord', version: '>= 0.1.34')
|
||||
gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: '>= 2.23.0')
|
||||
gio_dep = dependency('gio-2.0')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.76.6')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.75.0')
|
||||
gnome_desktop_dep = dependency('gnome-desktop-4')
|
||||
gnome_bg_dep = dependency('gnome-bg-4')
|
||||
gnome_rr_dep = dependency('gnome-rr-4')
|
||||
@@ -194,7 +182,7 @@ gudev_dep = dependency('gudev-1.0', version: '>= 232')
|
||||
x11_dep = dependency('x11', version: '>= 1.8')
|
||||
xi_dep = dependency('xi', version: '>= 1.2')
|
||||
epoxy_dep = dependency('epoxy')
|
||||
gcr_dep = dependency('gcr-4', version: '>= 4.1.0')
|
||||
gcr_dep = dependency('gcr-base-3')
|
||||
pwquality_dep = dependency('pwquality', version: '>= 1.2.2')
|
||||
|
||||
m_dep = cc.find_library('m')
|
||||
@@ -258,8 +246,9 @@ config_h.set10('HAVE_FN_EXPLICIT_BZERO',
|
||||
# Snap support
|
||||
enable_snap = get_option('snap')
|
||||
if enable_snap
|
||||
json_glib_dep = dependency('json-glib-1.0')
|
||||
libsoup_dep = dependency('libsoup-3.0')
|
||||
snapd_glib_deps = [
|
||||
dependency('snapd-glib-2', version: '>= 1.62')
|
||||
]
|
||||
endif
|
||||
config_h.set('HAVE_SNAP', enable_snap,
|
||||
description: 'Define to 1 if Snap support is enabled')
|
||||
|
||||
@@ -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"
|
||||
@@ -54,21 +54,11 @@ struct _CcApplicationsPanel
|
||||
{
|
||||
CcPanel parent;
|
||||
|
||||
CcDefaultAppsPage *default_apps_page;
|
||||
AdwSwitchRow *autorun_never_row;
|
||||
CcRemovableMediaSettings *removable_media_settings;
|
||||
|
||||
AdwNavigationView *navigation_view;
|
||||
AdwNavigationPage *app_settings_page;
|
||||
GtkListBox *app_listbox;
|
||||
GtkEntry *app_search_entry;
|
||||
GtkWidget *empty_search_placeholder;
|
||||
GtkStack *app_listbox_stack;
|
||||
AdwNavigationPage *sidebar_box;
|
||||
GtkListBox *sidebar_listbox;
|
||||
GtkEntry *sidebar_search_entry;
|
||||
GAppInfoMonitor *monitor;
|
||||
gulong monitor_id;
|
||||
GListModel *app_model;
|
||||
GListModel *filter_model;
|
||||
GtkFilter *filter;
|
||||
#ifdef HAVE_MALCONTENT
|
||||
GCancellable *cancellable;
|
||||
|
||||
@@ -88,17 +78,16 @@ struct _CcApplicationsPanel
|
||||
GtkLabel *app_name_label;
|
||||
GtkButton *launch_button;
|
||||
GtkButton *view_details_button;
|
||||
AdwBanner *sandbox_banner;
|
||||
GtkWidget *sandbox_info_button;
|
||||
|
||||
GDBusProxy *perm_store;
|
||||
GSettings *media_handling_settings;
|
||||
GtkListBoxRow *perm_store_pending_row;
|
||||
GSettings *notification_settings;
|
||||
GSettings *location_settings;
|
||||
GSettings *privacy_settings;
|
||||
GSettings *search_settings;
|
||||
|
||||
GtkStack *stack;
|
||||
GtkWidget *empty_box;
|
||||
GtkWidget *settings_box;
|
||||
GtkButton *install_button;
|
||||
|
||||
AdwPreferencesGroup *integration_section;
|
||||
@@ -117,12 +106,13 @@ struct _CcApplicationsPanel
|
||||
AdwSwitchRow *shortcuts;
|
||||
AdwSwitchRow *microphone;
|
||||
CcInfoRow *no_microphone;
|
||||
AdwPreferencesGroup *other_permissions_section;
|
||||
CcInfoRow *builtin;
|
||||
GtkWindow *builtin_dialog;
|
||||
AdwPreferencesPage *builtin_page;
|
||||
GtkListBox *builtin_list;
|
||||
#ifdef HAVE_SNAP
|
||||
GList *snap_permission_rows;
|
||||
#endif
|
||||
|
||||
GtkButton *handler_reset;
|
||||
GtkWindow *handler_dialog;
|
||||
@@ -709,9 +699,11 @@ add_snap_permissions (CcApplicationsPanel *self,
|
||||
const gchar *app_id)
|
||||
{
|
||||
const gchar *snap_name;
|
||||
g_autoptr(CcSnapdClient) client = NULL;
|
||||
g_autoptr(JsonArray) plugs = NULL;
|
||||
g_autoptr(JsonArray) slots = NULL;
|
||||
g_autoptr(SnapdClient) client = NULL;
|
||||
g_autoptr(GPtrArray) interfaces = NULL;
|
||||
g_autoptr(GPtrArray) plugs = NULL;
|
||||
g_autoptr(GPtrArray) slots = NULL;
|
||||
SnapdInterface *interface = NULL;
|
||||
gint added = 0;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GError) interfaces_error = NULL;
|
||||
@@ -720,20 +712,31 @@ add_snap_permissions (CcApplicationsPanel *self,
|
||||
return FALSE;
|
||||
snap_name = app_id + strlen (PORTAL_SNAP_PREFIX);
|
||||
|
||||
client = cc_snapd_client_new ();
|
||||
client = snapd_client_new ();
|
||||
|
||||
if (!cc_snapd_client_get_all_connections_sync (client, &plugs, &slots, cc_panel_get_cancellable (CC_PANEL (self)), &error))
|
||||
interfaces = snapd_client_get_interfaces2_sync (client,
|
||||
SNAPD_GET_INTERFACES_FLAGS_NONE,
|
||||
NULL,
|
||||
NULL, &interfaces_error);
|
||||
if (interfaces == NULL)
|
||||
g_warning ("Failed to get snap interfaces: %s", interfaces_error->message);
|
||||
|
||||
if (!snapd_client_get_connections2_sync (client,
|
||||
SNAPD_GET_CONNECTIONS_FLAGS_SELECT_ALL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
&plugs, &slots,
|
||||
NULL, &error))
|
||||
{
|
||||
g_warning ("Failed to get snap connections: %s", error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (guint i = 0; i < json_array_get_length (plugs); i++)
|
||||
for (int i = 0; i < plugs->len; i++)
|
||||
{
|
||||
JsonObject *plug = json_array_get_object_element (plugs, i);
|
||||
const gchar *plug_interface;
|
||||
SnapdPlug *plug = g_ptr_array_index (plugs, i);
|
||||
CcSnapRow *row;
|
||||
g_autoptr(JsonArray) available_slots = NULL;
|
||||
g_autoptr(GPtrArray) available_slots = NULL;
|
||||
const gchar * const hidden_interfaces[] = { "content",
|
||||
"desktop", "desktop-legacy",
|
||||
"mir",
|
||||
@@ -743,25 +746,34 @@ add_snap_permissions (CcApplicationsPanel *self,
|
||||
NULL };
|
||||
|
||||
/* Skip if not relating to this snap */
|
||||
if (g_strcmp0 (json_object_get_string_member (plug, "snap"), snap_name) != 0)
|
||||
if (g_strcmp0 (snapd_plug_get_snap (plug), snap_name) != 0)
|
||||
continue;
|
||||
|
||||
/* Ignore interfaces that are too low level to make sense to show or disable */
|
||||
plug_interface = json_object_get_string_member (plug, "interface");
|
||||
if (g_strv_contains (hidden_interfaces, plug_interface))
|
||||
if (g_strv_contains (hidden_interfaces, snapd_plug_get_interface (plug)))
|
||||
continue;
|
||||
|
||||
available_slots = json_array_new ();
|
||||
for (guint j = 0; j < json_array_get_length (slots); j++)
|
||||
available_slots = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
for (int j = 0; j < slots->len; j++)
|
||||
{
|
||||
JsonObject *slot = json_array_get_object_element (slots, j);
|
||||
if (g_strcmp0 (plug_interface, json_object_get_string_member (slot, "interface")) != 0)
|
||||
SnapdSlot *slot = g_ptr_array_index (slots, j);
|
||||
if (g_strcmp0 (snapd_plug_get_interface (plug), snapd_slot_get_interface (slot)) != 0)
|
||||
continue;
|
||||
|
||||
json_array_add_object_element (available_slots, slot);
|
||||
g_ptr_array_add (available_slots, g_object_ref (slot));
|
||||
}
|
||||
|
||||
row = cc_snap_row_new (cc_panel_get_cancellable (CC_PANEL (self)), plug, available_slots);
|
||||
if (interfaces != NULL)
|
||||
{
|
||||
for (int j = 0; j < interfaces->len; j++)
|
||||
{
|
||||
SnapdInterface *i = g_ptr_array_index (interfaces, j);
|
||||
if (g_strcmp0 (snapd_interface_get_name (i), snapd_plug_get_interface (plug)) == 0)
|
||||
interface = i;
|
||||
}
|
||||
}
|
||||
|
||||
row = cc_snap_row_new (cc_panel_get_cancellable (CC_PANEL (self)), interface, plug, available_slots);
|
||||
adw_preferences_group_add (self->integration_section, GTK_WIDGET (row));
|
||||
self->snap_permission_rows = g_list_prepend (self->snap_permission_rows, row);
|
||||
added++;
|
||||
@@ -771,22 +783,6 @@ add_snap_permissions (CcApplicationsPanel *self,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
update_sandbox_banner (CcApplicationsPanel *self,
|
||||
const gchar *display_name,
|
||||
gboolean is_sandboxed)
|
||||
{
|
||||
g_autofree gchar *sandbox_banner_message = NULL;
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->sandbox_banner), !is_sandboxed);
|
||||
if (is_sandboxed)
|
||||
return;
|
||||
|
||||
/* Translators: %s is an app name. (e.g. "Firefox is not sandboxed") */
|
||||
sandbox_banner_message = g_strdup_printf (_("%s is not sandboxed"), display_name);
|
||||
adw_banner_set_title (self->sandbox_banner, sandbox_banner_message);
|
||||
}
|
||||
|
||||
static gint
|
||||
add_static_permission_row (CcApplicationsPanel *self,
|
||||
const gchar *title,
|
||||
@@ -816,14 +812,9 @@ add_static_permissions (CcApplicationsPanel *self,
|
||||
g_autofree gchar *str = NULL;
|
||||
gint added = 0;
|
||||
g_autofree gchar *text = NULL;
|
||||
gboolean is_sandboxed, is_snap = FALSE;
|
||||
|
||||
is_snap = app_id && g_str_has_prefix (app_id, PORTAL_SNAP_PREFIX);
|
||||
if (app_id && !is_snap)
|
||||
if (app_id && !g_str_has_prefix (app_id, PORTAL_SNAP_PREFIX))
|
||||
keyfile = get_flatpak_metadata (app_id);
|
||||
|
||||
is_sandboxed = (keyfile != NULL) || is_snap;
|
||||
update_sandbox_banner (self, g_app_info_get_display_name (info), is_sandboxed);
|
||||
if (keyfile == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -866,7 +857,7 @@ add_static_permissions (CcApplicationsPanel *self,
|
||||
static void
|
||||
remove_static_permissions (CcApplicationsPanel *self)
|
||||
{
|
||||
gtk_list_box_remove_all (self->builtin_list);
|
||||
listbox_remove_all (self->builtin_list);
|
||||
}
|
||||
|
||||
/* --- header section --- */
|
||||
@@ -968,9 +959,9 @@ update_integration_section (CcApplicationsPanel *self,
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->no_location), set && disabled);
|
||||
has_any |= set;
|
||||
|
||||
#ifdef HAVE_SNAP
|
||||
#ifdef HAVE_SNAP
|
||||
has_any |= add_snap_permissions (self, info, portal_app_id);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1003,10 +994,15 @@ unset_cb (CcApplicationsPanel *self,
|
||||
GtkButton *button)
|
||||
{
|
||||
const gchar *type;
|
||||
GtkListBoxRow *selected;
|
||||
GAppInfo *info;
|
||||
|
||||
selected = gtk_list_box_get_selected_row (self->sidebar_listbox);
|
||||
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (selected));
|
||||
|
||||
type = (const gchar *)g_object_get_data (G_OBJECT (button), "type");
|
||||
|
||||
g_app_info_remove_supports_type (self->current_app_info, type, NULL);
|
||||
g_app_info_remove_supports_type (info, type, NULL);
|
||||
update_handler_dialog (self, self->current_app_info);
|
||||
}
|
||||
|
||||
@@ -1112,10 +1108,15 @@ app_info_recommended_for (GAppInfo *info,
|
||||
static void
|
||||
handler_reset_cb (CcApplicationsPanel *self)
|
||||
{
|
||||
GtkListBoxRow *selected;
|
||||
GAppInfo *info;
|
||||
const gchar **types;
|
||||
gint i;
|
||||
|
||||
types = g_app_info_get_supported_types (self->current_app_info);
|
||||
selected = gtk_list_box_get_selected_row (self->sidebar_listbox);
|
||||
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (selected));
|
||||
|
||||
types = g_app_info_get_supported_types (info);
|
||||
if (types == NULL || types[0] == NULL)
|
||||
return;
|
||||
|
||||
@@ -1123,7 +1124,7 @@ handler_reset_cb (CcApplicationsPanel *self)
|
||||
for (i = 0; types[i]; i++)
|
||||
{
|
||||
gchar *ctype = g_content_type_from_mime_type (types[i]);
|
||||
g_app_info_add_supports_type (self->current_app_info, ctype, NULL);
|
||||
g_app_info_add_supports_type (info, ctype, NULL);
|
||||
}
|
||||
g_signal_handler_unblock (self->monitor, self->monitor_id);
|
||||
g_signal_emit_by_name (self->monitor, "changed");
|
||||
@@ -1235,23 +1236,6 @@ on_storage_row_activated_cb (CcApplicationsPanel *self)
|
||||
gtk_window_present (self->storage_dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
on_items_changed_cb (GListModel *list,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer data)
|
||||
{
|
||||
CcApplicationsPanel *self = data;
|
||||
|
||||
if (g_list_model_get_n_items (list) == 0)
|
||||
gtk_stack_set_visible_child (self->app_listbox_stack,
|
||||
self->empty_search_placeholder);
|
||||
else
|
||||
gtk_stack_set_visible_child (self->app_listbox_stack,
|
||||
GTK_WIDGET (self->app_listbox));
|
||||
}
|
||||
|
||||
static void
|
||||
update_total_size (CcApplicationsPanel *self)
|
||||
{
|
||||
@@ -1264,7 +1248,7 @@ update_total_size (CcApplicationsPanel *self)
|
||||
g_object_set (self->total, "info", formatted_size, NULL);
|
||||
|
||||
/* Translators: '%s' is the formatted size, e.g. "26.2 MB" */
|
||||
subtitle = g_strdup_printf (_("%s of disk space used"), formatted_size);
|
||||
subtitle = g_strdup_printf (_("%s of disk space used."), formatted_size);
|
||||
g_object_set (self->storage, "subtitle", subtitle, NULL);
|
||||
}
|
||||
|
||||
@@ -1407,7 +1391,7 @@ update_usage_section (CcApplicationsPanel *self,
|
||||
|
||||
remove_static_permissions (self);
|
||||
has_builtin = add_static_permissions (self, info, portal_app_id);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->other_permissions_section), has_builtin);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->builtin), has_builtin);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->usage_section), portal_app_id || has_builtin);
|
||||
}
|
||||
@@ -1422,22 +1406,23 @@ update_panel (CcApplicationsPanel *self,
|
||||
|
||||
if (self->perm_store == NULL)
|
||||
{
|
||||
/* Async permission store not initialized, row will be re-activated in the callback */
|
||||
self->perm_store_pending_row = row;
|
||||
g_message ("No permissions store proxy yet, come back later");
|
||||
return;
|
||||
}
|
||||
|
||||
if (row == NULL)
|
||||
{
|
||||
g_message ("No app selected, try again");
|
||||
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (self), _("Apps"));
|
||||
gtk_stack_set_visible_child (self->stack, self->empty_box);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->view_details_button), FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (row));
|
||||
|
||||
adw_navigation_page_set_title (self->app_settings_page,
|
||||
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (self),
|
||||
g_app_info_get_display_name (info));
|
||||
adw_navigation_view_push_by_tag(self->navigation_view, "settings-box");
|
||||
gtk_stack_set_visible_child (self->stack, self->settings_box);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->view_details_button), gnome_software_is_installed ());
|
||||
|
||||
g_clear_pointer (&self->current_app_id, g_free);
|
||||
@@ -1453,45 +1438,19 @@ update_panel (CcApplicationsPanel *self,
|
||||
self->current_portal_app_id = get_portal_app_id (info);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
compare_rows (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer data)
|
||||
{
|
||||
GAppInfo *item1 = (GAppInfo *) a;
|
||||
GAppInfo *item2 = (GAppInfo *) b;
|
||||
|
||||
g_autofree gchar *key1 = NULL;
|
||||
g_autofree gchar *key2 = NULL;
|
||||
|
||||
key1 = g_utf8_casefold (g_app_info_get_display_name (item1), -1);
|
||||
key2 = g_utf8_casefold (g_app_info_get_display_name (item2), -1);
|
||||
|
||||
const gchar *sort_key1 = g_utf8_collate_key (key1, -1);
|
||||
const gchar *sort_key2 = g_utf8_collate_key (key2, -1);
|
||||
|
||||
return strcmp (sort_key1, sort_key2);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_applications (CcApplicationsPanel *self)
|
||||
{
|
||||
g_autolist(GObject) infos = NULL;
|
||||
GList *l;
|
||||
|
||||
g_list_store_remove_all (G_LIST_STORE (self->app_model));
|
||||
listbox_remove_all (self->sidebar_listbox);
|
||||
#ifdef HAVE_MALCONTENT
|
||||
g_signal_handler_block (self->manager, self->app_filter_id);
|
||||
#endif
|
||||
|
||||
infos = g_app_info_get_all ();
|
||||
|
||||
if (!infos)
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->app_search_entry), 0);
|
||||
else
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->app_search_entry), 1);
|
||||
|
||||
for (l = infos; l; l = l->next)
|
||||
{
|
||||
GAppInfo *info = l->data;
|
||||
@@ -1507,33 +1466,45 @@ populate_applications (CcApplicationsPanel *self)
|
||||
#endif
|
||||
|
||||
row = GTK_WIDGET (cc_applications_row_new (info));
|
||||
g_list_store_insert_sorted (G_LIST_STORE (self->app_model), info, compare_rows, NULL);
|
||||
gtk_list_box_insert (self->sidebar_listbox, row, -1);
|
||||
|
||||
id = get_app_id (info);
|
||||
if (g_strcmp0 (id, self->current_app_id) == 0)
|
||||
gtk_list_box_select_row (self->app_listbox, GTK_LIST_BOX_ROW (row));
|
||||
gtk_list_box_select_row (self->sidebar_listbox, GTK_LIST_BOX_ROW (row));
|
||||
}
|
||||
#ifdef HAVE_MALCONTENT
|
||||
g_signal_handler_unblock (self->manager, self->app_filter_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_rows (GtkListBoxRow *row1,
|
||||
GtkListBoxRow *row2,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *key1 = cc_applications_row_get_sort_key (CC_APPLICATIONS_ROW (row1));
|
||||
const gchar *key2 = cc_applications_row_get_sort_key (CC_APPLICATIONS_ROW (row2));
|
||||
|
||||
return strcmp (key1, key2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_app_rows (GObject *item,
|
||||
gpointer data)
|
||||
filter_sidebar_rows (GtkListBoxRow *row,
|
||||
gpointer data)
|
||||
{
|
||||
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (data);
|
||||
g_autofree gchar *app_name = NULL;
|
||||
g_autofree gchar *search_text = NULL;
|
||||
const gchar *text;
|
||||
GAppInfo *info = G_APP_INFO (item);
|
||||
GAppInfo *info;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (self->app_search_entry));
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (self->sidebar_search_entry));
|
||||
|
||||
/* Only filter after the second character */
|
||||
if (g_utf8_strlen (text, -1) < 2)
|
||||
return TRUE;
|
||||
|
||||
info = cc_applications_row_get_info (CC_APPLICATIONS_ROW (row));
|
||||
app_name = cc_util_normalize_casefold_and_unaccent (g_app_info_get_name (info));
|
||||
search_text = cc_util_normalize_casefold_and_unaccent (text);
|
||||
|
||||
@@ -1561,6 +1532,7 @@ row_activated_cb (CcApplicationsPanel *self,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
update_panel (self, row);
|
||||
g_signal_emit_by_name (self, "sidebar-activated");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1583,10 +1555,7 @@ on_perm_store_ready (GObject *source_object,
|
||||
|
||||
self->perm_store = proxy;
|
||||
|
||||
if (self->perm_store_pending_row)
|
||||
g_signal_emit_by_name (self->perm_store_pending_row, "activate");
|
||||
|
||||
self->perm_store_pending_row = NULL;
|
||||
update_panel (self, gtk_list_box_get_selected_row (self->sidebar_listbox));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1596,7 +1565,7 @@ select_app (CcApplicationsPanel *self,
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->app_listbox));
|
||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->sidebar_listbox));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
@@ -1604,7 +1573,7 @@ select_app (CcApplicationsPanel *self,
|
||||
GAppInfo *info = cc_applications_row_get_info (row);
|
||||
if (g_str_has_prefix (g_app_info_get_id (info), app_id))
|
||||
{
|
||||
gtk_list_box_select_row (self->app_listbox, GTK_LIST_BOX_ROW (row));
|
||||
gtk_list_box_select_row (self->sidebar_listbox, GTK_LIST_BOX_ROW (row));
|
||||
if (emit_activate)
|
||||
g_signal_emit_by_name (row, "activate");
|
||||
break;
|
||||
@@ -1631,38 +1600,38 @@ on_launch_button_clicked_cb (CcApplicationsPanel *self)
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
g_warning ("Error launching app: %s", error->message);
|
||||
g_warning ("Error launching application: %s", error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
on_app_search_entry_activated_cb (CcApplicationsPanel *self)
|
||||
on_sidebar_search_entry_activated_cb (CcApplicationsPanel *self)
|
||||
{
|
||||
GtkListBoxRow *row;
|
||||
|
||||
row = gtk_list_box_get_row_at_y (self->app_listbox, 0);
|
||||
row = gtk_list_box_get_row_at_y (self->sidebar_listbox, 0);
|
||||
|
||||
if (!row)
|
||||
return;
|
||||
|
||||
/* Show the app */
|
||||
gtk_list_box_select_row (self->app_listbox, row);
|
||||
gtk_list_box_select_row (self->sidebar_listbox, row);
|
||||
g_signal_emit_by_name (row, "activate");
|
||||
|
||||
/* Cleanup the entry */
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->app_search_entry), "");
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->app_search_entry));
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->sidebar_search_entry), "");
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->sidebar_search_entry));
|
||||
}
|
||||
|
||||
static void
|
||||
on_app_search_entry_search_changed_cb (CcApplicationsPanel *self)
|
||||
on_sidebar_search_entry_search_changed_cb (CcApplicationsPanel *self)
|
||||
{
|
||||
gtk_filter_changed (self->filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
gtk_list_box_invalidate_filter (self->sidebar_listbox);
|
||||
}
|
||||
|
||||
static void
|
||||
on_app_search_entry_search_stopped_cb (CcApplicationsPanel *self)
|
||||
on_sidebar_search_entry_search_stopped_cb (CcApplicationsPanel *self)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->app_search_entry), "");
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->sidebar_search_entry), "");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1670,7 +1639,6 @@ cc_applications_panel_dispose (GObject *object)
|
||||
{
|
||||
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (object);
|
||||
|
||||
g_clear_pointer (&self->sandbox_info_button, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->builtin_dialog, gtk_window_destroy);
|
||||
g_clear_pointer (&self->handler_dialog, gtk_window_destroy);
|
||||
g_clear_pointer (&self->storage_dialog, gtk_window_destroy);
|
||||
@@ -1699,7 +1667,6 @@ cc_applications_panel_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&self->manager);
|
||||
#endif
|
||||
g_clear_object (&self->media_handling_settings);
|
||||
g_clear_object (&self->notification_settings);
|
||||
g_clear_object (&self->location_settings);
|
||||
g_clear_object (&self->privacy_settings);
|
||||
@@ -1754,35 +1721,103 @@ cc_applications_panel_set_property (GObject *object,
|
||||
static void
|
||||
cc_applications_panel_constructed (GObject *object)
|
||||
{
|
||||
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (object);
|
||||
GtkListBoxRow *row;
|
||||
|
||||
G_OBJECT_CLASS (cc_applications_panel_parent_class)->constructed (object);
|
||||
|
||||
/* Select the first row */
|
||||
row = gtk_list_box_get_row_at_index (self->sidebar_listbox, 0);
|
||||
gtk_list_box_select_row (self->sidebar_listbox, row);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_collapsed_cb (CcApplicationsPanel *self)
|
||||
{
|
||||
GtkSelectionMode selection_mode;
|
||||
gboolean collapsed;
|
||||
GtkRoot *root;
|
||||
|
||||
g_assert (CC_IS_APPLICATIONS_PANEL (self));
|
||||
|
||||
root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
g_object_get (root, "collapsed", &collapsed, NULL);
|
||||
|
||||
selection_mode = collapsed ? GTK_SELECTION_NONE : GTK_SELECTION_SINGLE;
|
||||
|
||||
gtk_list_box_set_selection_mode (self->sidebar_listbox, selection_mode);
|
||||
|
||||
if (!collapsed)
|
||||
{
|
||||
if (self->current_app_id)
|
||||
select_app (self, self->current_app_id, FALSE);
|
||||
else
|
||||
{
|
||||
GtkListBoxRow *row;
|
||||
|
||||
row = gtk_list_box_get_row_at_index (self->sidebar_listbox, 0);
|
||||
row_activated_cb (self, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_applications_panel_root (GtkWidget *widget)
|
||||
{
|
||||
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (widget);
|
||||
GtkRoot *root;
|
||||
|
||||
GTK_WIDGET_CLASS (cc_applications_panel_parent_class)->root (widget);
|
||||
|
||||
root = gtk_widget_get_root (widget);
|
||||
|
||||
g_signal_connect_swapped (root, "notify::collapsed", G_CALLBACK (notify_collapsed_cb), self);
|
||||
|
||||
notify_collapsed_cb (self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_applications_panel_unroot (GtkWidget *widget)
|
||||
{
|
||||
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (widget);
|
||||
GtkRoot *root = gtk_widget_get_root (widget);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (root, notify_collapsed_cb, self);
|
||||
|
||||
GTK_WIDGET_CLASS (cc_applications_panel_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static AdwNavigationPage*
|
||||
cc_applications_panel_get_sidebar_widget (CcPanel *panel)
|
||||
{
|
||||
CcApplicationsPanel *self = CC_APPLICATIONS_PANEL (panel);
|
||||
return self->sidebar_box;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
{
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
g_type_ensure (CC_TYPE_DEFAULT_APPS_PAGE);
|
||||
g_type_ensure (CC_TYPE_REMOVABLE_MEDIA_SETTINGS);
|
||||
|
||||
object_class->dispose = cc_applications_panel_dispose;
|
||||
object_class->finalize = cc_applications_panel_finalize;
|
||||
object_class->constructed = cc_applications_panel_constructed;
|
||||
object_class->set_property = cc_applications_panel_set_property;
|
||||
|
||||
widget_class->root = cc_applications_panel_root;
|
||||
widget_class->unroot = cc_applications_panel_unroot;
|
||||
|
||||
panel_class->get_sidebar_widget = cc_applications_panel_get_sidebar_widget;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-applications-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_icon_image);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_name_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_search_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_settings_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, other_permissions_section);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, autorun_never_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin_page);
|
||||
@@ -1791,9 +1826,7 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, camera);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, clear_cache_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, data);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, default_apps_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, empty_search_placeholder);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app_listbox_stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, empty_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_file_group);
|
||||
@@ -1805,7 +1838,6 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, launch_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, location);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, microphone);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, navigation_view);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, no_camera);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, no_location);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, no_microphone);
|
||||
@@ -1814,13 +1846,15 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, notification);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, background);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, wallpaper);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, removable_media_settings);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sandbox_banner);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sandbox_info_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, screenshot);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, shortcuts);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_search_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, search);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, settings_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sound);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, storage);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, storage_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, total);
|
||||
@@ -1844,21 +1878,11 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_builtin_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_handler_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_launch_button_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_app_search_entry_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_app_search_entry_search_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_app_search_entry_search_stopped_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_sidebar_search_entry_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_sidebar_search_entry_search_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_sidebar_search_entry_search_stopped_cb);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_storage_row_activated_cb);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
app_row_new (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
GAppInfo *info = item;
|
||||
|
||||
return GTK_WIDGET (cc_applications_row_new (info));
|
||||
}
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_storage_row_activated_cb);}
|
||||
|
||||
static void
|
||||
cc_applications_panel_init (CcApplicationsPanel *self)
|
||||
@@ -1876,7 +1900,7 @@ cc_applications_panel_init (CcApplicationsPanel *self)
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->install_button), gnome_software_is_installed ());
|
||||
|
||||
g_signal_connect_object (self->app_listbox, "row-activated",
|
||||
g_signal_connect_object (self->sidebar_listbox, "row-activated",
|
||||
G_CALLBACK (row_activated_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (self->view_details_button,
|
||||
@@ -1885,32 +1909,17 @@ cc_applications_panel_init (CcApplicationsPanel *self)
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
self->filter = GTK_FILTER (gtk_custom_filter_new ((GtkCustomFilterFunc) filter_app_rows,
|
||||
self, NULL));
|
||||
gtk_list_box_set_sort_func (self->sidebar_listbox,
|
||||
compare_rows,
|
||||
NULL, NULL);
|
||||
|
||||
self->app_model = G_LIST_MODEL (g_list_store_new (G_TYPE_APP_INFO));
|
||||
self->filter_model = G_LIST_MODEL (gtk_filter_list_model_new (self->app_model,
|
||||
GTK_FILTER (self->filter)));
|
||||
g_signal_connect (self->filter_model, "items-changed",
|
||||
G_CALLBACK (on_items_changed_cb), self);
|
||||
|
||||
gtk_list_box_bind_model (self->app_listbox,
|
||||
self->filter_model,
|
||||
app_row_new,
|
||||
NULL,
|
||||
NULL);
|
||||
gtk_list_box_set_filter_func (self->sidebar_listbox,
|
||||
filter_sidebar_rows,
|
||||
self, NULL);
|
||||
|
||||
self->location_settings = g_settings_new ("org.gnome.system.location");
|
||||
self->privacy_settings = g_settings_new ("org.gnome.desktop.privacy");
|
||||
self->search_settings = g_settings_new ("org.gnome.desktop.search-providers");
|
||||
self->media_handling_settings = g_settings_new ("org.gnome.desktop.media-handling");
|
||||
|
||||
g_settings_bind (self->media_handling_settings,
|
||||
"autorun-never",
|
||||
self->autorun_never_row,
|
||||
"active",
|
||||
G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||||
|
||||
#ifdef HAVE_MALCONTENT
|
||||
/* FIXME: should become asynchronous */
|
||||
system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, self->cancellable, &error);
|
||||
|
||||
@@ -2,123 +2,93 @@
|
||||
<interface>
|
||||
<template class="CcApplicationsPanel" parent="CcPanel">
|
||||
<property name="child">
|
||||
<object class="AdwNavigationView" id="navigation_view">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
|
||||
<!-- App Search Page (Main Ladning Page) -->
|
||||
<child>
|
||||
<object class="AdwNavigationPage">
|
||||
<property name="title" translatable="yes">Apps</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
<property name="content">
|
||||
<object class="GtkStack" id="stack">
|
||||
|
||||
<!-- This "fake" empty box is there to show instead of the AdwStatusPage before the panel is initialized -->
|
||||
<child>
|
||||
<object class="GtkBox"/>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="empty_box">
|
||||
<property name="icon-name">org.gnome.Software-symbolic</property>
|
||||
<property name="title" translatable="yes">No Apps</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="install_button">
|
||||
<property name="label" translatable="yes">_Install Some…</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="halign">center</property>
|
||||
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesPage" id="settings_box">
|
||||
|
||||
<!-- App icon & buttons -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage" id="app_search_stack_page">
|
||||
<!-- Searchbar -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<object class="AdwClamp">
|
||||
<property name="maximum-size">280</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="app_search_entry">
|
||||
<property name="placeholder_text" translatable="yes">Search apps</property>
|
||||
<signal name="activate" handler="on_app_search_entry_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
<signal name="search-changed" handler="on_app_search_entry_search_changed_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
<signal name="stop-search" handler="on_app_search_entry_search_stopped_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkImage" id="app_icon_image">
|
||||
<property name="icon-name">org.gnome.Software</property>
|
||||
<property name="pixel-size">96</property>
|
||||
<style>
|
||||
<class name="icon-dropshadow" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Default Apps Row -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="CcListRow">
|
||||
<property name="activatable">True</property>
|
||||
<property name="title" translatable="yes">_Default Apps</property>
|
||||
<property name="show-arrow">True</property>
|
||||
<property name="action-name">navigation.push</property>
|
||||
<property name="action-target">'default-apps'</property>
|
||||
<object class="GtkLabel" id="app_name_label">
|
||||
<property name="wrap">True</property>
|
||||
<style>
|
||||
<class name="title" />
|
||||
<class name="title-1" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Apps List -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkStack" id="app_listbox_stack">
|
||||
<property name="vhomogeneous">False</property>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<!-- Empty search results placeholder -->
|
||||
<object class="GtkBox" id="empty_search_placeholder">
|
||||
<!--AdwStatusPage can't be used here, see: https://gitlab.gnome.org/GNOME/libadwaita/-/issues/697-->
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="valign">center</property>
|
||||
|
||||
<!--Use AdwClamp like AdwStatusPage-->
|
||||
<child>
|
||||
<object class="AdwClamp">
|
||||
<style>
|
||||
<class name="status-page"/>
|
||||
</style>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="pixel_size">128</property>
|
||||
<property name="icon_name">computer-fail-symbolic</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
<class name="icon"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">No Apps Found</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="wrap-mode">word-char</property>
|
||||
<property name="justify">center</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
<class name="title-1"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="install_button">
|
||||
<property name="label" translatable="yes">_Find in Software</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="halign">center</property>
|
||||
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="app_listbox">
|
||||
<property name="selection-mode">none</property>
|
||||
<object class="GtkButton" id="launch_button">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="can-shrink">True</property>
|
||||
<signal name="clicked" handler="on_launch_button_clicked_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
<style>
|
||||
<class name="boxed-list" />
|
||||
<class name="pill" />
|
||||
<class name="suggested-action" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="view_details_button">
|
||||
<property name="label" translatable="yes">App _Details</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="can-shrink">True</property>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
@@ -128,317 +98,240 @@
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Default Apps Page -->
|
||||
<child>
|
||||
<object class="AdwNavigationPage">
|
||||
<property name="title" translatable="yes">Default Apps</property>
|
||||
<property name="tag">default-apps</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<!-- Default Apps Settings -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="integration_section">
|
||||
<child>
|
||||
<object class="CcDefaultAppsPage" id="default_apps_page" />
|
||||
</child>
|
||||
|
||||
<!-- "Automatically Launch Apps" row -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Removable Media</property>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="autorun_never_row">
|
||||
<property name="title" translatable="yes">Automat_ically Launch Apps</property>
|
||||
<property name="subtitle" translatable="yes">Start apps when media is connected or inserted</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Removable Media Settings -->
|
||||
<child>
|
||||
<object class="CcRemovableMediaSettings" id="removable_media_settings" />
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- App Settings Page -->
|
||||
<child>
|
||||
<object class="AdwNavigationPage" id="app_settings_page">
|
||||
<property name="title" translatable="yes">App Settings</property>
|
||||
<property name="tag">settings-box</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="AdwBanner" id="sandbox_banner">
|
||||
<property name="visible">False</property>
|
||||
<property name="revealed">True</property>
|
||||
<child>
|
||||
<object class="CcListRowInfoButton" id="sandbox_info_button">
|
||||
<property name="visible" bind-source="sandbox_banner" bind-property="visible" bind-flags="sync-create|default"/>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-end">3</property>
|
||||
<property name="text" translatable="yes">App settings cannot be fully enforced for apps which are not sandboxed. These apps may use permissions which are not shown.</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="AdwSwitchRow" id="search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
|
||||
<signal name="notify::active" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage" id="settings_box">
|
||||
<!-- App icon & buttons -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="app_icon_image">
|
||||
<property name="icon-name">org.gnome.Software</property>
|
||||
<property name="pixel-size">96</property>
|
||||
<style>
|
||||
<class name="icon-dropshadow" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel" id="app_name_label">
|
||||
<property name="wrap">True</property>
|
||||
<style>
|
||||
<class name="title" />
|
||||
<class name="title-1" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="launch_button">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="can-shrink">True</property>
|
||||
<signal name="clicked" handler="on_launch_button_clicked_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
<style>
|
||||
<class name="pill" />
|
||||
<class name="suggested-action" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="view_details_button">
|
||||
<property name="label" translatable="yes">App _Details</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="can-shrink">True</property>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="integration_section">
|
||||
<property name="title" translatable="yes">Permissions</property>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="search">
|
||||
<property name="title" translatable="yes">_Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_search">
|
||||
<property name="title" translatable="yes">_Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="notification">
|
||||
<property name="title" translatable="yes">_Notifications</property>
|
||||
<property name="subtitle" translatable="yes">Show system notifications</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="notification_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="background">
|
||||
<property name="title" translatable="yes">_Run in Background</property>
|
||||
<property name="subtitle" translatable="yes">Allow activity when the app is closed</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="background_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="screenshot">
|
||||
<property name="title" translatable="yes">Scr_eenshots</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures of the screen at any time</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="screenshot_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="wallpaper">
|
||||
<property name="title" translatable="yes">Change _Wallpaper</property>
|
||||
<property name="subtitle" translatable="yes">Change the desktop wallpaper</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="wallpaper_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="sound">
|
||||
<property name="title" translatable="yes">So_unds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="sound_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_sound">
|
||||
<property name="title" translatable="yes">So_unds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="shortcuts">
|
||||
<property name="title" translatable="yes">_Inhibit Shortcuts</property>
|
||||
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="shortcuts_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
|
||||
<signal name="notify::active" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_camera">
|
||||
<property name="title" translatable="yes">C_amera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="microphone">
|
||||
<property name="title" translatable="yes">_Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_microphone">
|
||||
<property name="title" translatable="yes">_Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="location">
|
||||
<property name="title" translatable="yes">_Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="notify::active" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_location">
|
||||
<property name="title" translatable="yes">_Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="other_permissions_section">
|
||||
<child>
|
||||
<object class="CcInfoRow" id="builtin">
|
||||
<property name="title" translatable="yes">Re_quired Access</property>
|
||||
<property name="subtitle" translatable="yes">System access that is required by the app</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
<signal name="activated" handler="on_builtin_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="usage_section">
|
||||
<property name="title" translatable="yes">General</property>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="handler_row">
|
||||
<property name="title" translatable="yes">_File &amp; Link Associations</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
<signal name="activated" handler="on_handler_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="storage">
|
||||
<property name="title" translatable="yes">S_torage</property>
|
||||
<property name="has-expander">1</property>
|
||||
<property name="is-link">1</property>
|
||||
<signal name="activated" handler="on_storage_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<object class="CcInfoRow" id="no_search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="notification">
|
||||
<property name="title" translatable="yes">Notifications</property>
|
||||
<property name="subtitle" translatable="yes">Show system notifications</property>
|
||||
<signal name="notify::active" handler="notification_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="background">
|
||||
<property name="title" translatable="yes">Run in Background</property>
|
||||
<property name="subtitle" translatable="yes">Allow activity when the app is closed</property>
|
||||
<signal name="notify::active" handler="background_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="screenshot">
|
||||
<property name="title" translatable="yes">Screenshots</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures of the screen at any time</property>
|
||||
<signal name="notify::active" handler="screenshot_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="wallpaper">
|
||||
<property name="title" translatable="yes">Change Wallpaper</property>
|
||||
<property name="subtitle" translatable="yes">Change the desktop wallpaper.</property>
|
||||
<signal name="notify::active" handler="wallpaper_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds.</property>
|
||||
<signal name="notify::active" handler="sound_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="shortcuts">
|
||||
<property name="title" translatable="yes">Inhibit Shortcuts</property>
|
||||
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts</property>
|
||||
<signal name="notify::active" handler="shortcuts_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
|
||||
<signal name="notify::active" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
|
||||
<signal name="notify::active" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data</property>
|
||||
<signal name="notify::active" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="usage_section">
|
||||
<child>
|
||||
<object class="CcInfoRow" id="builtin">
|
||||
<property name="title" translatable="yes">Required Access</property>
|
||||
<property name="subtitle" translatable="yes">System access that is required by the app</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
<signal name="activated" handler="on_builtin_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="handler_row">
|
||||
<property name="title" translatable="yes">File &amp; Link Associations</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
<signal name="activated" handler="on_handler_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="storage">
|
||||
<property name="title" translatable="yes">Storage</property>
|
||||
<property name="has-expander">1</property>
|
||||
<property name="is-link">1</property>
|
||||
<signal name="activated" handler="on_storage_row_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<object class="AdwNavigationPage" id="sidebar_box">
|
||||
<property name="title" translatable="yes">Apps</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
<child type="top">
|
||||
<object class="AdwBin">
|
||||
<style>
|
||||
<class name="toolbar"/>
|
||||
</style>
|
||||
<property name="child">
|
||||
<object class="GtkSearchEntry" id="sidebar_search_entry">
|
||||
<property name="placeholder_text" translatable="yes">Search apps</property>
|
||||
<signal name="activate" handler="on_sidebar_search_entry_activated_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
<signal name="search-changed" handler="on_sidebar_search_entry_search_changed_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
<signal name="stop-search" handler="on_sidebar_search_entry_search_stopped_cb" object="CcApplicationsPanel" swapped="yes" />
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="child">
|
||||
<object class="GtkListBox" id="sidebar_listbox">
|
||||
<property name="selection-mode">browse</property>
|
||||
<style>
|
||||
<class name="navigation-sidebar" />
|
||||
</style>
|
||||
|
||||
<child type="placeholder">
|
||||
<object class="GtkBox" id="empty_search_placeholder">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">64</property>
|
||||
<property name="icon_name">edit-find-symbolic</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">No results found</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Try a different search</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<!-- Built-in Permissions dialog -->
|
||||
<object class="AdwWindow" id="builtin_dialog">
|
||||
<property name="title" translatable="yes">Required Access</property>
|
||||
@@ -532,13 +425,10 @@
|
||||
<object class="GtkButton" id="handler_reset">
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="label" translatable="yes">_Reset</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
<signal name="clicked" handler="handler_reset_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="destructive-action" />
|
||||
<class name="pill" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
@@ -558,8 +448,7 @@
|
||||
<property name="resizable">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="default-width">420</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">294</property>
|
||||
<property name="default-height">420</property>
|
||||
<child>
|
||||
<object class="GtkShortcutController">
|
||||
<property name="scope">managed</property>
|
||||
@@ -578,7 +467,7 @@
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<property name="description" translatable="yes">How much disk space this app is occupying with app data and caches</property>
|
||||
<property name="description" translatable="yes">How much disk space this app is occupying with app data and caches.</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
@@ -611,13 +500,9 @@
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkButton" id="clear_cache_button">
|
||||
<property name="label" translatable="yes">_Clear Cache</property>
|
||||
<property name="label" translatable="yes">_Clear Cache…</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="halign">center</property>
|
||||
<signal name="clicked" handler="clear_cache_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -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,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcDefaultAppsPage" parent="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Default Apps</property>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="web_row">
|
||||
<property name="title" translatable="yes">_Web</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">x-scheme-handler/http</property>
|
||||
<property name="filters">text/html;application/xhtml+xml;x-scheme-handler/https</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="mail_row">
|
||||
<property name="title" translatable="yes">_Mail</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="content-type">x-scheme-handler/mailto</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="calendar_row">
|
||||
<property name="title" translatable="yes">_Calendar</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">text/calendar</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="music_row">
|
||||
<property name="title" translatable="yes">M_usic</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">audio/x-vorbis+ogg</property>
|
||||
<property name="filters">audio/*</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="video_row">
|
||||
<property name="title" translatable="yes">_Video</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">video/x-ogm+ogg</property>
|
||||
<property name="filters">video/*</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="photos_row">
|
||||
<property name="title" translatable="yes">_Photos</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">image/jpeg</property>
|
||||
<property name="filters">image/*</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="calls_row">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes" comments="Translators: This is a telephone call">Ca_lls</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">x-scheme-handler/tel</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcDefaultAppsRow" id="sms_row">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">_SMS</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="content-type">x-scheme-handler/sms</property>
|
||||
<signal name="notify::selected-item" handler="on_row_selected_item_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -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,167 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcRemovableMediaSettings" parent="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="AdwActionRow" id="cd_audio_row">
|
||||
<property name="title" translatable="yes">CD _Audio</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">audio_cdda_chooser</property>
|
||||
<child>
|
||||
<object class="GtkAppChooserButton" id="audio_cdda_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="content_type">x-content/audio-cdda</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="dvd_video_row">
|
||||
<property name="title" translatable="yes">_DVD Video</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">video_dvd_chooser</property>
|
||||
<child>
|
||||
<object class="GtkAppChooserButton" id="video_dvd_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="content_type">x-content/video-dvd</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="music_player_row">
|
||||
<property name="title" translatable="yes">Music Pla_yer</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">music_player_chooser</property>
|
||||
<child>
|
||||
<object class="GtkAppChooserButton" id="music_player_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="content_type">x-content/audio-player</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="photos_row">
|
||||
<property name="title" translatable="yes">P_hotos</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">dcf_chooser</property>
|
||||
<child>
|
||||
<object class="GtkAppChooserButton" id="dcf_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="content_type">x-content/image-dcf</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="software_row">
|
||||
<property name="title" translatable="yes">Sof_tware</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">software_chooser</property>
|
||||
<child>
|
||||
<object class="GtkAppChooserButton" id="software_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="content_type">x-content/unix-software</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcListRow" id="other_media_row">
|
||||
<property name="title" translatable="yes">_Other Media</property>
|
||||
<property name="show-arrow">True</property>
|
||||
<property name="subtitle" translatable="yes">Select how other media should be handled</property>
|
||||
<signal name="activated" handler="on_extra_options_button_clicked" object="CcRemovableMediaSettings"/>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
<object class="GtkSizeGroup">
|
||||
<widgets>
|
||||
<widget name="audio_cdda_chooser"/>
|
||||
<widget name="video_dvd_chooser"/>
|
||||
<widget name="music_player_chooser"/>
|
||||
<widget name="dcf_chooser"/>
|
||||
<widget name="software_chooser"/>
|
||||
</widgets>
|
||||
</object>
|
||||
|
||||
<object class="AdwWindow" id="other_type_dialog">
|
||||
<property name="title" translatable="yes">Other Media</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">294</property>
|
||||
<property name="default-width">360</property>
|
||||
<property name="default-height">294</property>
|
||||
<signal name="close-request" handler="on_extra_options_dialog_close_request" object="CcRemovableMediaSettings" swapped="yes"/>
|
||||
<child>
|
||||
<object class="GtkShortcutController">
|
||||
<property name="scope">managed</property>
|
||||
<child>
|
||||
<object class="GtkShortcut">
|
||||
<property name="trigger">Escape</property>
|
||||
<property name="action">action(window.close)</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">_Type</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="activatable-widget">other_type_combo_box</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="other_type_combo_box">
|
||||
<property name="model">other_type_list_store</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="changed" handler="on_other_type_combo_box_changed" object="CcRemovableMediaSettings" swapped="yes"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="other_action_row">
|
||||
<property name="title" translatable="yes">_Action</property>
|
||||
<property name="use-underline">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="other_action_box">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
<object class="GtkListStore" id="other_type_list_store">
|
||||
<columns>
|
||||
<!-- column-name description -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name content-type -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -105,7 +105,7 @@ file_size_thread_func (GTask *task,
|
||||
|
||||
g_private_replace (&size_key, g_new0 (guint64, 1));
|
||||
|
||||
nftw (path, ftw_size_cb, 20, FTW_PHYS | FTW_DEPTH);
|
||||
nftw (path, ftw_size_cb, 20, FTW_DEPTH);
|
||||
|
||||
total = g_new0 (guint64, 1);
|
||||
*total = *(guint64*)g_private_get (&size_key);
|
||||
@@ -142,6 +142,15 @@ file_size_finish (GFile *file,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
listbox_remove_all (GtkListBox *listbox)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (listbox))))
|
||||
gtk_list_box_remove (listbox, child);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_output_of (const gchar **argv)
|
||||
{
|
||||
@@ -227,19 +236,19 @@ guint64
|
||||
get_snap_app_size (const gchar *snap_name)
|
||||
{
|
||||
#ifdef HAVE_SNAP
|
||||
g_autoptr(CcSnapdClient) client = NULL;
|
||||
g_autoptr(JsonObject) snap = NULL;
|
||||
g_autoptr(SnapdClient) client = NULL;
|
||||
g_autoptr(SnapdSnap) snap = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
client = cc_snapd_client_new ();
|
||||
snap = cc_snapd_client_get_snap_sync (client, snap_name, NULL, &error);
|
||||
client = snapd_client_new ();
|
||||
snap = snapd_client_get_snap_sync (client, snap_name, NULL, &error);
|
||||
if (snap == NULL)
|
||||
{
|
||||
g_warning ("Failed to get snap size: %s", error->message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return json_object_get_int_member (snap, "installed-size");
|
||||
return snapd_snap_get_installed_size (snap);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -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);
|
||||
|
||||
219
panels/background/bg-colors-source.c
Normal file
219
panels/background/bg-colors-source.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/* bg-colors-source.c */
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "bg-colors-source.h"
|
||||
|
||||
#include "cc-background-item.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gdesktop-enums.h>
|
||||
|
||||
struct _BgColorsSource
|
||||
{
|
||||
BgSource parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (BgColorsSource, bg_colors_source, BG_TYPE_SOURCE)
|
||||
|
||||
struct {
|
||||
GDesktopBackgroundShading type;
|
||||
int orientation;
|
||||
const char *pcolor;
|
||||
} items[] = {
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#000000" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#db5d33" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#008094" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#5d479d" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ab2876" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#fad166" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#437740" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#d272c4" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ed9116" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ff89a9" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#7a8aa2" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#888888" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#475b52" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#425265" },
|
||||
{ G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#7a634b" },
|
||||
};
|
||||
|
||||
static gchar *
|
||||
get_colors_path (void)
|
||||
{
|
||||
return g_build_filename (g_get_user_config_dir (), "gnome-control-center", "backgrounds", "colors.ini", NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_colors_dir (void)
|
||||
{
|
||||
return g_build_filename (g_get_user_config_dir (), "gnome-control-center", "backgrounds", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
bg_colors_source_add_color (BgColorsSource *self,
|
||||
GListStore *store,
|
||||
const char *color)
|
||||
{
|
||||
CcBackgroundItemFlags flags;
|
||||
g_autoptr(CcBackgroundItem) item = NULL;
|
||||
|
||||
item = cc_background_item_new (NULL);
|
||||
flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
|
||||
CC_BACKGROUND_ITEM_HAS_SCOLOR |
|
||||
CC_BACKGROUND_ITEM_HAS_SHADING |
|
||||
CC_BACKGROUND_ITEM_HAS_PLACEMENT |
|
||||
CC_BACKGROUND_ITEM_HAS_URI;
|
||||
/* It does have a URI, it's "none" */
|
||||
|
||||
g_object_set (G_OBJECT (item),
|
||||
"uri", "file:///" DATADIR "/gnome-control-center/pixmaps/noise-texture-light.png",
|
||||
"primary-color", color,
|
||||
"secondary-color", color,
|
||||
"shading", G_DESKTOP_BACKGROUND_SHADING_SOLID,
|
||||
"placement", G_DESKTOP_BACKGROUND_STYLE_WALLPAPER,
|
||||
"flags", flags,
|
||||
NULL);
|
||||
cc_background_item_load (item, NULL);
|
||||
|
||||
/* insert the item into the liststore */
|
||||
g_list_store_append (store, item);
|
||||
}
|
||||
|
||||
static void
|
||||
bg_colors_source_constructed (GObject *object)
|
||||
{
|
||||
BgColorsSource *self = BG_COLORS_SOURCE (object);
|
||||
guint i;
|
||||
GListStore *store;
|
||||
g_autoptr(GKeyFile) keyfile = NULL;
|
||||
g_autofree gchar *path = NULL;
|
||||
|
||||
G_OBJECT_CLASS (bg_colors_source_parent_class)->constructed (object);
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (self));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (items); i++)
|
||||
bg_colors_source_add_color (self, store, items[i].pcolor);
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
path = get_colors_path ();
|
||||
if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL))
|
||||
{
|
||||
g_auto(GStrv) colors = NULL;
|
||||
|
||||
colors = g_key_file_get_string_list (keyfile, "Colors", "custom-colors", NULL, NULL);
|
||||
for (i = 0; colors != NULL && colors[i] != NULL; i++)
|
||||
bg_colors_source_add_color (self, store, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
bg_colors_source_add (BgColorsSource *self,
|
||||
GdkRGBA *rgba,
|
||||
GtkTreeRowReference **ret_row_ref)
|
||||
{
|
||||
GListStore *store;
|
||||
g_autofree gchar *c = NULL;
|
||||
g_auto(GStrv) colors = NULL;
|
||||
gsize len;
|
||||
g_autoptr(GKeyFile) keyfile = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autofree gchar *dir = NULL;
|
||||
g_autofree gchar *path = NULL;
|
||||
|
||||
c = g_strdup_printf ("#%02x%02x%02x",
|
||||
(int)(255*rgba->red),
|
||||
(int)(255*rgba->green),
|
||||
(int)(255*rgba->blue));
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (self));
|
||||
|
||||
bg_colors_source_add_color (self, store, c);
|
||||
|
||||
/* Save to the keyfile */
|
||||
dir = get_colors_dir ();
|
||||
g_mkdir_with_parents (dir, 0700);
|
||||
|
||||
path = get_colors_path ();
|
||||
colors = NULL;
|
||||
len = 0;
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL))
|
||||
colors = g_key_file_get_string_list (keyfile, "Colors", "custom-colors", &len, NULL);
|
||||
|
||||
if (len == 0 && colors != NULL)
|
||||
g_clear_pointer (&colors, g_strfreev);
|
||||
|
||||
if (colors == NULL)
|
||||
{
|
||||
colors = g_new0 (char *, 2);
|
||||
colors[0] = g_steal_pointer (&c);
|
||||
len = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char **new_colors;
|
||||
guint i;
|
||||
|
||||
new_colors = g_new0 (char *, len + 2);
|
||||
for (i = 0; colors[i] != NULL; i++)
|
||||
{
|
||||
new_colors[i] = colors[i];
|
||||
colors[i] = NULL;
|
||||
}
|
||||
|
||||
new_colors[len] = g_steal_pointer (&c);
|
||||
len++;
|
||||
|
||||
g_strfreev (colors);
|
||||
colors = new_colors;
|
||||
}
|
||||
|
||||
g_key_file_set_string_list (keyfile, "Colors", "custom-colors", (const gchar * const*) colors, len);
|
||||
|
||||
if (!g_key_file_save_to_file (keyfile, path, &error))
|
||||
g_warning ("Could not save custom color: %s", error->message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
bg_colors_source_init (BgColorsSource *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
bg_colors_source_class_init (BgColorsSourceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = bg_colors_source_constructed;
|
||||
}
|
||||
|
||||
BgColorsSource *
|
||||
bg_colors_source_new (GtkWidget *widget)
|
||||
{
|
||||
return g_object_new (BG_TYPE_COLORS_SOURCE, "widget", widget, NULL);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* cc-wacom-stylus-action-dialog.h
|
||||
*
|
||||
* Copyright © 2024 Red Hat, Inc.
|
||||
/* bg-colors-source.h */
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,22 +15,24 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "bg-source.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_WACOM_STYLUS_ACTION_DIALOG (cc_wacom_stylus_action_dialog_get_type ())
|
||||
#define BG_TYPE_COLORS_SOURCE (bg_colors_source_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (BgColorsSource, bg_colors_source, BG, COLORS_SOURCE, BgSource)
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CcWacomStylusActionDialog, cc_wacom_stylus_action_dialog, CC, WACOM_STYLUS_ACTION_DIALOG, AdwWindow)
|
||||
BgColorsSource *bg_colors_source_new (GtkWidget *widget);
|
||||
|
||||
GtkWidget* cc_wacom_stylus_action_dialog_new (GSettings *settings,
|
||||
const char *stylus_name,
|
||||
guint button,
|
||||
const char *key);
|
||||
gboolean bg_colors_source_add (BgColorsSource *self,
|
||||
GdkRGBA *rgba,
|
||||
GtkTreeRowReference **ret_row_ref);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -396,9 +396,11 @@ bg_recent_source_init (BgRecentSource *self)
|
||||
}
|
||||
|
||||
BgRecentSource*
|
||||
bg_recent_source_new (void)
|
||||
bg_recent_source_new (GtkWidget *widget)
|
||||
{
|
||||
return g_object_new (BG_TYPE_RECENT_SOURCE, NULL);
|
||||
return g_object_new (BG_TYPE_RECENT_SOURCE,
|
||||
"widget", widget,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -28,7 +28,7 @@ G_BEGIN_DECLS
|
||||
#define BG_TYPE_RECENT_SOURCE (bg_recent_source_get_type())
|
||||
G_DECLARE_FINAL_TYPE (BgRecentSource, bg_recent_source, BG, RECENT_SOURCE, BgSource)
|
||||
|
||||
BgRecentSource* bg_recent_source_new (void);
|
||||
BgRecentSource* bg_recent_source_new (GtkWidget *widget);
|
||||
|
||||
void bg_recent_source_add_file (BgRecentSource *self,
|
||||
const gchar *path);
|
||||
|
||||
@@ -23,19 +23,55 @@
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#define THUMBNAIL_WIDTH 144
|
||||
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
GListStore *store;
|
||||
GtkWidget *widget;
|
||||
gint thumbnail_height;
|
||||
gint thumbnail_width;
|
||||
} BgSourcePrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (BgSource, bg_source, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_LISTSTORE
|
||||
PROP_LISTSTORE = 1,
|
||||
PROP_WIDGET
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
bg_source_calculate_thumbnail_dimensions (BgSource *source)
|
||||
{
|
||||
BgSourcePrivate *priv = bg_source_get_instance_private (source);
|
||||
gint scale_factor;
|
||||
|
||||
priv->thumbnail_height = THUMBNAIL_HEIGHT;
|
||||
priv->thumbnail_width = THUMBNAIL_WIDTH;
|
||||
|
||||
if (priv->widget == NULL)
|
||||
return;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (priv->widget);
|
||||
if (scale_factor > 1)
|
||||
{
|
||||
priv->thumbnail_height *= scale_factor;
|
||||
priv->thumbnail_width *= scale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bg_source_constructed (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (bg_source_parent_class)->constructed (object);
|
||||
|
||||
bg_source_calculate_thumbnail_dimensions (BG_SOURCE (object));
|
||||
}
|
||||
|
||||
static void
|
||||
bg_source_get_property (GObject *object,
|
||||
guint property_id,
|
||||
@@ -55,12 +91,33 @@ bg_source_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bg_source_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BgSource *source = BG_SOURCE (object);
|
||||
BgSourcePrivate *priv = bg_source_get_instance_private (source);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_WIDGET:
|
||||
priv->widget = GTK_WIDGET (g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bg_source_dispose (GObject *object)
|
||||
{
|
||||
BgSource *source = BG_SOURCE (object);
|
||||
BgSourcePrivate *priv = bg_source_get_instance_private (source);
|
||||
|
||||
g_clear_object (&priv->thumbnail_factory);
|
||||
g_clear_object (&priv->store);
|
||||
|
||||
G_OBJECT_CLASS (bg_source_parent_class)->dispose (object);
|
||||
@@ -72,7 +129,9 @@ bg_source_class_init (BgSourceClass *klass)
|
||||
GParamSpec *pspec;
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = bg_source_constructed;
|
||||
object_class->get_property = bg_source_get_property;
|
||||
object_class->set_property = bg_source_set_property;
|
||||
object_class->dispose = bg_source_dispose;
|
||||
|
||||
pspec = g_param_spec_object ("liststore",
|
||||
@@ -81,6 +140,13 @@ bg_source_class_init (BgSourceClass *klass)
|
||||
G_TYPE_LIST_STORE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_LISTSTORE, pspec);
|
||||
|
||||
pspec = g_param_spec_object ("widget",
|
||||
"Widget",
|
||||
"Widget used to view the source",
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_WIDGET, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -88,6 +154,7 @@ bg_source_init (BgSource *self)
|
||||
{
|
||||
BgSourcePrivate *priv = bg_source_get_instance_private (self);
|
||||
priv->store = g_list_store_new (CC_TYPE_BACKGROUND_ITEM);
|
||||
priv->thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
}
|
||||
|
||||
GListStore*
|
||||
@@ -100,3 +167,47 @@ bg_source_get_liststore (BgSource *source)
|
||||
priv = bg_source_get_instance_private (source);
|
||||
return priv->store;
|
||||
}
|
||||
|
||||
gint
|
||||
bg_source_get_scale_factor (BgSource *source)
|
||||
{
|
||||
BgSourcePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (BG_IS_SOURCE (source), 1);
|
||||
|
||||
priv = bg_source_get_instance_private (source);
|
||||
return gtk_widget_get_scale_factor (priv->widget);
|
||||
}
|
||||
|
||||
gint
|
||||
bg_source_get_thumbnail_height (BgSource *source)
|
||||
{
|
||||
BgSourcePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (BG_IS_SOURCE (source), THUMBNAIL_HEIGHT);
|
||||
|
||||
priv = bg_source_get_instance_private (source);
|
||||
return priv->thumbnail_height;
|
||||
}
|
||||
|
||||
gint
|
||||
bg_source_get_thumbnail_width (BgSource *source)
|
||||
{
|
||||
BgSourcePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (BG_IS_SOURCE (source), THUMBNAIL_WIDTH);
|
||||
|
||||
priv = bg_source_get_instance_private (source);
|
||||
return priv->thumbnail_width;
|
||||
}
|
||||
|
||||
GnomeDesktopThumbnailFactory*
|
||||
bg_source_get_thumbnail_factory (BgSource *source)
|
||||
{
|
||||
BgSourcePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (BG_IS_SOURCE (source), NULL);
|
||||
|
||||
priv = bg_source_get_instance_private (source);
|
||||
return priv->thumbnail_factory;
|
||||
}
|
||||
|
||||
@@ -35,4 +35,12 @@ struct _BgSourceClass
|
||||
|
||||
GListStore* bg_source_get_liststore (BgSource *source);
|
||||
|
||||
gint bg_source_get_scale_factor (BgSource *source);
|
||||
|
||||
gint bg_source_get_thumbnail_height (BgSource *source);
|
||||
|
||||
gint bg_source_get_thumbnail_width (BgSource *source);
|
||||
|
||||
GnomeDesktopThumbnailFactory* bg_source_get_thumbnail_factory (BgSource *source);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -157,7 +157,8 @@ bg_wallpapers_source_class_init (BgWallpapersSourceClass *klass)
|
||||
}
|
||||
|
||||
BgWallpapersSource *
|
||||
bg_wallpapers_source_new (void)
|
||||
bg_wallpapers_source_new (GtkWidget *widget)
|
||||
{
|
||||
return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, NULL);
|
||||
return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, "widget", widget, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,6 @@ G_BEGIN_DECLS
|
||||
#define BG_TYPE_WALLPAPERS_SOURCE (bg_wallpapers_source_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (BgWallpapersSource, bg_wallpapers_source, BG, WALLPAPERS_SOURCE, BgSource)
|
||||
|
||||
BgWallpapersSource *bg_wallpapers_source_new (void);
|
||||
BgWallpapersSource *bg_wallpapers_source_new (GtkWidget *widget);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -24,14 +24,12 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
#include "bg-colors-source.h"
|
||||
#include "bg-recent-source.h"
|
||||
#include "bg-wallpapers-source.h"
|
||||
#include "cc-background-chooser.h"
|
||||
#include "cc-background-paintable.h"
|
||||
|
||||
#define THUMBNAIL_WIDTH 144
|
||||
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
|
||||
|
||||
struct _CcBackgroundChooser
|
||||
{
|
||||
GtkBox parent;
|
||||
@@ -44,8 +42,6 @@ struct _CcBackgroundChooser
|
||||
|
||||
BgWallpapersSource *wallpapers_source;
|
||||
BgRecentSource *recent_source;
|
||||
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundChooser, cc_background_chooser, GTK_TYPE_BOX)
|
||||
@@ -104,7 +100,6 @@ create_widget_func (gpointer model_item,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(CcBackgroundPaintable) paintable = NULL;
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
CcBackgroundItem *item;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *child;
|
||||
@@ -117,13 +112,7 @@ create_widget_func (gpointer model_item,
|
||||
source = BG_SOURCE (user_data);
|
||||
item = CC_BACKGROUND_ITEM (model_item);
|
||||
|
||||
thumbnail_factory = g_object_get_data (G_OBJECT (source), "thumbnail-factory");
|
||||
|
||||
paintable = cc_background_paintable_new (thumbnail_factory,
|
||||
item,
|
||||
CC_BACKGROUND_PAINT_LIGHT_DARK,
|
||||
THUMBNAIL_WIDTH,
|
||||
THUMBNAIL_HEIGHT);
|
||||
paintable = cc_background_paintable_new (source, item);
|
||||
|
||||
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (paintable));
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
@@ -154,8 +143,6 @@ create_widget_func (gpointer model_item,
|
||||
gtk_widget_add_css_class (button, "circular");
|
||||
gtk_widget_add_css_class (button, "remove-button");
|
||||
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("Remove Background"));
|
||||
|
||||
g_signal_connect (button,
|
||||
"clicked",
|
||||
G_CALLBACK (on_delete_background_clicked_cb),
|
||||
@@ -277,7 +264,6 @@ cc_background_chooser_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&self->recent_source);
|
||||
g_clear_object (&self->wallpapers_source);
|
||||
g_clear_object (&self->thumbnail_factory);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_chooser_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -312,13 +298,8 @@ cc_background_chooser_init (CcBackgroundChooser *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->recent_source = bg_recent_source_new ();
|
||||
self->wallpapers_source = bg_wallpapers_source_new ();
|
||||
|
||||
self->thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
g_object_set_data (G_OBJECT (self->recent_source), "thumbnail-factory", self->thumbnail_factory);
|
||||
g_object_set_data (G_OBJECT (self->wallpapers_source), "thumbnail-factory", self->thumbnail_factory);
|
||||
|
||||
self->recent_source = bg_recent_source_new (GTK_WIDGET (self));
|
||||
self->wallpapers_source = bg_wallpapers_source_new (GTK_WIDGET (self));
|
||||
setup_flowbox (self);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "cc-background-item.h"
|
||||
#include "gdesktop-enums-types.h"
|
||||
#include "cc-background-enum-types.h"
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
@@ -223,15 +222,15 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
pixbuf = gnome_bg_create_frame_thumbnail (bg,
|
||||
thumbs,
|
||||
&monitor_layout,
|
||||
scale_factor * width,
|
||||
scale_factor * height,
|
||||
width,
|
||||
height,
|
||||
frame);
|
||||
} else {
|
||||
pixbuf = gnome_bg_create_thumbnail (bg,
|
||||
thumbs,
|
||||
&monitor_layout,
|
||||
scale_factor * width,
|
||||
scale_factor * height);
|
||||
width,
|
||||
height);
|
||||
}
|
||||
|
||||
update_size (item);
|
||||
@@ -771,7 +770,7 @@ cc_background_item_class_init (CcBackgroundItemClass *klass)
|
||||
g_param_spec_flags ("flags",
|
||||
"flags",
|
||||
"flags",
|
||||
CC_TYPE_BACKGROUND_ITEM_FLAGS,
|
||||
G_DESKTOP_TYPE_BACKGROUND_ITEM_FLAGS,
|
||||
0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
@@ -885,7 +884,7 @@ flags_to_str (CcBackgroundItemFlags flag)
|
||||
GFlagsClass *fclass;
|
||||
GFlagsValue *value;
|
||||
|
||||
fclass = G_FLAGS_CLASS (g_type_class_peek (CC_TYPE_BACKGROUND_ITEM_FLAGS));
|
||||
fclass = G_FLAGS_CLASS (g_type_class_peek (G_DESKTOP_TYPE_BACKGROUND_ITEM_FLAGS));
|
||||
value = g_flags_get_first_value (fclass, flag);
|
||||
|
||||
g_assert (value);
|
||||
|
||||
@@ -19,36 +19,28 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "cc-background-enum-types.h"
|
||||
#include "cc-background-paintable.h"
|
||||
|
||||
struct _CcBackgroundPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
BgSource *source;
|
||||
CcBackgroundItem *item;
|
||||
int width;
|
||||
int height;
|
||||
int scale_factor;
|
||||
GtkTextDirection text_direction;
|
||||
|
||||
GdkPaintable *texture;
|
||||
GdkPaintable *dark_texture;
|
||||
|
||||
CcBackgroundPaintFlags paint_flags;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_THUMBNAIL_FACTORY,
|
||||
PROP_SOURCE,
|
||||
PROP_ITEM,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_TEXT_DIRECTION,
|
||||
PROP_PAINT_FLAGS,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
@@ -63,32 +55,34 @@ G_DEFINE_TYPE_WITH_CODE (CcBackgroundPaintable, cc_background_paintable, G_TYPE_
|
||||
static void
|
||||
update_cache (CcBackgroundPaintable *self)
|
||||
{
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
g_autoptr(GdkPixbuf) dark_pixbuf = NULL;
|
||||
gboolean has_dark;
|
||||
g_autoptr (GdkPixbuf) pixbuf = NULL;
|
||||
GnomeDesktopThumbnailFactory *factory;
|
||||
int width, height;
|
||||
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_object (&self->dark_texture);
|
||||
|
||||
has_dark = cc_background_item_has_dark_version (self->item);
|
||||
factory = bg_source_get_thumbnail_factory (self->source);
|
||||
width = bg_source_get_thumbnail_width (self->source);
|
||||
height = bg_source_get_thumbnail_height (self->source);
|
||||
|
||||
if ((self->paint_flags & CC_BACKGROUND_PAINT_LIGHT) || !has_dark)
|
||||
{
|
||||
pixbuf = cc_background_item_get_thumbnail (self->item,
|
||||
self->thumbnail_factory,
|
||||
self->width,
|
||||
self->height,
|
||||
self->scale_factor,
|
||||
FALSE);
|
||||
self->texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
|
||||
}
|
||||
pixbuf = cc_background_item_get_thumbnail (self->item,
|
||||
factory,
|
||||
width,
|
||||
height,
|
||||
self->scale_factor,
|
||||
FALSE);
|
||||
|
||||
if ((self->paint_flags & CC_BACKGROUND_PAINT_DARK) && has_dark)
|
||||
self->texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
|
||||
|
||||
if (cc_background_item_has_dark_version (self->item))
|
||||
{
|
||||
g_autoptr (GdkPixbuf) dark_pixbuf = NULL;
|
||||
|
||||
dark_pixbuf = cc_background_item_get_thumbnail (self->item,
|
||||
self->thumbnail_factory,
|
||||
self->width,
|
||||
self->height,
|
||||
factory,
|
||||
width,
|
||||
height,
|
||||
self->scale_factor,
|
||||
TRUE);
|
||||
self->dark_texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (dark_pixbuf));
|
||||
@@ -103,7 +97,7 @@ cc_background_paintable_dispose (GObject *object)
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object);
|
||||
|
||||
g_clear_object (&self->item);
|
||||
g_clear_object (&self->thumbnail_factory);
|
||||
g_clear_object (&self->source);
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_object (&self->dark_texture);
|
||||
|
||||
@@ -130,22 +124,14 @@ cc_background_paintable_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_THUMBNAIL_FACTORY:
|
||||
g_value_set_object (value, self->thumbnail_factory);
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, self->source);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, self->item);
|
||||
break;
|
||||
|
||||
case PROP_WIDTH:
|
||||
g_value_set_int (value, self->width);
|
||||
break;
|
||||
|
||||
case PROP_HEIGHT:
|
||||
g_value_set_int (value, self->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, self->scale_factor);
|
||||
break;
|
||||
@@ -154,10 +140,6 @@ cc_background_paintable_get_property (GObject *object,
|
||||
g_value_set_enum (value, self->text_direction);
|
||||
break;
|
||||
|
||||
case PROP_PAINT_FLAGS:
|
||||
g_value_set_flags (value, self->paint_flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -173,22 +155,14 @@ cc_background_paintable_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_THUMBNAIL_FACTORY:
|
||||
g_set_object (&self->thumbnail_factory, g_value_get_object (value));
|
||||
case PROP_SOURCE:
|
||||
g_set_object (&self->source, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_set_object (&self->item, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_WIDTH:
|
||||
self->width = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_HEIGHT:
|
||||
self->height = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
self->scale_factor = g_value_get_int (value);
|
||||
update_cache (self);
|
||||
@@ -199,10 +173,6 @@ cc_background_paintable_set_property (GObject *object,
|
||||
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
|
||||
break;
|
||||
|
||||
case PROP_PAINT_FLAGS:
|
||||
self->paint_flags = g_value_get_flags (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -218,11 +188,11 @@ cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
|
||||
object_class->get_property = cc_background_paintable_get_property;
|
||||
object_class->set_property = cc_background_paintable_set_property;
|
||||
|
||||
properties[PROP_THUMBNAIL_FACTORY] =
|
||||
g_param_spec_object ("thumbnail-factory",
|
||||
"Thumbnail factory",
|
||||
"Thumbnail factory",
|
||||
GNOME_DESKTOP_TYPE_THUMBNAIL_FACTORY,
|
||||
properties[PROP_SOURCE] =
|
||||
g_param_spec_object ("source",
|
||||
"Source",
|
||||
"Source",
|
||||
BG_TYPE_SOURCE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
@@ -236,24 +206,6 @@ cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_WIDTH] =
|
||||
g_param_spec_int ("width",
|
||||
"Width",
|
||||
"Width",
|
||||
1, G_MAXINT, 144,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_HEIGHT] =
|
||||
g_param_spec_int ("height",
|
||||
"Height",
|
||||
"Height",
|
||||
1, G_MAXINT, 144 * 3 / 4,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
"Scale Factor",
|
||||
@@ -271,16 +223,6 @@ cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_PAINT_FLAGS] =
|
||||
g_param_spec_flags ("paint-flags",
|
||||
"Paint Flags",
|
||||
"Paint Flags",
|
||||
CC_TYPE_BACKGROUND_PAINT_FLAGS,
|
||||
CC_BACKGROUND_PAINT_LIGHT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@@ -306,12 +248,6 @@ cc_background_paintable_snapshot (GdkPaintable *paintable,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->texture)
|
||||
{
|
||||
gdk_paintable_snapshot (self->dark_texture, snapshot, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
is_rtl = self->text_direction == GTK_TEXT_DIR_RTL;
|
||||
|
||||
gtk_snapshot_push_clip (GTK_SNAPSHOT (snapshot),
|
||||
@@ -335,27 +271,24 @@ static int
|
||||
cc_background_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
GdkPaintable *valid_texture = self->texture ? self->texture : self->dark_texture;
|
||||
|
||||
return gdk_paintable_get_intrinsic_width (valid_texture) / self->scale_factor;
|
||||
return gdk_paintable_get_intrinsic_width (self->texture) / self->scale_factor;
|
||||
}
|
||||
|
||||
static int
|
||||
cc_background_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
GdkPaintable *valid_texture = self->texture ? self->texture : self->dark_texture;
|
||||
|
||||
return gdk_paintable_get_intrinsic_height (valid_texture) / self->scale_factor;
|
||||
return gdk_paintable_get_intrinsic_height (self->texture) / self->scale_factor;
|
||||
}
|
||||
|
||||
static double
|
||||
cc_background_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
GdkPaintable *valid_texture = self->texture ? self->texture : self->dark_texture;
|
||||
|
||||
return gdk_paintable_get_intrinsic_aspect_ratio (valid_texture);
|
||||
return gdk_paintable_get_intrinsic_aspect_ratio (self->texture);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -367,24 +300,15 @@ cc_background_paintable_paintable_init (GdkPaintableInterface *iface)
|
||||
iface->get_intrinsic_aspect_ratio = cc_background_paintable_get_intrinsic_aspect_ratio;
|
||||
}
|
||||
|
||||
/* Workaround for a typo in libgnome-desktop, see gnome-desktop!160 */
|
||||
#define G_TYPE_INSTANCE_CHECK_TYPE G_TYPE_CHECK_INSTANCE_TYPE
|
||||
|
||||
CcBackgroundPaintable *
|
||||
cc_background_paintable_new (GnomeDesktopThumbnailFactory *thumbnail_factory,
|
||||
CcBackgroundItem *item,
|
||||
CcBackgroundPaintFlags paint_flags,
|
||||
int width,
|
||||
int height)
|
||||
cc_background_paintable_new (BgSource *source,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
g_return_val_if_fail (GNOME_DESKTOP_IS_THUMBNAIL_FACTORY (thumbnail_factory), NULL);
|
||||
g_return_val_if_fail (BG_IS_SOURCE (source), NULL);
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
|
||||
|
||||
return g_object_new (CC_TYPE_BACKGROUND_PAINTABLE,
|
||||
"thumbnail-factory", thumbnail_factory,
|
||||
"source", source,
|
||||
"item", item,
|
||||
"paint-flags", paint_flags,
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -23,25 +23,13 @@
|
||||
|
||||
#include "bg-source.h"
|
||||
#include "cc-background-item.h"
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_BACKGROUND_PAINTABLE (cc_background_paintable_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundPaintable, cc_background_paintable, CC, BACKGROUND_PAINTABLE, GObject)
|
||||
|
||||
typedef enum {
|
||||
CC_BACKGROUND_PAINT_LIGHT = 1 << 0,
|
||||
CC_BACKGROUND_PAINT_DARK = 1 << 1
|
||||
} CcBackgroundPaintFlags;
|
||||
|
||||
#define CC_BACKGROUND_PAINT_LIGHT_DARK (CC_BACKGROUND_PAINT_LIGHT | \
|
||||
CC_BACKGROUND_PAINT_DARK)
|
||||
|
||||
CcBackgroundPaintable * cc_background_paintable_new (GnomeDesktopThumbnailFactory *thumbnail_factory,
|
||||
CcBackgroundItem *item,
|
||||
CcBackgroundPaintFlags paint_flags,
|
||||
int width,
|
||||
int height);
|
||||
CcBackgroundPaintable * cc_background_paintable_new (BgSource *source,
|
||||
CcBackgroundItem *item);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<property name="focusable">False</property>
|
||||
<child>
|
||||
<object class="AdwClamp">
|
||||
<property name="maximum-size">400</property>
|
||||
<property name="tightening-threshold">300</property>
|
||||
<property name="maximum_size">400</property>
|
||||
<property name="tightening_threshold">300</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="column-homogeneous">True</property>
|
||||
@@ -52,9 +52,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="default_label">
|
||||
<property name="label" translatable="yes">_Default</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">default_toggle</property>
|
||||
<property name="label" translatable="yes">Default</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
@@ -84,9 +82,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="dark_label">
|
||||
<property name="label" translatable="yes">Da_rk</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">dark_toggle</property>
|
||||
<property name="label" translatable="yes">Dark</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
@@ -111,8 +107,7 @@
|
||||
<child>
|
||||
<object class="AdwButtonContent">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<property name="label" translatable="yes">_Add Picture…</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="label" translatable="yes">Add Picture…</property>
|
||||
</object>
|
||||
</child>
|
||||
<signal name="clicked" handler="on_add_picture_button_clicked_cb" object="CcBackgroundPanel" swapped="yes" />
|
||||
|
||||
@@ -21,16 +21,12 @@
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
#include "cc-background-preview.h"
|
||||
#include "cc-background-paintable.h"
|
||||
|
||||
#define THUMBNAIL_WIDTH 256 /* No use asking for more, gnome_bg caps at 256 */
|
||||
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
|
||||
|
||||
struct _CcBackgroundPreview
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkWidget *picture;
|
||||
GtkWidget *drawing_area;
|
||||
GtkWidget *light_dark_window;
|
||||
GtkWidget *dark_window;
|
||||
|
||||
@@ -52,6 +48,35 @@ enum
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static void
|
||||
draw_preview_func (GtkDrawingArea *drawing_area,
|
||||
cairo_t *cr,
|
||||
gint width,
|
||||
gint height,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundPreview *self = CC_BACKGROUND_PREVIEW (user_data);
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
gint scale_factor;
|
||||
|
||||
if (!self->item)
|
||||
return;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (drawing_area));
|
||||
pixbuf = cc_background_item_get_thumbnail (self->item,
|
||||
self->thumbnail_factory,
|
||||
width,
|
||||
height,
|
||||
scale_factor,
|
||||
self->is_dark &&
|
||||
cc_background_item_has_dark_version (self->item));
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_paint (cr);
|
||||
}
|
||||
|
||||
/* GObject overrides */
|
||||
|
||||
static void
|
||||
@@ -59,7 +84,7 @@ cc_background_preview_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundPreview *self = (CcBackgroundPreview *)object;
|
||||
|
||||
g_clear_pointer (&self->picture, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->drawing_area, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->light_dark_window, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->dark_window, gtk_widget_unparent);
|
||||
|
||||
@@ -147,6 +172,36 @@ cc_background_preview_get_request_mode (GtkWidget *widget)
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
get_primary_monitor_geometry (int *width, int *height)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GListModel *monitors;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
monitors = gdk_display_get_monitors (display);
|
||||
if (monitors)
|
||||
{
|
||||
g_autoptr(GdkMonitor) primary_monitor = NULL;
|
||||
GdkRectangle monitor_layout;
|
||||
|
||||
primary_monitor = g_list_model_get_item (monitors, 0);
|
||||
gdk_monitor_get_geometry (primary_monitor, &monitor_layout);
|
||||
if (width)
|
||||
*width = monitor_layout.width;
|
||||
if (height)
|
||||
*height = monitor_layout.height;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = 1920;
|
||||
if (height)
|
||||
*height = 1080;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -157,17 +212,21 @@ cc_background_preview_measure (GtkWidget *widget,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int width;
|
||||
|
||||
get_primary_monitor_geometry (&width, NULL);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*natural = THUMBNAIL_WIDTH;
|
||||
*minimum = 0;
|
||||
}
|
||||
*natural = width;
|
||||
else if (for_size < 0)
|
||||
*natural = 0;
|
||||
else
|
||||
{
|
||||
*natural = MAX (0, for_size * 3 / 4); /* 4:3 aspect ratio */
|
||||
*minimum = *natural;
|
||||
}
|
||||
*natural = floor ((double) for_size * 0.75); /* 4:3 aspect ratio */
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
*minimum = *natural;
|
||||
else
|
||||
*minimum = 0;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child;
|
||||
@@ -210,7 +269,7 @@ cc_background_preview_size_allocate (GtkWidget *widget,
|
||||
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (is_rtl ? margin_x : opposite_margin_x,
|
||||
margin_y));
|
||||
|
||||
gtk_widget_allocate (self->picture, width, height, baseline, NULL);
|
||||
gtk_widget_allocate (self->drawing_area, width, height, baseline, NULL);
|
||||
gtk_widget_allocate (self->dark_window, window_width, window_height,
|
||||
baseline, back_transform);
|
||||
gtk_widget_allocate (self->light_dark_window, window_width, window_height,
|
||||
@@ -248,7 +307,7 @@ cc_background_preview_class_init (CcBackgroundPreviewClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-preview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, picture);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, drawing_area);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, light_dark_window);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, dark_window);
|
||||
|
||||
@@ -275,27 +334,15 @@ void
|
||||
cc_background_preview_set_item (CcBackgroundPreview *self,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
g_autoptr(CcBackgroundPaintable) paintable;
|
||||
CcBackgroundPaintFlags paint_flags;
|
||||
|
||||
g_return_if_fail (CC_IS_BACKGROUND_PREVIEW (self));
|
||||
g_return_if_fail (CC_IS_BACKGROUND_ITEM (item));
|
||||
|
||||
if (!g_set_object (&self->item, item))
|
||||
return;
|
||||
|
||||
paint_flags = self->is_dark ? CC_BACKGROUND_PAINT_DARK : CC_BACKGROUND_PAINT_LIGHT;
|
||||
|
||||
paintable = cc_background_paintable_new (self->thumbnail_factory,
|
||||
item,
|
||||
paint_flags,
|
||||
THUMBNAIL_WIDTH,
|
||||
THUMBNAIL_HEIGHT);
|
||||
|
||||
g_object_bind_property (self->picture, "scale-factor",
|
||||
paintable, "scale-factor", G_BINDING_SYNC_CREATE);
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (self->picture), GDK_PAINTABLE (paintable));
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (self->drawing_area),
|
||||
draw_preview_func, self, NULL);
|
||||
gtk_widget_queue_draw (self->drawing_area);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
|
||||
<!-- Wallpaper -->
|
||||
<child>
|
||||
<object class="GtkPicture" id="picture">
|
||||
<property name="content-fit">cover</property>
|
||||
</object>
|
||||
<object class="GtkDrawingArea" id="drawing_area"/>
|
||||
</child>
|
||||
|
||||
<!-- Always dark window -->
|
||||
|
||||
@@ -626,7 +626,10 @@ cc_background_xml_finalize (GObject *object)
|
||||
g_slist_free_full (xml->monitors, g_object_unref);
|
||||
|
||||
g_clear_pointer (&xml->wp_hash, g_hash_table_destroy);
|
||||
g_clear_handle_id (&xml->item_added_id, g_source_remove);
|
||||
if (xml->item_added_id != 0) {
|
||||
g_source_remove (xml->item_added_id);
|
||||
xml->item_added_id = 0;
|
||||
}
|
||||
g_clear_pointer (&xml->item_added_queue, g_async_queue_unref);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_xml_parent_class)->finalize (object);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#222222">
|
||||
<path d="m 3.011719 1 c -1.644531 0 -3.0000002 1.355469 -3.0000002 3 v 6 c 0 1.644531 1.3554692 3 3.0000002 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -5 h -0.011719 c 0 -0.550781 -0.449219 -1 -1 -1 s -1 0.449219 -1 1 v 0.5 l 0.011719 4.5 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570313 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429687 -1 1 -1 h 4.988281 c 0.550781 0 1 -0.449219 1 -1 c 0 -0.542969 -0.4375 -0.988281 -0.980469 -1 z m 0 0"/>
|
||||
<g fill="#2e3436">
|
||||
<path d="m 3.011719 1 c -1.644531 0 -3.0000002 1.355469 -3.0000002 3 v 6 c 0 1.644531 1.3554692 3 3.0000002 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -6 c 0 -0.570312 -0.167969 -1.101562 -0.449219 -1.558594 l -1.550781 1.554688 v 6.003906 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570313 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429687 -1 1 -1 h 5.96875 l 2.007812 -2 z m 0 0"/>
|
||||
<path d="m 11.011719 7 c 0 1.65625 -1.339844 3.007812 -3 3 h -3 v -3 c 0 -1.660156 1.34375 -3 3 -3 c 1.660156 0 3 1.339844 3 3 z m 0 0"/>
|
||||
<path d="m 13.410156 0 l -3.46875 3.457031 c 0.683594 0.355469 1.234375 0.910157 1.589844 1.589844 l 0.171875 -0.171875 l 0.007813 0.007812 l 4.300781 -4.300781 v -0.582031 z m 0 0"/>
|
||||
<path d="m 5.011719 14 c -1.105469 0 -2 0.894531 -2 2 h 10 c 0 -1.105469 -0.894531 -2 -2 -2 z m 0 0"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 999 B |
@@ -17,14 +17,10 @@ install_data(
|
||||
|
||||
common_sources = []
|
||||
|
||||
common_sources += gnome.mkenums_simple(
|
||||
'cc-background-enum-types',
|
||||
sources: ['cc-background-item.h', 'cc-background-paintable.h']
|
||||
)
|
||||
|
||||
enums = 'gdesktop-enums-types'
|
||||
enums_header = files(
|
||||
gsettings_desktop_dep.get_variable(pkgconfig: 'prefix') + '/include/gsettings-desktop-schemas/gdesktop-enums.h'
|
||||
gsettings_desktop_dep.get_variable(pkgconfig: 'prefix') + '/include/gsettings-desktop-schemas/gdesktop-enums.h',
|
||||
'cc-background-item.h'
|
||||
)
|
||||
|
||||
common_sources += gnome.mkenums(
|
||||
@@ -54,6 +50,7 @@ common_sources += gnome.compile_resources(
|
||||
)
|
||||
|
||||
sources = common_sources + files(
|
||||
'bg-colors-source.c',
|
||||
'bg-recent-source.c',
|
||||
'bg-source.c',
|
||||
'bg-wallpapers-source.c',
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<object class="AdwStatusPage" id="no_devices_page">
|
||||
<property name="icon-name">bluetooth-active-symbolic</property>
|
||||
<property name="title" translatable="yes">No Bluetooth Found</property>
|
||||
<property name="description" translatable="yes">Plug in a dongle to use Bluetooth</property>
|
||||
<property name="description" translatable="yes">Plug in a dongle to use Bluetooth.</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -61,7 +61,7 @@
|
||||
<object class="AdwStatusPage" id="hw_airplane_page">
|
||||
<property name="icon-name">airplane-mode-symbolic</property>
|
||||
<property name="title" translatable="yes">Hardware Airplane Mode is On</property>
|
||||
<property name="description" translatable="yes">Turn off the Airplane mode switch to enable Bluetooth</property>
|
||||
<property name="description" translatable="yes">Turn off the Airplane mode switch to enable Bluetooth.</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
|
||||
#include "cc-common-resources.h"
|
||||
#include "cc-hostname.h"
|
||||
#include "cc-hostname-entry.h"
|
||||
#include "hostname-helper.h"
|
||||
|
||||
@@ -30,6 +29,7 @@ struct _CcHostnameEntry
|
||||
{
|
||||
AdwEntryRow parent;
|
||||
|
||||
GDBusProxy *hostnamed_proxy;
|
||||
guint set_hostname_timeout_source_id;
|
||||
};
|
||||
|
||||
@@ -37,23 +37,119 @@ G_DEFINE_TYPE (CcHostnameEntry, cc_hostname_entry, ADW_TYPE_ENTRY_ROW)
|
||||
|
||||
#define SET_HOSTNAME_TIMEOUT 1
|
||||
|
||||
static void
|
||||
cc_hostname_entry_set_hostname (CcHostnameEntry *self)
|
||||
{
|
||||
g_autofree gchar *hostname = NULL;
|
||||
g_autoptr(GVariant) pretty_result = NULL;
|
||||
g_autoptr(GVariant) static_result = NULL;
|
||||
g_autoptr(GError) pretty_error = NULL;
|
||||
g_autoptr(GError) static_error = NULL;
|
||||
const gchar *text;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (self));
|
||||
|
||||
g_debug ("Setting PrettyHostname to '%s'", text);
|
||||
pretty_result = g_dbus_proxy_call_sync (self->hostnamed_proxy,
|
||||
"SetPrettyHostname",
|
||||
g_variant_new ("(sb)", text, FALSE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, &pretty_error);
|
||||
if (pretty_result == NULL)
|
||||
g_warning ("Could not set PrettyHostname: %s", pretty_error->message);
|
||||
|
||||
/* Set the static hostname */
|
||||
hostname = pretty_hostname_to_static (text, FALSE);
|
||||
g_assert (hostname);
|
||||
|
||||
g_debug ("Setting StaticHostname to '%s'", hostname);
|
||||
static_result = g_dbus_proxy_call_sync (self->hostnamed_proxy,
|
||||
"SetStaticHostname",
|
||||
g_variant_new ("(sb)", hostname, FALSE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, &static_error);
|
||||
if (static_result == NULL)
|
||||
g_warning ("Could not set StaticHostname: %s", static_error->message);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_hostname_property (CcHostnameEntry *self,
|
||||
const char *property)
|
||||
{
|
||||
g_autoptr(GVariant) variant = NULL;
|
||||
|
||||
if (!self->hostnamed_proxy)
|
||||
return g_strdup ("");
|
||||
|
||||
variant = g_dbus_proxy_get_cached_property (self->hostnamed_proxy,
|
||||
property);
|
||||
if (!variant)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GVariant) inner = NULL;
|
||||
|
||||
/* Work around systemd-hostname not sending us back
|
||||
* the property value when changing values */
|
||||
variant = g_dbus_proxy_call_sync (self->hostnamed_proxy,
|
||||
"org.freedesktop.DBus.Properties.Get",
|
||||
g_variant_new ("(ss)", "org.freedesktop.hostname1", property),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
if (variant == NULL)
|
||||
{
|
||||
g_warning ("Failed to get property '%s': %s", property, error->message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_get (variant, "(v)", &inner);
|
||||
return g_variant_dup_string (inner, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_variant_dup_string (variant, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
cc_hostname_entry_get_display_hostname (CcHostnameEntry *self)
|
||||
{
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
str = get_hostname_property (self, "PrettyHostname");
|
||||
|
||||
/* Empty strings means that we need to fallback */
|
||||
if (str != NULL &&
|
||||
*str == '\0')
|
||||
return get_hostname_property (self, "Hostname");
|
||||
|
||||
return g_steal_pointer (&str);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_hostname_timeout (CcHostnameEntry *self)
|
||||
{
|
||||
const gchar *text = NULL;
|
||||
|
||||
self->set_hostname_timeout_source_id = 0;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (self));
|
||||
cc_hostname_set_hostname (cc_hostname_get_default (), text);
|
||||
cc_hostname_entry_set_hostname (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_hostname_timeout (CcHostnameEntry *self)
|
||||
{
|
||||
if (self->set_hostname_timeout_source_id)
|
||||
g_source_remove (self->set_hostname_timeout_source_id);
|
||||
|
||||
self->set_hostname_timeout_source_id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_hostname_timeout (CcHostnameEntry *self)
|
||||
{
|
||||
g_clear_handle_id (&self->set_hostname_timeout_source_id, g_source_remove);
|
||||
remove_hostname_timeout (self);
|
||||
|
||||
self->set_hostname_timeout_source_id = g_timeout_add_seconds (SET_HOSTNAME_TIMEOUT,
|
||||
(GSourceFunc) set_hostname_timeout,
|
||||
@@ -73,10 +169,12 @@ cc_hostname_entry_dispose (GObject *object)
|
||||
|
||||
if (self->set_hostname_timeout_source_id)
|
||||
{
|
||||
g_clear_handle_id (&self->set_hostname_timeout_source_id, g_source_remove);
|
||||
remove_hostname_timeout (self);
|
||||
set_hostname_timeout (self);
|
||||
}
|
||||
|
||||
g_clear_object (&self->hostnamed_proxy);
|
||||
|
||||
G_OBJECT_CLASS (cc_hostname_entry_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -109,7 +207,25 @@ cc_hostname_entry_constructed (GObject *object)
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
||||
}
|
||||
|
||||
str = cc_hostname_get_display_hostname (cc_hostname_get_default ());
|
||||
self->hostnamed_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
"org.freedesktop.hostname1",
|
||||
"/org/freedesktop/hostname1",
|
||||
"org.freedesktop.hostname1",
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
/* This could only happen if the policy file was installed
|
||||
* but not hostnamed, which points to a system bug */
|
||||
if (self->hostnamed_proxy == NULL)
|
||||
{
|
||||
g_debug ("Couldn't get hostnamed to start, bailing: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
str = cc_hostname_entry_get_display_hostname (CC_HOSTNAME_ENTRY (self));
|
||||
|
||||
if (str != NULL)
|
||||
gtk_editable_set_text (GTK_EDITABLE (self), str);
|
||||
else
|
||||
@@ -140,3 +256,9 @@ cc_hostname_entry_new (void)
|
||||
{
|
||||
return g_object_new (CC_TYPE_HOSTNAME_ENTRY, NULL);
|
||||
}
|
||||
|
||||
gchar*
|
||||
cc_hostname_entry_get_hostname (CcHostnameEntry *entry)
|
||||
{
|
||||
return get_hostname_property (entry, "Hostname");
|
||||
}
|
||||
|
||||
@@ -28,5 +28,6 @@ G_BEGIN_DECLS
|
||||
G_DECLARE_FINAL_TYPE (CcHostnameEntry, cc_hostname_entry, CC, HOSTNAME_ENTRY, AdwEntryRow)
|
||||
|
||||
CcHostnameEntry *cc_hostname_entry_new (void);
|
||||
gchar* cc_hostname_entry_get_hostname (CcHostnameEntry *entry);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* cc-hostname.c
|
||||
*
|
||||
* Copyright 2023 Red Hat Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author(s):
|
||||
* Felipe Borges <felipeborges@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "cc-hostname"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "cc-hostname.h"
|
||||
#include "hostname-helper.h"
|
||||
#include "shell/cc-object-storage.h"
|
||||
|
||||
#define HOSTNAME_BUS_NAME "org.freedesktop.hostname1"
|
||||
#define HOSTNAME_OBJECT_PATH "/org/freedesktop/hostname1"
|
||||
|
||||
struct _CcHostname
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GDBusProxy *proxy;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcHostname, cc_hostname, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
cc_hostname_dispose (GObject *object)
|
||||
{
|
||||
CcHostname *self = CC_HOSTNAME (object);
|
||||
|
||||
g_clear_object (&self->proxy);
|
||||
|
||||
G_OBJECT_CLASS (cc_hostname_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_hostname_constructed (GObject *object)
|
||||
{
|
||||
CcHostname *self = CC_HOSTNAME (object);
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
self->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
HOSTNAME_BUS_NAME,
|
||||
HOSTNAME_OBJECT_PATH,
|
||||
HOSTNAME_BUS_NAME,
|
||||
NULL,
|
||||
&error);
|
||||
if (self->proxy == NULL) {
|
||||
g_critical ("Couldn't connect to hostnamed: %s", error->message);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_hostname_init (CcHostname *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
cc_hostname_class_init (CcHostnameClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = cc_hostname_constructed;
|
||||
object_class->dispose = cc_hostname_dispose;
|
||||
}
|
||||
|
||||
CcHostname *
|
||||
cc_hostname_get_default (void)
|
||||
{
|
||||
g_autoptr(CcHostname) self = NULL;
|
||||
|
||||
if (cc_object_storage_has_object (CC_OBJECT_HOSTNAME)) {
|
||||
self = cc_object_storage_get_object (CC_OBJECT_HOSTNAME);
|
||||
} else {
|
||||
self = g_object_new (CC_TYPE_HOSTNAME, NULL);
|
||||
cc_object_storage_add_object (CC_OBJECT_HOSTNAME, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
gchar *
|
||||
cc_hostname_get_property (CcHostname *self,
|
||||
const gchar *property)
|
||||
{
|
||||
g_autoptr(GVariant) variant = NULL;
|
||||
g_autoptr(GVariant) inner = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_return_val_if_fail (CC_IS_HOSTNAME (self), NULL);
|
||||
g_return_val_if_fail (property != NULL, NULL);
|
||||
|
||||
if (!self->proxy)
|
||||
return g_strdup ("");
|
||||
|
||||
variant = g_dbus_proxy_get_cached_property (self->proxy, property);
|
||||
if (variant)
|
||||
return g_variant_dup_string (variant, NULL);
|
||||
|
||||
variant = g_dbus_proxy_call_sync (self->proxy,
|
||||
"org.freedesktop.DBus.Properties.Get",
|
||||
g_variant_new ("(ss)", HOSTNAME_BUS_NAME, property),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
if (variant == NULL) {
|
||||
g_warning ("Failed to get property '%s': %s", property, error->message);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_get (variant, "(v)", &inner);
|
||||
return g_variant_dup_string (inner, NULL);
|
||||
}
|
||||
|
||||
gchar *
|
||||
cc_hostname_get_display_hostname (CcHostname *self)
|
||||
{
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
g_return_val_if_fail (CC_IS_HOSTNAME (self), NULL);
|
||||
|
||||
str = cc_hostname_get_property (self, "PrettyHostname");
|
||||
/* Empty strings means that we need to fallback */
|
||||
if (str != NULL && *str == '\0')
|
||||
return cc_hostname_get_property (self, "Hostname");
|
||||
|
||||
return g_steal_pointer (&str);
|
||||
}
|
||||
|
||||
void
|
||||
cc_hostname_set_hostname (CcHostname *self,
|
||||
const gchar *hostname)
|
||||
{
|
||||
g_autofree gchar *static_hostname = NULL;
|
||||
g_autoptr(GVariant) pretty_result = NULL;
|
||||
g_autoptr(GVariant) static_result = NULL;
|
||||
g_autoptr(GError) pretty_error = NULL;
|
||||
g_autoptr(GError) static_error = NULL;
|
||||
|
||||
g_return_if_fail (CC_IS_HOSTNAME (self));
|
||||
g_return_if_fail (hostname != NULL);
|
||||
|
||||
g_debug ("Setting PrettyHostname to '%s'", hostname);
|
||||
pretty_result = g_dbus_proxy_call_sync (self->proxy,
|
||||
"SetPrettyHostname",
|
||||
g_variant_new ("(sb)", hostname, FALSE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, &pretty_error);
|
||||
if (pretty_result == NULL)
|
||||
g_warning ("Could not set PrettyHostname: %s", pretty_error->message);
|
||||
|
||||
/* Set the static hostname */
|
||||
static_hostname = pretty_hostname_to_static (hostname, FALSE);
|
||||
g_assert (hostname);
|
||||
|
||||
g_debug ("Setting StaticHostname to '%s'", static_hostname);
|
||||
static_result = g_dbus_proxy_call_sync (self->proxy,
|
||||
"SetStaticHostname",
|
||||
g_variant_new ("(sb)", static_hostname, FALSE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, &static_error);
|
||||
if (static_result == NULL)
|
||||
g_warning ("Could not set StaticHostname: %s", static_error->message);
|
||||
}
|
||||
|
||||
gchar *
|
||||
cc_hostname_get_chassis_type (CcHostname *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_HOSTNAME (self), NULL);
|
||||
|
||||
return cc_hostname_get_property (self, "Chassis");
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_hostname_is_vm_chassis (CcHostname *self)
|
||||
{
|
||||
g_autofree gchar *chassis_type = NULL;
|
||||
|
||||
g_return_val_if_fail (CC_IS_HOSTNAME (self), FALSE);
|
||||
|
||||
chassis_type = cc_hostname_get_chassis_type (self);
|
||||
return g_strcmp0 (chassis_type, "vm") == 0;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* cc-hostname.h
|
||||
*
|
||||
* Copyright 2023 Red Hat Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author(s):
|
||||
* Felipe Borges <felipeborges@gnome.org>
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_HOSTNAME (cc_hostname_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcHostname, cc_hostname, CC, HOSTNAME, GObject)
|
||||
|
||||
CcHostname *cc_hostname_get_default (void);
|
||||
|
||||
gchar *cc_hostname_get_display_hostname (CcHostname *self);
|
||||
|
||||
void cc_hostname_set_hostname (CcHostname *self, const gchar *hostname);
|
||||
|
||||
gchar *cc_hostname_get_property (CcHostname *self, const gchar *property);
|
||||
|
||||
gchar *cc_hostname_get_chassis_type (CcHostname *self);
|
||||
|
||||
gboolean cc_hostname_is_vm_chassis (CcHostname *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -3,11 +3,13 @@
|
||||
<template class="CcListRowInfoButton" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="button">
|
||||
<property name="tooltip-text" translatable="yes">More Information</property>
|
||||
<property name="icon-name">info-symbolic</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
<accessibility>
|
||||
<property name="label" translatable="yes">More information</property>
|
||||
</accessibility>
|
||||
<property name="popover">
|
||||
<object class="GtkPopover" id="popover">
|
||||
<child>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,7 +11,4 @@
|
||||
<file preprocess="xml-stripblanks">cc-split-row.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-vertical-row.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gnome/Settings/icons/scalable/actions">
|
||||
<file preprocess="xml-stripblanks">info-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <gdk/x11/gdkx.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
@@ -313,27 +312,8 @@ gsd_device_manager_real_lookup_device (GsdDeviceManager *manager,
|
||||
GsdDevice *device;
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (GDK_IS_X11_DISPLAY (display)) {
|
||||
XIDeviceInfo *info;
|
||||
int n_infos, i, source_id = 0;
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
info = XIQueryDevice (gdk_x11_display_get_xdisplay (display),
|
||||
gdk_x11_device_get_id (gdk_device),
|
||||
&n_infos);
|
||||
if (gdk_x11_display_error_trap_pop (display) != 0)
|
||||
return NULL;
|
||||
if (!info || n_infos != 1)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < info->num_classes; i++) {
|
||||
if (info->classes[i]->type == XIValuatorClass)
|
||||
source_id = info->classes[i]->sourceid;
|
||||
}
|
||||
|
||||
if (source_id != 0)
|
||||
node_path = xdevice_get_device_node (source_id);
|
||||
}
|
||||
if (GDK_IS_X11_DISPLAY (display))
|
||||
node_path = xdevice_get_device_node (gdk_x11_device_get_id (gdk_device));
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 8 1 c -3.855469 0 -7 3.144531 -7 7 s 3.144531 7 7 7 s 7 -3.144531 7 -7 s -3.144531 -7 -7 -7 z m 0 2.875 c 0.621094 0 1.125 0.503906 1.125 1.125 s -0.503906 1.125 -1.125 1.125 s -1.125 -0.503906 -1.125 -1.125 s 0.503906 -1.125 1.125 -1.125 z m 1 3.125 v 5 h -2 v -5 z m 0 0" fill="#222222"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 440 B |
@@ -54,7 +54,6 @@ libwidgets_dep = declare_dependency(
|
||||
|
||||
sources = common_sources + files(
|
||||
'cc-common-language.c',
|
||||
'cc-hostname.c',
|
||||
'cc-illustrated-row.c',
|
||||
'cc-language-chooser.c',
|
||||
'cc-language-row.c',
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/*
|
||||
* cc-datetime-page.c
|
||||
*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||
* Copyright 2023 Gotam Gorabh <gautamy672@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,12 +15,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "cc-list-row.h"
|
||||
#include "cc-time-editor.h"
|
||||
#include "cc-datetime-page.h"
|
||||
#include "cc-datetime-panel.h"
|
||||
#include "cc-datetime-resources.h"
|
||||
#include "cc-list-row.h"
|
||||
|
||||
#include <langinfo.h>
|
||||
#include <sys/time.h>
|
||||
@@ -66,9 +67,9 @@
|
||||
#define DATETIME_SCHEMA "org.gnome.desktop.datetime"
|
||||
#define AUTO_TIMEZONE_KEY "automatic-timezone"
|
||||
|
||||
struct _CcDateTimePage
|
||||
struct _CcDateTimePanel
|
||||
{
|
||||
AdwNavigationPage parent_instance;
|
||||
CcPanel parent_instance;
|
||||
|
||||
GList *toplevels;
|
||||
|
||||
@@ -84,29 +85,32 @@ struct _CcDateTimePage
|
||||
GSettings *filechooser_settings;
|
||||
GDesktopClockFormat clock_format;
|
||||
AdwActionRow *auto_datetime_row;
|
||||
AdwSwitchRow *auto_timezone_row;
|
||||
AdwActionRow *auto_timezone_row;
|
||||
GtkSwitch *auto_timezone_switch;
|
||||
AdwActionRow *datetime_row;
|
||||
GtkWindow *datetime_dialog;
|
||||
GtkLabel *datetime_label;
|
||||
AdwSpinRow *day_spin_row;
|
||||
GtkToggleButton *twentyfour_format_button;
|
||||
GtkToggleButton *ampm_format_button;
|
||||
GtkSpinButton *day_spinbutton;
|
||||
AdwComboRow *timeformat_row;
|
||||
GtkSpinButton *h_spinbutton;
|
||||
AdwSwitchRow *weekday_row;
|
||||
AdwSwitchRow *date_row;
|
||||
AdwSwitchRow *seconds_row;
|
||||
AdwSwitchRow *week_numbers_row;
|
||||
GtkWidget *weekday_row;
|
||||
GtkWidget *weekday_switch;
|
||||
GtkWidget *date_switch;
|
||||
GtkWidget *seconds_switch;
|
||||
GtkWidget *week_numbers_switch;
|
||||
GtkLockButton *lock_button;
|
||||
GtkListBox *date_box;
|
||||
AdwActionRow *day_row;
|
||||
GtkSingleSelection *month_model;
|
||||
GtkPopover *month_popover;
|
||||
CcListRow *month_row;
|
||||
AdwActionRow *year_row;
|
||||
GtkSwitch *network_time_switch;
|
||||
CcTimeEditor *time_editor;
|
||||
AdwActionRow *timezone_row;
|
||||
CcTzDialog *timezone_dialog;
|
||||
GtkLabel *timezone_label;
|
||||
AdwSpinRow *year_spin_row;
|
||||
GtkSpinButton *year_spinbutton;
|
||||
|
||||
GnomeWallClock *clock_tracker;
|
||||
|
||||
@@ -122,14 +126,19 @@ struct _CcDateTimePage
|
||||
int month; /* index starts from 1 */
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcDateTimePage, cc_date_time_page, ADW_TYPE_NAVIGATION_PAGE)
|
||||
CC_PANEL_REGISTER (CcDateTimePanel, cc_date_time_panel)
|
||||
|
||||
static void update_time (CcDateTimePage *self);
|
||||
static void update_time (CcDateTimePanel *self);
|
||||
|
||||
static void on_month_selection_changed_cb (CcDateTimePanel *self);
|
||||
|
||||
static void time_changed_cb (CcDateTimePanel *self,
|
||||
CcTimeEditor *editor);
|
||||
|
||||
static void
|
||||
cc_date_time_page_dispose (GObject *object)
|
||||
cc_date_time_panel_dispose (GObject *object)
|
||||
{
|
||||
CcDateTimePage *self = CC_DATE_TIME_PAGE (object);
|
||||
CcDateTimePanel *self = CC_DATE_TIME_PANEL (object);
|
||||
|
||||
if (self->cancellable)
|
||||
{
|
||||
@@ -155,24 +164,45 @@ cc_date_time_page_dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&self->date, g_date_time_unref);
|
||||
|
||||
G_OBJECT_CLASS (cc_date_time_page_parent_class)->dispose (object);
|
||||
G_OBJECT_CLASS (cc_date_time_panel_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void clock_settings_changed_cb (CcDateTimePage *self,
|
||||
gchar *key);
|
||||
static const char *
|
||||
cc_date_time_panel_get_help_uri (CcPanel *panel)
|
||||
{
|
||||
return "help:gnome-help/clock";
|
||||
}
|
||||
|
||||
static void clock_settings_changed_cb (CcDateTimePanel *self,
|
||||
gchar *key);
|
||||
|
||||
static char *
|
||||
format_clock_name_cb (AdwEnumListItem *item,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
||||
switch (adw_enum_list_item_get_value (item))
|
||||
{
|
||||
case G_DESKTOP_CLOCK_FORMAT_24H:
|
||||
return g_strdup (_("24-hour"));
|
||||
case G_DESKTOP_CLOCK_FORMAT_12H:
|
||||
return g_strdup (_("AM / PM"));
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
change_clock_settings (CcDateTimePage *self)
|
||||
change_clock_settings (CcDateTimePanel *self)
|
||||
{
|
||||
GDesktopClockFormat value;
|
||||
AdwEnumListItem *item;
|
||||
|
||||
g_signal_handlers_block_by_func (self->clock_settings, clock_settings_changed_cb,
|
||||
self);
|
||||
|
||||
if (gtk_toggle_button_get_active (self->twentyfour_format_button))
|
||||
value = G_DESKTOP_CLOCK_FORMAT_24H;
|
||||
else
|
||||
value = G_DESKTOP_CLOCK_FORMAT_12H;
|
||||
item = ADW_ENUM_LIST_ITEM (adw_combo_row_get_selected_item (self->timeformat_row));
|
||||
value = adw_enum_list_item_get_value (item);
|
||||
|
||||
g_settings_set_enum (self->clock_settings, CLOCK_FORMAT_KEY, value);
|
||||
g_settings_set_enum (self->filechooser_settings, CLOCK_FORMAT_KEY, value);
|
||||
@@ -185,33 +215,29 @@ change_clock_settings (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
clock_settings_changed_cb (CcDateTimePage *self,
|
||||
gchar *key)
|
||||
clock_settings_changed_cb (CcDateTimePanel *self,
|
||||
gchar *key)
|
||||
{
|
||||
GDesktopClockFormat value;
|
||||
|
||||
value = g_settings_get_enum (self->clock_settings, CLOCK_FORMAT_KEY);
|
||||
self->clock_format = value;
|
||||
|
||||
g_signal_handlers_block_by_func (self->ampm_format_button, change_clock_settings, self);
|
||||
g_signal_handlers_block_by_func (self->twentyfour_format_button, change_clock_settings, self);
|
||||
g_signal_handlers_block_by_func (self->timeformat_row, change_clock_settings, self);
|
||||
|
||||
adw_combo_row_set_selected (self->timeformat_row, value);
|
||||
|
||||
gtk_toggle_button_set_active (self->twentyfour_format_button,
|
||||
value == G_DESKTOP_CLOCK_FORMAT_24H);
|
||||
gtk_toggle_button_set_active (self->ampm_format_button,
|
||||
value == G_DESKTOP_CLOCK_FORMAT_12H);
|
||||
cc_time_editor_set_am_pm (self->time_editor,
|
||||
value == G_DESKTOP_CLOCK_FORMAT_12H);
|
||||
update_time (self);
|
||||
|
||||
g_signal_handlers_unblock_by_func (self->twentyfour_format_button, change_clock_settings, self);
|
||||
g_signal_handlers_unblock_by_func (self->ampm_format_button, change_clock_settings, self);
|
||||
g_signal_handlers_unblock_by_func (self->timeformat_row, change_clock_settings, self);
|
||||
}
|
||||
|
||||
|
||||
/* Update the widgets based on the system time */
|
||||
static void
|
||||
update_time (CcDateTimePage *self)
|
||||
update_time (CcDateTimePanel *self)
|
||||
{
|
||||
g_autofree gchar *label = NULL;
|
||||
gboolean use_ampm;
|
||||
@@ -221,9 +247,11 @@ update_time (CcDateTimePage *self)
|
||||
else
|
||||
use_ampm = FALSE;
|
||||
|
||||
g_signal_handlers_block_by_func (self->time_editor, time_changed_cb, self);
|
||||
cc_time_editor_set_time (self->time_editor,
|
||||
g_date_time_get_hour (self->date),
|
||||
g_date_time_get_minute (self->date));
|
||||
g_signal_handlers_unblock_by_func (self->time_editor, time_changed_cb, self);
|
||||
|
||||
/* Update the time on the listbow row */
|
||||
if (use_ampm)
|
||||
@@ -238,7 +266,9 @@ update_time (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
self->month = g_date_time_get_month (self->date);
|
||||
g_signal_handlers_block_by_func (self->month_model, on_month_selection_changed_cb, self);
|
||||
gtk_single_selection_set_selected (self->month_model, self->month - 1);
|
||||
g_signal_handlers_unblock_by_func (self->month_model, on_month_selection_changed_cb, self);
|
||||
gtk_label_set_text (self->datetime_label, label);
|
||||
}
|
||||
|
||||
@@ -247,7 +277,7 @@ set_time_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcDateTimePage *self = user_data;
|
||||
CcDateTimePanel *self = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (!timedate1_call_set_time_finish (self->dtm,
|
||||
@@ -268,7 +298,7 @@ set_timezone_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcDateTimePage *self = user_data;
|
||||
CcDateTimePanel *self = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (!timedate1_call_set_timezone_finish (self->dtm,
|
||||
@@ -285,7 +315,7 @@ set_using_ntp_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcDateTimePage *self = user_data;
|
||||
CcDateTimePanel *self = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (!timedate1_call_set_ntp_finish (self->dtm,
|
||||
@@ -302,7 +332,7 @@ set_using_ntp_cb (GObject *source,
|
||||
}
|
||||
|
||||
static void
|
||||
queue_set_datetime (CcDateTimePage *self)
|
||||
queue_set_datetime (CcDateTimePanel *self)
|
||||
{
|
||||
gint64 unixtime;
|
||||
|
||||
@@ -319,8 +349,8 @@ queue_set_datetime (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
queue_set_ntp (CcDateTimePage *self,
|
||||
gboolean using_ntp)
|
||||
queue_set_ntp (CcDateTimePanel *self,
|
||||
gboolean using_ntp)
|
||||
{
|
||||
self->pending_ntp_state = using_ntp;
|
||||
timedate1_call_set_ntp (self->dtm,
|
||||
@@ -332,7 +362,7 @@ queue_set_ntp (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
queue_set_timezone (CcDateTimePage *self)
|
||||
queue_set_timezone (CcDateTimePanel *self)
|
||||
{
|
||||
/* for now just do it */
|
||||
if (self->current_location)
|
||||
@@ -347,22 +377,24 @@ queue_set_timezone (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
change_date (CcDateTimePage *self)
|
||||
change_date (CcDateTimePanel *self)
|
||||
{
|
||||
guint y, d;
|
||||
g_autoptr(GDateTime) old_date = NULL;
|
||||
|
||||
y = (guint)adw_spin_row_get_value (self->year_spin_row);
|
||||
d = (guint)adw_spin_row_get_value (self->day_spin_row);
|
||||
y = gtk_spin_button_get_value_as_int (self->year_spinbutton);
|
||||
d = gtk_spin_button_get_value_as_int (self->day_spinbutton);
|
||||
|
||||
old_date = self->date;
|
||||
self->date = g_date_time_new_local (y, self->month, d,
|
||||
g_date_time_get_hour (old_date),
|
||||
g_date_time_get_minute (old_date),
|
||||
g_date_time_get_second (old_date));
|
||||
g_signal_handlers_block_by_func (self->time_editor, time_changed_cb, self);
|
||||
cc_time_editor_set_time (self->time_editor,
|
||||
g_date_time_get_hour (self->date),
|
||||
g_date_time_get_minute (self->date));
|
||||
g_signal_handlers_unblock_by_func (self->time_editor, time_changed_cb, self);
|
||||
|
||||
queue_set_datetime (self);
|
||||
}
|
||||
@@ -395,7 +427,7 @@ translated_city_name (TzLocation *loc)
|
||||
}
|
||||
|
||||
static void
|
||||
update_timezone (CcDateTimePage *self)
|
||||
update_timezone (CcDateTimePanel *self)
|
||||
{
|
||||
g_autofree gchar *city_country = NULL;
|
||||
g_autofree gchar *label = NULL;
|
||||
@@ -411,7 +443,7 @@ update_timezone (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
get_initial_timezone (CcDateTimePage *self)
|
||||
get_initial_timezone (CcDateTimePanel *self)
|
||||
{
|
||||
const gchar *timezone;
|
||||
|
||||
@@ -429,48 +461,48 @@ get_initial_timezone (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
day_changed (CcDateTimePage *self)
|
||||
day_changed (CcDateTimePanel *self)
|
||||
{
|
||||
change_date (self);
|
||||
}
|
||||
|
||||
static void
|
||||
month_year_changed (CcDateTimePage *self)
|
||||
month_year_changed (CcDateTimePanel *self)
|
||||
{
|
||||
guint y;
|
||||
guint num_days;
|
||||
GtkAdjustment *adj;
|
||||
|
||||
y = (guint)adw_spin_row_get_value (self->year_spin_row);
|
||||
y = gtk_spin_button_get_value_as_int (self->year_spinbutton);
|
||||
|
||||
/* Check the number of days in that month */
|
||||
num_days = g_date_get_days_in_month (self->month, y);
|
||||
|
||||
adj = GTK_ADJUSTMENT (adw_spin_row_get_adjustment (self->day_spin_row));
|
||||
adj = GTK_ADJUSTMENT (gtk_spin_button_get_adjustment (self->day_spinbutton));
|
||||
gtk_adjustment_set_upper (adj, num_days + 1);
|
||||
|
||||
if ((guint)adw_spin_row_get_value (self->day_spin_row) > num_days)
|
||||
adw_spin_row_set_value (self->day_spin_row, num_days);
|
||||
if (gtk_spin_button_get_value_as_int (self->day_spinbutton) > num_days)
|
||||
gtk_spin_button_set_value (self->day_spinbutton, num_days);
|
||||
|
||||
change_date (self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_date_box_row_activated_cb (CcDateTimePage *self,
|
||||
GtkListBoxRow *row)
|
||||
on_date_box_row_activated_cb (CcDateTimePanel *self,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
g_assert (CC_IS_DATE_TIME_PAGE (self));
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
|
||||
if (row == GTK_LIST_BOX_ROW (self->month_row))
|
||||
gtk_popover_popup (self->month_popover);
|
||||
}
|
||||
|
||||
static void
|
||||
on_month_selection_changed_cb (CcDateTimePage *self)
|
||||
on_month_selection_changed_cb (CcDateTimePanel *self)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_assert (CC_IS_DATE_TIME_PAGE (self));
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
|
||||
i = gtk_single_selection_get_selected (self->month_model);
|
||||
g_assert (i >= 0 && i < 12);
|
||||
@@ -482,8 +514,8 @@ on_month_selection_changed_cb (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
on_clock_changed (CcDateTimePage *self,
|
||||
GParamSpec *pspec)
|
||||
on_clock_changed (CcDateTimePanel *self,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
g_date_time_unref (self->date);
|
||||
self->date = g_date_time_new_now_local ();
|
||||
@@ -492,8 +524,8 @@ on_clock_changed (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
change_ntp (CcDateTimePage *self,
|
||||
gboolean state)
|
||||
change_ntp (CcDateTimePanel *self,
|
||||
gboolean state)
|
||||
{
|
||||
queue_set_ntp (self, state);
|
||||
|
||||
@@ -502,7 +534,7 @@ change_ntp (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_ntp_available (CcDateTimePage *self)
|
||||
is_ntp_available (CcDateTimePanel *self)
|
||||
{
|
||||
g_autoptr(GVariant) value = NULL;
|
||||
gboolean ntp_available = TRUE;
|
||||
@@ -521,7 +553,7 @@ is_ntp_available (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
on_permission_changed (CcDateTimePage *self)
|
||||
on_permission_changed (CcDateTimePanel *self)
|
||||
{
|
||||
gboolean allowed, location_allowed, tz_allowed, auto_timezone, using_ntp;
|
||||
|
||||
@@ -529,7 +561,7 @@ on_permission_changed (CcDateTimePage *self)
|
||||
location_allowed = g_settings_get_boolean (self->location_settings, LOCATION_ENABLED);
|
||||
tz_allowed = (self->tz_permission != NULL && g_permission_get_allowed (self->tz_permission));
|
||||
using_ntp = gtk_switch_get_active (self->network_time_switch);
|
||||
auto_timezone = adw_switch_row_get_active (self->auto_timezone_row);
|
||||
auto_timezone = gtk_switch_get_active (self->auto_timezone_switch);
|
||||
|
||||
/* All the widgets but the lock button and the 24h setting */
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_datetime_row), allowed);
|
||||
@@ -545,26 +577,26 @@ on_permission_changed (CcDateTimePage *self)
|
||||
}
|
||||
|
||||
static void
|
||||
on_location_settings_changed (CcDateTimePage *self)
|
||||
on_location_settings_changed (CcDateTimePanel *self)
|
||||
{
|
||||
on_permission_changed (self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_can_ntp_changed (CcDateTimePage *self)
|
||||
on_can_ntp_changed (CcDateTimePanel *self)
|
||||
{
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->auto_datetime_row), is_ntp_available (self));
|
||||
}
|
||||
|
||||
static void
|
||||
on_timezone_changed (CcDateTimePage *self)
|
||||
on_timezone_changed (CcDateTimePanel *self)
|
||||
{
|
||||
get_initial_timezone (self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_timedated_properties_changed (CcDateTimePage *self,
|
||||
GVariant *changed_properties,
|
||||
on_timedated_properties_changed (CcDateTimePanel *self,
|
||||
GVariant *changed_properties,
|
||||
const gchar **invalidated_properties)
|
||||
{
|
||||
guint i;
|
||||
@@ -594,22 +626,22 @@ on_timedated_properties_changed (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
present_window (CcDateTimePage *self,
|
||||
GtkWindow *window)
|
||||
present_window (CcDateTimePanel *self,
|
||||
GtkWindow *window)
|
||||
{
|
||||
GtkNative *native;
|
||||
GtkWidget *parent;
|
||||
|
||||
native = gtk_widget_get_native (GTK_WIDGET (self));
|
||||
parent = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)));
|
||||
|
||||
gtk_window_set_transient_for (window, GTK_WINDOW (native));
|
||||
gtk_window_set_transient_for (window, GTK_WINDOW (parent));
|
||||
gtk_window_present (window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tz_switch_to_row_transform_func (GBinding *binding,
|
||||
const GValue *source_value,
|
||||
GValue *target_value,
|
||||
CcDateTimePage *self)
|
||||
tz_switch_to_row_transform_func (GBinding *binding,
|
||||
const GValue *source_value,
|
||||
GValue *target_value,
|
||||
CcDateTimePanel *self)
|
||||
{
|
||||
gboolean active;
|
||||
gboolean allowed;
|
||||
@@ -626,10 +658,10 @@ tz_switch_to_row_transform_func (GBinding *binding,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
switch_to_row_transform_func (GBinding *binding,
|
||||
const GValue *source_value,
|
||||
GValue *target_value,
|
||||
CcDateTimePage *self)
|
||||
switch_to_row_transform_func (GBinding *binding,
|
||||
const GValue *source_value,
|
||||
GValue *target_value,
|
||||
CcDateTimePanel *self)
|
||||
{
|
||||
gboolean active;
|
||||
gboolean allowed;
|
||||
@@ -643,9 +675,9 @@ switch_to_row_transform_func (GBinding *binding,
|
||||
}
|
||||
|
||||
static void
|
||||
bind_switch_to_row (CcDateTimePage *self,
|
||||
GtkSwitch *gtkswitch,
|
||||
GtkWidget *listrow)
|
||||
bind_switch_to_row (CcDateTimePanel *self,
|
||||
GtkSwitch *gtkswitch,
|
||||
GtkWidget *listrow)
|
||||
{
|
||||
g_object_bind_property_full (gtkswitch, "active",
|
||||
listrow, "sensitive",
|
||||
@@ -655,17 +687,17 @@ bind_switch_to_row (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
panel_tz_selection_changed_cb (CcDateTimePage *self)
|
||||
panel_tz_selection_changed_cb (CcDateTimePanel *self)
|
||||
{
|
||||
g_assert (CC_IS_DATE_TIME_PAGE (self));
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
|
||||
self->current_location = cc_tz_dialog_get_selected_location (self->timezone_dialog);
|
||||
queue_set_timezone (self);
|
||||
}
|
||||
|
||||
static void
|
||||
list_box_row_activated (CcDateTimePage *self,
|
||||
GtkListBoxRow *row)
|
||||
list_box_row_activated (CcDateTimePanel *self,
|
||||
GtkListBoxRow *row)
|
||||
|
||||
{
|
||||
if (row == GTK_LIST_BOX_ROW (self->datetime_row))
|
||||
@@ -679,12 +711,12 @@ list_box_row_activated (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
time_changed_cb (CcDateTimePage *self,
|
||||
CcTimeEditor *editor)
|
||||
time_changed_cb (CcDateTimePanel *self,
|
||||
CcTimeEditor *editor)
|
||||
{
|
||||
g_autoptr(GDateTime) old_date = NULL;
|
||||
|
||||
g_assert (CC_IS_DATE_TIME_PAGE (self));
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
g_assert (CC_IS_TIME_EDITOR (editor));
|
||||
|
||||
old_date = self->date;
|
||||
@@ -700,7 +732,7 @@ time_changed_cb (CcDateTimePage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
setup_datetime_dialog (CcDateTimePage *self)
|
||||
setup_datetime_dialog (CcDateTimePanel *self)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
GdkDisplay *display;
|
||||
@@ -730,35 +762,37 @@ setup_datetime_dialog (CcDateTimePage *self)
|
||||
g_date_time_get_year (self->date));
|
||||
adjustment = (GtkAdjustment*) gtk_adjustment_new (g_date_time_get_day_of_month (self->date), 1,
|
||||
num_days + 1, 1, 10, 1);
|
||||
adw_spin_row_set_adjustment (self->day_spin_row, adjustment);
|
||||
g_signal_connect_object (G_OBJECT (self->day_spin_row), "changed",
|
||||
gtk_spin_button_set_adjustment (self->day_spinbutton, adjustment);
|
||||
g_signal_connect_object (G_OBJECT (self->day_spinbutton), "value-changed",
|
||||
G_CALLBACK (day_changed), self, G_CONNECT_SWAPPED);
|
||||
|
||||
/* Year */
|
||||
adjustment = (GtkAdjustment*) gtk_adjustment_new (g_date_time_get_year (self->date),
|
||||
1, G_MAXDOUBLE, 1,
|
||||
10, 1);
|
||||
adw_spin_row_set_adjustment (self->year_spin_row, adjustment);
|
||||
g_signal_connect_object (G_OBJECT (self->year_spin_row), "changed",
|
||||
gtk_spin_button_set_adjustment (self->year_spinbutton, adjustment);
|
||||
g_signal_connect_object (G_OBJECT (self->year_spinbutton), "value-changed",
|
||||
G_CALLBACK (month_year_changed), self, G_CONNECT_SWAPPED);
|
||||
|
||||
/* Month */
|
||||
self->month = g_date_time_get_month (self->date);
|
||||
g_signal_handlers_block_by_func (self->month_model, on_month_selection_changed_cb, self);
|
||||
gtk_single_selection_set_selected (self->month_model, self->month - 1);
|
||||
g_signal_handlers_unblock_by_func (self->month_model, on_month_selection_changed_cb, self);
|
||||
}
|
||||
|
||||
static int
|
||||
sort_date_box (GtkListBoxRow *a,
|
||||
GtkListBoxRow *b,
|
||||
CcDateTimePage *self)
|
||||
sort_date_box (GtkListBoxRow *a,
|
||||
GtkListBoxRow *b,
|
||||
CcDateTimePanel *self)
|
||||
{
|
||||
GtkListBoxRow *day_row, *month_row, *year_row;
|
||||
|
||||
g_assert (CC_IS_DATE_TIME_PAGE (self));
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
|
||||
day_row = GTK_LIST_BOX_ROW (self->day_spin_row);
|
||||
day_row = GTK_LIST_BOX_ROW (self->day_row);
|
||||
month_row = GTK_LIST_BOX_ROW (self->month_row);
|
||||
year_row = GTK_LIST_BOX_ROW (self->year_spin_row);
|
||||
year_row = GTK_LIST_BOX_ROW (self->year_row);
|
||||
|
||||
switch (date_endian_get_default (FALSE)) {
|
||||
case DATE_ENDIANESS_BIG:
|
||||
@@ -794,60 +828,68 @@ sort_date_box (GtkListBoxRow *a,
|
||||
}
|
||||
|
||||
static void
|
||||
cc_date_time_page_class_init (CcDateTimePageClass *klass)
|
||||
cc_date_time_panel_class_init (CcDateTimePanelClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
|
||||
object_class->dispose = cc_date_time_page_dispose;
|
||||
object_class->dispose = cc_date_time_panel_dispose;
|
||||
|
||||
panel_class->get_help_uri = cc_date_time_panel_get_help_uri;
|
||||
|
||||
g_type_ensure (CC_TYPE_LIST_ROW);
|
||||
g_type_ensure (CC_TYPE_TIME_EDITOR);
|
||||
g_type_ensure (CC_TYPE_TZ_DIALOG);
|
||||
g_type_ensure (G_DESKTOP_TYPE_DESKTOP_CLOCK_FORMAT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/system/datetime/cc-datetime-page.ui");
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/datetime/cc-datetime-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, auto_datetime_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, auto_timezone_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, auto_timezone_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, date_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, datetime_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, datetime_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, datetime_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, day_spin_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, twentyfour_format_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, ampm_format_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, weekday_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, date_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, seconds_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, week_numbers_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, lock_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, month_model);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, month_popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, month_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, network_time_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, time_editor);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, timezone_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, timezone_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, timezone_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePage, year_spin_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_datetime_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_timezone_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_timezone_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, date_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, day_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, day_spinbutton);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timeformat_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, weekday_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, date_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, seconds_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, week_numbers_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, lock_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_model);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, network_time_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, time_editor);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, year_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, year_spinbutton);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, panel_tz_selection_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_box_row_activated);
|
||||
gtk_widget_class_bind_template_callback (widget_class, time_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, change_clock_settings);
|
||||
gtk_widget_class_bind_template_callback (widget_class, format_clock_name_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_date_box_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_month_selection_changed_cb);
|
||||
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE_TIMEZONES, "UTF-8");
|
||||
|
||||
g_type_ensure (CC_TYPE_TIME_EDITOR);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_date_time_page_init (CcDateTimePage *self)
|
||||
cc_date_time_panel_init (CcDateTimePanel *self)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_resources_register (cc_datetime_get_resource ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
@@ -911,7 +953,7 @@ cc_date_time_page_init (CcDateTimePage *self)
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->auto_datetime_row), is_ntp_available (self));
|
||||
|
||||
/* Timezone settings */
|
||||
g_object_bind_property_full (self->auto_timezone_row, "active",
|
||||
g_object_bind_property_full (self->auto_timezone_switch, "active",
|
||||
self->timezone_row, "sensitive",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
(GBindingTransformFunc) tz_switch_to_row_transform_func,
|
||||
@@ -919,7 +961,7 @@ cc_date_time_page_init (CcDateTimePage *self)
|
||||
|
||||
self->datetime_settings = g_settings_new (DATETIME_SCHEMA);
|
||||
g_settings_bind (self->datetime_settings, AUTO_TIMEZONE_KEY,
|
||||
self->auto_timezone_row, "active",
|
||||
self->auto_timezone_switch, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
/* Clock settings */
|
||||
@@ -935,22 +977,22 @@ cc_date_time_page_init (CcDateTimePage *self)
|
||||
|
||||
/* setup top bar clock setting switches */
|
||||
g_settings_bind (self->clock_settings, CLOCK_SHOW_WEEKDAY_KEY,
|
||||
self->weekday_row, "active",
|
||||
self->weekday_switch, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
g_settings_bind (self->clock_settings, CLOCK_SHOW_DATE_KEY,
|
||||
self->date_row, "active",
|
||||
self->date_switch, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
g_settings_bind (self->clock_settings, CLOCK_SHOW_SECONDS_KEY,
|
||||
self->seconds_row, "active",
|
||||
self->seconds_switch, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
/* Calendar settings */
|
||||
self->calendar_settings = g_settings_new (CALENDAR_SCHEMA);
|
||||
|
||||
g_settings_bind (self->calendar_settings, CALENDAR_SHOW_WEEK_NUMBERS_KEY,
|
||||
self->week_numbers_row, "active",
|
||||
self->week_numbers_switch, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
update_time (self);
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* cc-region-page.h
|
||||
*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -16,19 +14,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Sergey Udaltsov <svu@gnome.org>
|
||||
* Gotam Gorabh <gautamy672@gmail.com>
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <shell/cc-panel.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_REGION_PAGE (cc_region_page_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CcRegionPage, cc_region_page, CC, REGION_PAGE, AdwNavigationPage)
|
||||
#define CC_TYPE_DATE_TIME_PANEL (cc_date_time_panel_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcDateTimePanel, cc_date_time_panel, CC, DATE_TIME_PANEL, CcPanel)
|
||||
|
||||
G_END_DECLS
|
||||
@@ -56,19 +56,24 @@
|
||||
|
||||
<!-- Year row -->
|
||||
<child>
|
||||
<object class="AdwSpinRow" id="year_spin_row">
|
||||
<property name="title" translatable="yes">_Year</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="width-chars">4</property>
|
||||
<property name="numeric">True</property>
|
||||
<object class="AdwActionRow" id="year_row">
|
||||
<property name="title" translatable="yes">Year</property>
|
||||
<property name="activatable-widget">year_spinbutton</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="year_spinbutton">
|
||||
<property name="valign">center</property>
|
||||
<property name="width-chars">4</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Month row -->
|
||||
<child>
|
||||
<object class="CcListRow" id="month_row">
|
||||
<property name="title" translatable="yes">_Month</property>
|
||||
<property name="title" translatable="yes">Month</property>
|
||||
<binding name="secondary-label">
|
||||
<lookup name="string" type="GtkStringObject">
|
||||
<lookup name="selected-item">month_model</lookup>
|
||||
@@ -94,12 +99,16 @@
|
||||
|
||||
<!-- Day row -->
|
||||
<child>
|
||||
<object class="AdwSpinRow" id="day_spin_row">
|
||||
<property name="title" translatable="yes">_Day</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="width-chars">3</property>
|
||||
<property name="numeric">True</property>
|
||||
<object class="AdwActionRow" id="day_row">
|
||||
<property name="title" translatable="yes">Day</property>
|
||||
<property name="activatable-widget">day_spinbutton</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="day_spinbutton">
|
||||
<property name="valign">center</property>
|
||||
<property name="width-chars">3</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -113,9 +122,7 @@
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
<template class="CcDateTimePage" parent="AdwNavigationPage">
|
||||
<property name="title" translatable="yes">Date & Time</property>
|
||||
<property name="tag">system-date-time-page</property>
|
||||
<template class="CcDateTimePanel" parent="CcPanel">
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
@@ -170,10 +177,16 @@
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="auto_timezone_row">
|
||||
<object class="AdwActionRow" id="auto_timezone_row">
|
||||
<property name="title" translatable="yes">Automatic Time _Zone</property>
|
||||
<property name="subtitle" translatable="yes">Requires location services enabled and internet access</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">auto_timezone_switch</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="auto_timezone_switch">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -202,33 +215,18 @@
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<object class="AdwComboRow" id="timeformat_row">
|
||||
<property name="title" translatable="yes">Time _Format</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="suffix">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="twentyfour_format_button">
|
||||
<property name="label" translatable="yes">_24-hour</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="group">ampm_format_button</property>
|
||||
<signal name="toggled" handler="change_clock_settings" object="CcDateTimePage" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="ampm_format_button">
|
||||
<property name="label" translatable="yes">AM / _PM</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="toggled" handler="change_clock_settings" object="CcDateTimePage" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<signal name="notify::selected-item" handler="change_clock_settings" object="CcDateTimePanel" swapped="yes"/>
|
||||
<property name="model">
|
||||
<object class="AdwEnumListModel">
|
||||
<property name="enum-type">GDesktopClockFormat</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
<property name="expression">
|
||||
<closure type="gchararray" function="format_clock_name_cb"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -238,28 +236,51 @@
|
||||
<property name="title" translatable="yes">Clock &amp; Calendar</property>
|
||||
<property name="description" translatable="yes">Control how the time and date is shown in the top bar</property>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="weekday_row">
|
||||
<property name="title" translatable="yes">_Week Day</property>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Week Day</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">weekday_switch</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="weekday_switch">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="date_row">
|
||||
<property name="title" translatable="yes">D_ate</property>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Date</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">date_switch</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="date_switch">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="seconds_row">
|
||||
<property name="title" translatable="yes">_Seconds</property>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Seconds</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">seconds_switch</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="seconds_switch">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="week_numbers_row">
|
||||
<property name="title" translatable="yes">Week _Numbers</property>
|
||||
<property name="subtitle" translatable="yes">Shown in the dropdown calendar</property>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Week Numbers</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="activatable_widget">week_numbers_switch</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="week_numbers_switch">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -285,7 +306,7 @@
|
||||
</style>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/org/gnome/control-center/system/datetime/cc-month-row.ui</property>
|
||||
<property name="resource">/org/gnome/control-center/datetime/cc-month-row.ui</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="model">
|
||||
@@ -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