Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3a3c544b3 | ||
|
|
afb6b2a713 | ||
|
|
a28ac69531 | ||
|
|
eaa4dd4aa3 | ||
|
|
d0c76cff43 | ||
|
|
055ab69378 | ||
|
|
196477e60c | ||
|
|
9a67cd0884 | ||
|
|
4d64299561 | ||
|
|
49deb7796f | ||
|
|
3489e88acd | ||
|
|
1d4d5527b3 | ||
|
|
7461501c5b | ||
|
|
077a7c4a64 | ||
|
|
040c895208 | ||
|
|
09356dbdc7 | ||
|
|
91130064e9 | ||
|
|
3c97de2121 | ||
|
|
fb81c922c8 | ||
|
|
2e363141eb | ||
|
|
86c60f47b0 | ||
|
|
e6c0c0e1c1 | ||
|
|
738dbfb6ea | ||
|
|
809fac82df | ||
|
|
5fac79b089 | ||
|
|
725a921028 | ||
|
|
8e78f8438a | ||
|
|
419d2f99d4 | ||
|
|
5c1dedbebd | ||
|
|
901bb6b366 |
300
.gitlab-ci.yml
300
.gitlab-ci.yml
@@ -1,14 +1,9 @@
|
||||
include:
|
||||
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/5888c7388134cbe4661600222fe9befb10441f6e/templates/fedora.yml'
|
||||
|
||||
variables:
|
||||
FDO_UPSTREAM_REPO: gnome/gnome-control-center
|
||||
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-control-center:fedora.dev
|
||||
stages:
|
||||
- prepare
|
||||
- build
|
||||
- test
|
||||
- manual
|
||||
- review
|
||||
- deploy
|
||||
|
||||
.Log files: &log_files [./*.log, _build/meson-logs/]
|
||||
@@ -32,97 +27,13 @@ stages:
|
||||
.Build procedure: &build_procedure
|
||||
echo "== Building ==" &&
|
||||
rm -rf _build/ &&
|
||||
meson . _build ${BUILD_OPTS} -Dprofile=development &&
|
||||
meson . _build ${BUILD_OPTS} &&
|
||||
ninja -C _build 2>&1 | tee compilation.log
|
||||
|
||||
.Run Tests: &run_tests
|
||||
echo "== Testing ==" &&
|
||||
meson test -C _build --verbose --no-stdsplit
|
||||
|
||||
.fedora.container.common:
|
||||
variables:
|
||||
# When branching a stable release, change 'main'
|
||||
# to the release number/branch to ensure that
|
||||
# a new image will be created, tailored for the
|
||||
# stable branch.
|
||||
# Could probably also switch away from rawhide,
|
||||
# to stable fedora branch as well.
|
||||
FDO_DISTRIBUTION_TAG: '2021-07-22.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: rawhide
|
||||
|
||||
#############################################
|
||||
# Create CI Docker Images #
|
||||
#############################################
|
||||
|
||||
# See also https://gitlab.freedesktop.org/freedesktop/ci-templates
|
||||
build.container.fedora@x86_64:
|
||||
extends:
|
||||
- '.fdo.container-build@fedora'
|
||||
- '.fedora.container.common'
|
||||
stage: 'prepare'
|
||||
variables:
|
||||
# no need to pull the whole tree for rebuilding the image
|
||||
GIT_STRATEGY: none
|
||||
# Expiry sets fdo.expires on the image
|
||||
FDO_EXPIRES_AFTER: 8w
|
||||
# NOTES:
|
||||
# - gobject-introspection-devel is needed for gsettings-desktop-schemas
|
||||
FDO_DISTRIBUTION_PACKAGES: >-
|
||||
@c-development @development-tools
|
||||
git
|
||||
llvm clang libasan libtsan libubsan gcovr
|
||||
meson
|
||||
accountsservice-devel
|
||||
cheese-libs-devel
|
||||
chrpath
|
||||
colord-devel colord-gtk-devel
|
||||
cups-devel
|
||||
desktop-file-utils
|
||||
docbook-style-xsl
|
||||
flatpak-devel
|
||||
gdk-pixbuf2-devel
|
||||
gettext
|
||||
glib2-devel
|
||||
gobject-introspection-devel
|
||||
gnome-bluetooth-libs-devel
|
||||
gnome-desktop3-devel
|
||||
gnome-online-accounts-devel
|
||||
gnome-settings-daemon-devel
|
||||
grilo-devel
|
||||
gsettings-desktop-schemas-devel
|
||||
gsound-devel
|
||||
gtk3-devel ibus-devel
|
||||
intltool
|
||||
libcanberra-devel
|
||||
libgtop2-devel
|
||||
libgudev-devel
|
||||
libnma-devel
|
||||
libpwquality-devel
|
||||
libsmbclient-devel
|
||||
libsoup-devel
|
||||
libudisks2-devel
|
||||
libwacom-devel
|
||||
libX11-devel
|
||||
libXi-devel
|
||||
libxml2-devel
|
||||
libxslt
|
||||
ModemManager-glib-devel
|
||||
NetworkManager-libnm-devel
|
||||
polkit-devel
|
||||
pulseaudio-libs-devel
|
||||
upower-devel
|
||||
python3-dbusmock
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
libsecret-devel
|
||||
FDO_DISTRIBUTION_EXEC: |-
|
||||
git clone https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git && \
|
||||
cd gsettings-desktop-schemas && \
|
||||
meson . _build --prefix=/usr && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd ..
|
||||
|
||||
##
|
||||
# Stage: Build
|
||||
#
|
||||
@@ -131,15 +42,10 @@ build.container.fedora@x86_64:
|
||||
# any of them.
|
||||
##
|
||||
build:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
|
||||
<<: *save_untracked_files
|
||||
stage: build
|
||||
|
||||
script:
|
||||
- dnf -y install gcr-devel
|
||||
- *environment_information
|
||||
- *build_procedure
|
||||
|
||||
@@ -162,9 +68,6 @@ build:
|
||||
# Runs the unit tests.
|
||||
##
|
||||
test:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *save_build_logs
|
||||
stage: test
|
||||
|
||||
@@ -172,7 +75,6 @@ test:
|
||||
- build
|
||||
|
||||
script:
|
||||
- dnf -y install gcr-devel
|
||||
- *environment_information
|
||||
- *run_tests
|
||||
|
||||
@@ -189,9 +91,6 @@ test:
|
||||
|
||||
# Runs the coverage test.
|
||||
coverage:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *save_build_logs
|
||||
stage: test
|
||||
variables:
|
||||
@@ -201,7 +100,6 @@ coverage:
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
script:
|
||||
- dnf -y install gcr-devel
|
||||
- *environment_information
|
||||
- *build_procedure
|
||||
- *run_tests
|
||||
@@ -227,9 +125,6 @@ coverage:
|
||||
# Publishes the Coverage Report generated above
|
||||
##
|
||||
pages:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- coverage
|
||||
@@ -307,17 +202,61 @@ flatpak:
|
||||
- gnome-3-.*
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
##
|
||||
# Review
|
||||
#
|
||||
# Stage: review
|
||||
#
|
||||
# Starts the Flatpak review process.
|
||||
##
|
||||
review:
|
||||
stage: review
|
||||
dependencies:
|
||||
- flatpak
|
||||
|
||||
when: manual
|
||||
variables:
|
||||
BUNDLE: "org.gnome.SettingsDevel.flatpak"
|
||||
script:
|
||||
- echo "Generating flatpak deployment"
|
||||
artifacts:
|
||||
paths:
|
||||
- ${BUNDLE}
|
||||
expire_in: 30 days
|
||||
environment:
|
||||
name: review/$CI_COMMIT_REF_NAME
|
||||
url: https://gitlab.gnome.org/$CI_PROJECT_PATH/-/jobs/$CI_JOB_ID/artifacts/raw/${BUNDLE}
|
||||
on_stop: stop_review
|
||||
except:
|
||||
- tags
|
||||
- gnome-3-.*
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
##
|
||||
# Stop Review
|
||||
#
|
||||
# Stage: review
|
||||
#
|
||||
# Stops the Flatpak review process.
|
||||
##
|
||||
stop_review:
|
||||
stage: review
|
||||
script:
|
||||
- echo "Stopping flatpak deployment"
|
||||
when: manual
|
||||
environment:
|
||||
name: review/$CI_COMMIT_REF_NAME
|
||||
action: stop
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
|
||||
# Runs the sanitizers [address, thread, undefined, and memory].
|
||||
.sanitizer: &sanitizer
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *save_build_logs
|
||||
stage: manual
|
||||
when: manual
|
||||
script:
|
||||
- dnf -y install gcr-devel
|
||||
- *environment_information
|
||||
- *build_procedure
|
||||
- *run_tests
|
||||
@@ -328,39 +267,144 @@ flatpak:
|
||||
- $CI_COMMIT_TITLE =~ /^Update.*translation$/
|
||||
|
||||
asan:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *sanitizer
|
||||
# ASAN requires debugging capabilities
|
||||
tags: [ asan ]
|
||||
stage: manual
|
||||
when: manual
|
||||
stage: test
|
||||
when: on_success
|
||||
variables:
|
||||
BUILD_OPTS: "-Db_sanitize=address"
|
||||
LSAN_OPTIONS: "suppressions=${CI_PROJECT_DIR}/build-aux/ci/lsan.supp"
|
||||
|
||||
tsan:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *sanitizer
|
||||
variables:
|
||||
BUILD_OPTS: "-Db_sanitize=thread"
|
||||
|
||||
ubsan:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *sanitizer
|
||||
variables:
|
||||
BUILD_OPTS: "-Db_sanitize=undefined"
|
||||
|
||||
msan:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *sanitizer
|
||||
variables:
|
||||
BUILD_OPTS: "-Db_sanitize=memory"
|
||||
CC: "clang"
|
||||
|
||||
# Runs multiarch build test.
|
||||
.qemu: &multiarch
|
||||
<<: *save_build_logs
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
script:
|
||||
# Register QEMU archs
|
||||
- docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
|
||||
# Run the multiarch test job using QEMU
|
||||
- 'docker run -v $(pwd):/cwd $IMAGE bash -e -c "cd /cwd &&
|
||||
echo == Building == &&
|
||||
rm -rf _build/ &&
|
||||
meson . _build ${BUILD_OPTS} &&
|
||||
ninja -C _build 2>&1 | tee compilation.log &&
|
||||
|
||||
echo == Testing == &&
|
||||
ninja -C _build test"
|
||||
'
|
||||
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
- $CI_COMMIT_TITLE =~ /^Update.*translation$/
|
||||
|
||||
armv8:
|
||||
<<: *multiarch
|
||||
stage: manual
|
||||
when: manual
|
||||
variables:
|
||||
DOCKER_DRIVER: overlay
|
||||
IMAGE: "registry.gitlab.gnome.org/gnome/gnome-control-center:fedora.aarch64"
|
||||
|
||||
ppc64le:
|
||||
<<: *multiarch
|
||||
stage: manual
|
||||
when: manual
|
||||
allow_failure: true
|
||||
variables:
|
||||
DOCKER_DRIVER: overlay
|
||||
IMAGE: "registry.gitlab.gnome.org/gnome/gnome-control-center:fedora.ppc64le"
|
||||
|
||||
#############################################
|
||||
# Create CI Docker Images #
|
||||
#############################################
|
||||
.Docker image template: &create_docker_image
|
||||
image: docker:latest
|
||||
stage: deploy
|
||||
services:
|
||||
- docker:dind
|
||||
only:
|
||||
variables:
|
||||
- $CRON_TASK == "BUILD_CI_IMAGES"
|
||||
changes:
|
||||
- build-aux/ci/Dockerfile.*
|
||||
|
||||
|
||||
script:
|
||||
# Skip the build (if requested)
|
||||
- |
|
||||
if [[ -z "${CI_COMMIT_MESSAGE##*'[skip images]'*}" ]]; then
|
||||
echo "== Nothing to do =="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- |
|
||||
if [[ "${CI_COMMIT_REF_NAME}" != "master" ]]; then
|
||||
echo "== Exiting, will only build CI images when pushing to master. =="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Only when we have somewhere to publish to
|
||||
- |
|
||||
if [[ -z "${CI_REGISTRY}${CI_REGISTRY_IMAGE}${CI_REGISTRY_USER}${CI_REGISTRY_PASSWORD}" ]]; then
|
||||
echo "== Exiting, CI registry not configured. =="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get multiarch stuff
|
||||
- |
|
||||
if [[ -n "${TARGET_ARCH}" ]]; then
|
||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
wget https://github.com/multiarch/qemu-user-static/releases/download/v2.12.0/x86_64_qemu-${TARGET_ARCH}-static.tar.gz
|
||||
fi
|
||||
|
||||
# Build using the Dockerfile
|
||||
- docker build -f "$DOCKERFILE" -t "$CI_REGISTRY_IMAGE:$NAME" .
|
||||
|
||||
# Publish
|
||||
- docker tag "$CI_REGISTRY_IMAGE:$NAME" "$CI_REGISTRY_IMAGE:job-"$CI_JOB_ID"_$NAME"
|
||||
- docker images
|
||||
- docker login ${CI_REGISTRY} -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD}
|
||||
- docker push "$CI_REGISTRY_IMAGE"
|
||||
|
||||
fedora.dev:
|
||||
<<: *create_docker_image
|
||||
variables:
|
||||
DOCKER_DRIVER: overlay
|
||||
DOCKERFILE: "build-aux/ci/Dockerfile.fedora.30"
|
||||
NAME: "fedora.dev"
|
||||
|
||||
fedora.aarch64:
|
||||
<<: *create_docker_image
|
||||
variables:
|
||||
DOCKER_DRIVER: overlay
|
||||
DOCKERFILE: "build-aux/ci/Dockerfile.arm64v8.fedora.30"
|
||||
NAME: "fedora.aarch64"
|
||||
TARGET_ARCH: "aarch64"
|
||||
|
||||
fedora.ppc64le:
|
||||
<<: *create_docker_image
|
||||
variables:
|
||||
DOCKER_DRIVER: overlay
|
||||
DOCKERFILE: "build-aux/ci/Dockerfile.ppc64le.fedora.latest"
|
||||
NAME: "fedora.ppc64le"
|
||||
TARGET_ARCH: "ppc64le"
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
<!--
|
||||
|
||||
Not following the communication guidelines [1] will mean your issue or comment
|
||||
will be removed. Read it carefully before submitting this issue.
|
||||
|
||||
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guideline
|
||||
|
||||
-->
|
||||
|
||||
Detailed description of the issue. Put as much information as you can, potentially
|
||||
with images showing the issue.
|
||||
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
<!--
|
||||
|
||||
Not following the communication guidelines [1] will mean your issue or comment
|
||||
will be removed. Read it carefully before submitting this issue.
|
||||
|
||||
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guideline
|
||||
|
||||
-->
|
||||
|
||||
Detailed description of the feature. Put as much information as you can.
|
||||
|
||||
Proposed Mockups:
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -3,4 +3,4 @@
|
||||
url = https://gitlab.gnome.org/GNOME/libgnome-volume-control.git
|
||||
[submodule "subprojects/libhandy"]
|
||||
path = subprojects/libhandy
|
||||
url = https://gitlab.gnome.org/GNOME/libhandy.git
|
||||
url = https://source.puri.sm/Librem5/libhandy.git
|
||||
|
||||
390
NEWS
390
NEWS
@@ -1,395 +1,27 @@
|
||||
================
|
||||
Version 41.beta
|
||||
================
|
||||
|
||||
- Introduce the new Cellular panel
|
||||
- Introduce the new Multitasking panel
|
||||
- Updated translations
|
||||
|
||||
About
|
||||
- Fix a crash due to uninitialized variables
|
||||
|
||||
Bluetooth
|
||||
- Fix Bluetooth switch transitions
|
||||
|
||||
Location
|
||||
- Fix permission store id (again)
|
||||
|
||||
Power
|
||||
- Polish power profiles section
|
||||
|
||||
================
|
||||
Version 41.alpha
|
||||
================
|
||||
|
||||
- Improve and fix the development Flatpak manifest
|
||||
- Drop dependency on grilo
|
||||
- Updated translations
|
||||
|
||||
About
|
||||
- Don't show GNOME micro version number
|
||||
- Look for dark and text distro logo variants
|
||||
|
||||
Accessibility
|
||||
- Add "Enable Animations" option
|
||||
|
||||
Location
|
||||
- Fix permission store id
|
||||
|
||||
Mouse & Touchpad
|
||||
- Update artwork
|
||||
|
||||
Online Accounts
|
||||
- Present all online accounts providers at once
|
||||
|
||||
Power
|
||||
- Integrate with new power profiles daemon API
|
||||
- Show more information about power profiles
|
||||
- Cleanup some preferences
|
||||
|
||||
================
|
||||
Version 40
|
||||
Version 3.32.2
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 40.rc
|
||||
================
|
||||
|
||||
- Various fixes to the language chooser
|
||||
- Updated translations
|
||||
|
||||
Location
|
||||
- Wrap label to fit smaller window sizes
|
||||
|
||||
Mouse & Touchpad
|
||||
- Allow horizontal scrolling in test page
|
||||
|
||||
Network
|
||||
- Fix creation of the netmask widget
|
||||
|
||||
================
|
||||
Version 40.beta
|
||||
================
|
||||
|
||||
- Various improvements to fingerprint management
|
||||
- Show hardware model and vendor in the About panel
|
||||
- New Keyboard panel design
|
||||
- New power mode selector in the Power panel
|
||||
- Updated translations
|
||||
|
||||
About
|
||||
- Show hardware model and vendor
|
||||
- Use os-release to search for the OS logo
|
||||
|
||||
Accessibility
|
||||
- Major code cleanup
|
||||
|
||||
Display
|
||||
- Try harder to select a good and working scale
|
||||
|
||||
Keyboard
|
||||
- Handle input sources
|
||||
|
||||
Power
|
||||
- Rearrange battery code to a new widget
|
||||
- Add a new "Power Mode" section
|
||||
|
||||
Sharing
|
||||
- Also disable Traker3
|
||||
|
||||
Sound
|
||||
- Update mute button icon when volume changes
|
||||
|
||||
User Accounts
|
||||
- Fix free of constant string
|
||||
- Use properly translated fingerprint strings
|
||||
- Improve transition to parental controls window
|
||||
- Many improvements to fingerprint management
|
||||
|
||||
================
|
||||
Version 3.38.0
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 3.37.92
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Display
|
||||
- Show screen orientation setting even when accelerometer is present
|
||||
|
||||
Wacom
|
||||
- Group pad/stylus devices together with the group name
|
||||
|
||||
================
|
||||
Version 3.37.90
|
||||
================
|
||||
|
||||
- Rename Universal to Accessibility
|
||||
- Updated translations
|
||||
- Clean CI jobs
|
||||
- Adapt to libhandy-1
|
||||
|
||||
Network
|
||||
- Add support for Enhanced Open Wi-Fi security
|
||||
- Fix connection editor blanking when removing manual entry
|
||||
- Small fixes
|
||||
|
||||
Thunderbolt
|
||||
- Plug some memory leaks
|
||||
|
||||
User Accounts
|
||||
- Show "Take a picture" button only when cam is available
|
||||
|
||||
================
|
||||
Version 3.37.3
|
||||
================
|
||||
|
||||
- Update various panels with more modern GTK practices
|
||||
- Improve how time periods are displayed
|
||||
- Rework CI images to use FreeDesktop-style templates
|
||||
- Improve Settings icon
|
||||
- Updated translations
|
||||
|
||||
Applications
|
||||
- Integrate with parental controls
|
||||
|
||||
Date & Time
|
||||
- Add new time editor UI
|
||||
|
||||
Keyboard
|
||||
- Various cleanups
|
||||
|
||||
Lock Screen
|
||||
- Add USB protection entry when available
|
||||
|
||||
Power
|
||||
- Add option to show battery percentage
|
||||
- Various smaller UI adjustments
|
||||
|
||||
Printers
|
||||
- Do not authenticate SMB servers when search field is edited
|
||||
|
||||
Sharing
|
||||
- Set label for checkbox properly
|
||||
- Use gnome-remote-desktop instead of Vino on X11
|
||||
|
||||
Sound
|
||||
- Fix translation of "System Sounds"
|
||||
- Stop non-interactive profile changes from triggering changed events
|
||||
|
||||
User Accounts
|
||||
- Always show permissions bar, even when no users are listed
|
||||
- Use custom setting to override faces
|
||||
- New Fingerprint dialog and various related improvements
|
||||
- Integrate with parental controls
|
||||
|
||||
================
|
||||
Version 3.36.1
|
||||
================
|
||||
|
||||
- Update man page for info panel change
|
||||
- Updated translations
|
||||
|
||||
Display
|
||||
- Fix resolution options getting stuck in a low resolution
|
||||
|
||||
Sound
|
||||
- Remove unused files
|
||||
|
||||
================
|
||||
Version 3.36.0
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 3.35.92
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Applications
|
||||
- Update icon
|
||||
|
||||
Background
|
||||
- Remove split desktop and lock screen wallpapers
|
||||
- Improve visuals of the background icons
|
||||
|
||||
Network
|
||||
- Make VPN gear buttons consistent with oter buttons
|
||||
|
||||
================
|
||||
Version 3.35.91
|
||||
================
|
||||
|
||||
- Share GCancellable code
|
||||
- Updated translations
|
||||
|
||||
Background
|
||||
- Remove unused GCancellable
|
||||
|
||||
Power
|
||||
- Fix mobile broadband switch logic
|
||||
|
||||
Sharing
|
||||
- Remember password on remote desktop sharing
|
||||
|
||||
Thunderbolt
|
||||
- Fix GCancellable leak
|
||||
|
||||
User Accounts
|
||||
- Always generate user avatars
|
||||
|
||||
================
|
||||
Version 3.35.90
|
||||
================
|
||||
|
||||
- New sidebar panel order and grouping
|
||||
- Introduce CcPermissionInfoBar
|
||||
- More code style updates
|
||||
- Updated translations
|
||||
|
||||
Applications
|
||||
- Add "Run in Background" switch
|
||||
- Add "Set Desktop Background" switch
|
||||
- Show snap packages
|
||||
|
||||
Network
|
||||
- Add SAE support
|
||||
- Many code refactorings
|
||||
- Switch to use GtkTemplate
|
||||
|
||||
Power
|
||||
- Hide power button the chassis is handset
|
||||
|
||||
Printers
|
||||
- Use CcPermissionInfoBar
|
||||
|
||||
Region & Language
|
||||
- New design for the Formats dialog
|
||||
|
||||
User Accounts
|
||||
- Use CcPermissionInfoBar
|
||||
- Improved layout
|
||||
|
||||
================
|
||||
Version 3.35.2
|
||||
================
|
||||
|
||||
- Tighten up code style
|
||||
- Improve timezone for various countries
|
||||
- Replace deprecated logging functions with modern equivalents
|
||||
- Updated translations
|
||||
|
||||
Background
|
||||
- Update clock in both preview modes
|
||||
|
||||
Date & Time
|
||||
- Allow changing the timezone when auto-update is prohibited
|
||||
|
||||
Display
|
||||
- Replace CC_DISPLAY_*_GET_PRIVATE
|
||||
|
||||
Info
|
||||
- Implement new design
|
||||
- Add windowing system field
|
||||
|
||||
Network
|
||||
- Add new hotspot creation dialog
|
||||
- Major cleanups and code refactorings
|
||||
- Plug various memory leaks
|
||||
|
||||
Privacy
|
||||
- Drop the panel and replace it by various subpanels
|
||||
|
||||
Search
|
||||
- Make rows and its elements reachable via keyboard
|
||||
|
||||
Sharing
|
||||
- Set new shared folder visible as soon as it gets added
|
||||
|
||||
Sound
|
||||
- Remove leftover canberra-gtk header inclusion
|
||||
|
||||
Universal Access
|
||||
- Make rows and its elements reachable via keyboard
|
||||
|
||||
User Accounts
|
||||
- Use 'pw usershow' to check username validity on FreeBSD
|
||||
|
||||
|
||||
================
|
||||
Version 3.34.0.1
|
||||
================
|
||||
|
||||
Sound
|
||||
- Fix sliders not behaving properly
|
||||
|
||||
|
||||
================
|
||||
Version 3.34.0
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 3.33.90
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Background:
|
||||
- Clarify remove background button
|
||||
Applications:
|
||||
- Use larger icons
|
||||
|
||||
Display:
|
||||
- Various bugfixes
|
||||
|
||||
Search:
|
||||
- Introduce Drag n' Drop
|
||||
- Visual polishment
|
||||
|
||||
|
||||
================
|
||||
Version 3.33.3
|
||||
================
|
||||
|
||||
- Various minor improvements from the Every Detail Matters session
|
||||
- Add shadows to application icons
|
||||
- Documented Communication Guidelines
|
||||
- Development builds with Flatpak working again
|
||||
- Updated translations
|
||||
|
||||
Background:
|
||||
- Redesigned panel
|
||||
|
||||
Display:
|
||||
- Move Night Light to a tab, instead of a dialog
|
||||
|
||||
Keyboard Shortcuts:
|
||||
- Panel renamed from "Keyboard"
|
||||
- Minor UI adjustments
|
||||
- Set Night Light screen temperature strings as translatable
|
||||
- Fix crash if a monitor has no preferred mode
|
||||
|
||||
Mouse & Touchpad:
|
||||
- Reinstate keyboard navitation
|
||||
- Reinstate keyboard navigation in the panel
|
||||
|
||||
Power:
|
||||
- Don't treat all batteries as laptop batteries
|
||||
- Correct the value of 90 minutes to 5400
|
||||
|
||||
Sharing:
|
||||
- Use a HdyLeaflet
|
||||
|
||||
User Accounts:
|
||||
- Present the default avatar in the avatar popover
|
||||
|
||||
Wacom:
|
||||
- Ensure calibrator UI CSS only applies to its UI
|
||||
Region & Language:
|
||||
- Fix input source options not being applied
|
||||
|
||||
Sound:
|
||||
- Clean up labels of devices without origin
|
||||
|
||||
================
|
||||
Version 3.32.1
|
||||
|
||||
25
README.md
25
README.md
@@ -1,4 +1,4 @@
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
|
||||
[](https://gnome.pages.gitlab.gnome.org/gnome-control-center/)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/COPYING)
|
||||
|
||||
@@ -12,9 +12,16 @@ GNOME Settings is GNOME's main interface for configuration of various aspects of
|
||||
See `docs/CONTRIBUTING.md` for details on the contribution process, and `docs/HACKING.md`
|
||||
for the coding style guidelines.
|
||||
|
||||
## Reporting Bugs
|
||||
## Testing Unstable Settings
|
||||
|
||||
Before reporting any bugs or opening feature requests, [read the communication guidelines][communication-guidelines].
|
||||
It is quite easy to test and give feedback about the development version of GNOME
|
||||
Settings. Just access https://gitlab.gnome.org/GNOME/gnome-control-center/environments,
|
||||
get the latest version, download it, double-click the file, install and run.
|
||||
|
||||
Note that GNOME Settings Flatpak will only work if you are running
|
||||
the latest GNOME version in your host system.
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
Bugs should be reported to the GNOME bug tracking system under the product
|
||||
gnome-control-center. It is available at [GitLab Issues](https://gitlab.gnome.org/GNOME/gnome-control-center/issues).
|
||||
@@ -49,15 +56,3 @@ Reproduce the crash and when the program exits to (gdb) prompt, get the backtrac
|
||||
|
||||
Once you have the backtrace, copy and paste it into the 'Comments' field or attach it as
|
||||
a file to the bug report.
|
||||
|
||||
## Testing Unstable Settings
|
||||
|
||||
It is quite easy to test and give feedback about the development version of GNOME
|
||||
Settings. Just access https://gitlab.gnome.org/GNOME/gnome-control-center/environments,
|
||||
get the latest version, download it, double-click the file, install and run.
|
||||
|
||||
Note that GNOME Settings Flatpak will only work if you are running
|
||||
the latest GNOME version in your host system.
|
||||
|
||||
|
||||
[communication-guidelines]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guidelines
|
||||
|
||||
26
build-aux/ci/Dockerfile.arm64v8.fedora.30
Normal file
26
build-aux/ci/Dockerfile.arm64v8.fedora.30
Normal file
@@ -0,0 +1,26 @@
|
||||
FROM arm64v8/fedora:30
|
||||
MAINTAINER Claudio André (c) 2018 V1.0
|
||||
|
||||
LABEL architecture="aarch64"
|
||||
LABEL version="1.0"
|
||||
LABEL description="Multiarch Docker image to run CI for GNOME Settings."
|
||||
|
||||
ADD x86_64_qemu-aarch64-static.tar.gz /usr/bin
|
||||
|
||||
RUN dnf -y --nogpgcheck upgrade && \
|
||||
dnf -y install \
|
||||
@c-development @development-tools clang libasan gcovr \
|
||||
accountsservice-devel cheese-libs-devel chrpath colord-devel \
|
||||
colord-gtk-devel cups-devel desktop-file-utils docbook-style-xsl flatpak-devel gdk-pixbuf2-devel \
|
||||
gettext git glib2-devel gnome-bluetooth-libs-devel gnome-desktop3-devel \
|
||||
gnome-online-accounts-devel gnome-settings-daemon-devel grilo-devel \
|
||||
gsettings-desktop-schemas-devel gsound-devel gtk3-devel ibus-devel intltool libcanberra-devel \
|
||||
libgtop2-devel libgudev-devel libnma-devel libpwquality-devel libsmbclient-devel \
|
||||
libsoup-devel libudisks2-devel libwacom-devel libX11-devel libXi-devel libxml2-devel libxslt \
|
||||
libXxf86misc-devel meson ModemManager-glib-devel NetworkManager-libnm-devel \
|
||||
polkit-devel pulseaudio-libs-devel upower-devel \
|
||||
python3-dbusmock xorg-x11-server-Xvfb mesa-dri-drivers libsecret-devel && \
|
||||
dnf -y clean all
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
24
build-aux/ci/Dockerfile.fedora.30
Normal file
24
build-aux/ci/Dockerfile.fedora.30
Normal file
@@ -0,0 +1,24 @@
|
||||
FROM fedora:30
|
||||
MAINTAINER Claudio André (c) 2018 V1.0
|
||||
|
||||
LABEL architecture="x86_64"
|
||||
LABEL version="1.0"
|
||||
LABEL description="Docker image to run CI for GNOME Settings."
|
||||
|
||||
RUN dnf -y --nogpgcheck upgrade && \
|
||||
dnf -y install \
|
||||
@c-development @development-tools clang libasan gcovr \
|
||||
accountsservice-devel cheese-libs-devel chrpath colord-devel \
|
||||
colord-gtk-devel cups-devel desktop-file-utils docbook-style-xsl flatpak-devel gdk-pixbuf2-devel \
|
||||
gettext git glib2-devel gnome-bluetooth-libs-devel gnome-desktop3-devel \
|
||||
gnome-online-accounts-devel gnome-settings-daemon-devel grilo-devel \
|
||||
gsettings-desktop-schemas-devel gsound-devel gtk3-devel ibus-devel intltool libcanberra-devel \
|
||||
libgtop2-devel libgudev-devel libnma-devel libpwquality-devel libsmbclient-devel \
|
||||
libsoup-devel libudisks2-devel libwacom-devel libX11-devel libXi-devel libxml2-devel libxslt \
|
||||
libXxf86misc-devel meson ModemManager-glib-devel NetworkManager-libnm-devel \
|
||||
polkit-devel pulseaudio-libs-devel upower-devel \
|
||||
python3-dbusmock xorg-x11-server-Xvfb mesa-dri-drivers libsecret-devel llvm && \
|
||||
dnf -y clean all
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
26
build-aux/ci/Dockerfile.ppc64le.fedora.latest
Normal file
26
build-aux/ci/Dockerfile.ppc64le.fedora.latest
Normal file
@@ -0,0 +1,26 @@
|
||||
FROM ppc64le/fedora:latest
|
||||
MAINTAINER Claudio André (c) 2018 V1.0
|
||||
|
||||
LABEL architecture="ppc64le"
|
||||
LABEL version="1.0"
|
||||
LABEL description="Multiarch Docker image to run CI for GNOME Settings."
|
||||
|
||||
ADD x86_64_qemu-ppc64le-static.tar.gz /usr/bin
|
||||
|
||||
RUN dnf -y --nogpgcheck upgrade && \
|
||||
dnf -y install \
|
||||
@c-development @development-tools clang libasan gcovr \
|
||||
accountsservice-devel cheese-libs-devel chrpath colord-devel \
|
||||
colord-gtk-devel cups-devel desktop-file-utils docbook-style-xsl flatpak-devel gdk-pixbuf2-devel \
|
||||
gettext git glib2-devel gnome-bluetooth-libs-devel gnome-desktop3-devel \
|
||||
gnome-online-accounts-devel gnome-settings-daemon-devel grilo-devel \
|
||||
gsettings-desktop-schemas-devel gsound-devel gtk3-devel ibus-devel intltool libcanberra-devel \
|
||||
libgtop2-devel libgudev-devel libnma-devel libpwquality-devel libsmbclient-devel \
|
||||
libsoup-devel libudisks2-devel libwacom-devel libX11-devel libXi-devel libxml2-devel libxslt \
|
||||
libXxf86misc-devel meson ModemManager-glib-devel NetworkManager-libnm-devel \
|
||||
polkit-devel pulseaudio-libs-devel upower-devel \
|
||||
python3-dbusmock xorg-x11-server-Xvfb mesa-dri-drivers libsecret-devel && \
|
||||
dnf -y clean all
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
From ba5e0451b51c983e40afd123b6e0d3eddb55e610 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sat, 24 Mar 2018 17:37:02 +0000
|
||||
Subject: linux: Include <sys/sysmacros.h> for major() macro.
|
||||
|
||||
Since glibc 2.27 this header is required.
|
||||
---
|
||||
libparted/arch/linux.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
|
||||
index 31b98ab..7e86b51 100644
|
||||
--- a/libparted/arch/linux.c
|
||||
+++ b/libparted/arch/linux.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <sys/utsname.h> /* for uname() */
|
||||
#include <scsi/scsi.h>
|
||||
#include <assert.h>
|
||||
+#include <sys/sysmacros.h>
|
||||
#ifdef ENABLE_DEVICE_MAPPER
|
||||
#include <libdevmapper.h>
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"app-id" : "org.gnome.Settings",
|
||||
"runtime" : "org.gnome.Sdk",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gnome-control-center",
|
||||
@@ -48,7 +48,6 @@
|
||||
"name" : "pwquality",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--disable-python-bindings"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -58,54 +57,53 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "intltool",
|
||||
"cleanup": [ "*" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz",
|
||||
"sha256": "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"
|
||||
"name" : "mozjs52",
|
||||
"build-options" : {
|
||||
"arch" : {
|
||||
"i386" : {
|
||||
"config-opts" : [
|
||||
"--host=i586-unknown-linux-gnu"
|
||||
]
|
||||
},
|
||||
"arm" : {
|
||||
"config-opts" : [
|
||||
"--host=arm-unknown-linux-gnueabi"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"config-opts": [
|
||||
"--enable-posix-nspr-emulation",
|
||||
"--with-system-zlib",
|
||||
"--without-system-icu",
|
||||
"--with-intl-api",
|
||||
"--disable-jemalloc",
|
||||
"AUTOCONF=autoconf"
|
||||
],
|
||||
"builddir" : true,
|
||||
"subdir" : "js/src",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://download.gnome.org/teams/releng/tarballs-needing-help/mozjs/mozjs-52.2.1gnome1.tar.gz",
|
||||
"sha256" : "31697943b1dbbb51ba9aee35b8269a353c487d7af4d336010b90054dc4f9b0af"
|
||||
}
|
||||
],
|
||||
"cleanup" : [
|
||||
"libjs_static.ajs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "polkit",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--disable-polkitd",
|
||||
"--disable-man-pages",
|
||||
"--disable-introspection",
|
||||
"--disable-examples",
|
||||
"--disable-gtk-doc",
|
||||
"--disable-libelogind",
|
||||
"--disable-libsystemd-login",
|
||||
"--with-systemdsystemunitdir=no",
|
||||
"--with-authdb=dummy",
|
||||
"--with-authfw=none"
|
||||
],
|
||||
"rm-configure" : true,
|
||||
"cleanup" : [
|
||||
"/bin/*",
|
||||
"/etc/pam.d",
|
||||
"/etc/dbus-1",
|
||||
"/share/dbus-1/system-services/*",
|
||||
"/share/polkit-1",
|
||||
"/lib/polkit-1"
|
||||
"--disable-libelogind"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://www.freedesktop.org/software/polkit/releases/polkit-0.116.tar.gz",
|
||||
"sha256" : "88170c9e711e8db305a12fdb8234fac5706c61969b94e084d0f117d8ec5d34b1"
|
||||
},
|
||||
{
|
||||
"type" : "patch",
|
||||
"path" : "polkit-build-Add-option-to-build-without-polkitd.patch"
|
||||
},
|
||||
{
|
||||
"type" : "file",
|
||||
"path" : "polkit-autogen",
|
||||
"dest-filename" : "autogen.sh"
|
||||
"type" : "git",
|
||||
"url" : "git://anongit.freedesktop.org/polkit"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -189,10 +187,9 @@
|
||||
},
|
||||
{
|
||||
"name" : "gudev",
|
||||
"buildsystem" : "meson",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"-Dtests=disabled",
|
||||
"-Dintrospection=disabled"
|
||||
"--disable-umockdev"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -209,11 +206,7 @@
|
||||
"-Dbash_completion=false",
|
||||
"-Dman=false",
|
||||
"-Dudev_rules=false",
|
||||
"-Dsystemd=false",
|
||||
"-Dvapi=false",
|
||||
"-Ddocs=false",
|
||||
"-Dtests=false",
|
||||
"-Dinstalled_tests=false"
|
||||
"-Dsystemd=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -224,9 +217,8 @@
|
||||
},
|
||||
{
|
||||
"name" : "colord-gtk",
|
||||
"buildsystem" : "meson",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"-Dman=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -248,14 +240,13 @@
|
||||
},
|
||||
{
|
||||
"name" : "gnome-online-accounts",
|
||||
"buildsystem" : "meson",
|
||||
"buildsystem" : "autotools",
|
||||
"build-options" : {
|
||||
"cflags" : "-Wno-error"
|
||||
},
|
||||
"config-opts" : [
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dvapi=false"
|
||||
"--disable-telepathy",
|
||||
"--disable-documentation"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -277,11 +268,6 @@
|
||||
{
|
||||
"name" : "geocode-glib",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Denable-gtk-doc=false",
|
||||
"-Denable-introspection=false",
|
||||
"-Denable-installed-tests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
@@ -292,11 +278,6 @@
|
||||
{
|
||||
"name" : "libgweather",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dglade_catalog=false",
|
||||
"-Denable_vala=false",
|
||||
"-Dgtk_doc=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
@@ -307,13 +288,6 @@
|
||||
{
|
||||
"name" : "upower",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--prefix=/app",
|
||||
"--with-systemdsystemunitdir=/app/lib/systemd/system",
|
||||
"--disable-gtk-doc",
|
||||
"--disable-man-pages",
|
||||
"--disable-tests"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
@@ -376,47 +350,23 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch": "main",
|
||||
"tag": "1.14.0",
|
||||
"commit" : "2979c891c4af7584780924e92b6d448b7d6cd328",
|
||||
"url" : "https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "mobile-broadband-provider-info",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libnma",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dvapi=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libnma.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "network-manager-applet",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dappindicator=no",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dlibnm_gtk=false",
|
||||
"-Dselinux=false",
|
||||
"-Dteam=false",
|
||||
"-Dwwan=false"
|
||||
"-Dwwan=false",
|
||||
"-Dmobile_broadband_provider_info=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -432,7 +382,6 @@
|
||||
"--disable-introspection",
|
||||
"--disable-vala",
|
||||
"--with-udev-base-dir=/app/lib",
|
||||
"--with-systemdsystemunitdir=/app/lib/systemd/system",
|
||||
"--without-mbim",
|
||||
"--without-qmi"
|
||||
],
|
||||
@@ -446,31 +395,11 @@
|
||||
{
|
||||
"name" : "gnome-settings-daemon",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dsystemd=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gnome-settings-daemon.git"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "libcanberra",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "http://0pointer.de/lennart/projects/libcanberra/libcanberra-0.30.tar.xz",
|
||||
"sha256": "c2b671e67e0c288a69fc33dc1b6f1b534d07882c2aceed37004bf48c601afa72"
|
||||
}
|
||||
],
|
||||
"config-opts": [
|
||||
"--disable-alsa",
|
||||
"--disable-null",
|
||||
"--disable-oss"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -486,6 +415,23 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "grilo",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Denable-grl-pls=false",
|
||||
"-Denable-gtk-doc=false",
|
||||
"-Denable-introspection=false",
|
||||
"-Denable-test-ui=false",
|
||||
"-Denable-vala=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/grilo.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "openldap",
|
||||
"buildsystem" : "autotools",
|
||||
@@ -506,8 +452,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "http://downloads.sourceforge.net/sourceforge/libtirpc/libtirpc-1.2.6.tar.bz2",
|
||||
"sha256" : "4278e9a5181d5af9cd7885322fdecebc444f9a3da87c526e7d47f7a12a37d1cc"
|
||||
"url" : "http://downloads.sourceforge.net/sourceforge/libtirpc/libtirpc-1.0.3.tar.bz2",
|
||||
"sha256" : "86c3a78fc1bddefa96111dd233124c703b22a78884203c55c3e06b3be6a0fd5e"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -522,61 +468,14 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "lmdb",
|
||||
"buildsystem" : "simple",
|
||||
"build-commands" : [
|
||||
"cd libraries/liblmdb/ && make prefix=/app install"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://github.com/LMDB/lmdb/archive/LMDB_0.9.23.tar.gz",
|
||||
"sha256" : "abf42e91f046787ed642d9eb21812a5c473f3ba5854124484d16eadbe0aa9c81"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "yapp-driver",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"perl Makefile.PL",
|
||||
"make install -j1"
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"PERL5LIB": "/app/lib/perl5/",
|
||||
"PERL_MM_OPT": "INSTALL_BASE=/app"
|
||||
}
|
||||
},
|
||||
"cleanup": [ "*" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://cpan.metacpan.org/authors/id/W/WB/WBRASWELL/Parse-Yapp-1.21.tar.gz",
|
||||
"sha256": "3810e998308fba2e0f4f26043035032b027ce51ce5c8a52a8b8e340ca65f13e5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "samba",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--without-json",
|
||||
"--without-ad-dc",
|
||||
"--without-pam"
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"PERL5LIB": "/app/lib/perl5/",
|
||||
"PERL_MM_OPT": "INSTALL_BASE=/app"
|
||||
}
|
||||
},
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://download.samba.org/pub/samba/stable/samba-4.14.5.tar.gz",
|
||||
"sha256" : "bb6ef5d2f16b85288d823578abc453d9a80514c42e5a2ea2c4e3c60dc42335c3"
|
||||
"url" : "https://download.samba.org/pub/samba/stable/samba-4.8.1.tar.gz",
|
||||
"sha256" : "8ef7367507f16b7a5e2f6aed5bcdbd1143feca79aa2a07c9b21292b17d7f789d"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -593,62 +492,11 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cogl",
|
||||
"config-opts": [
|
||||
"--disable-cogl-gst",
|
||||
"--enable-xlib-egl-platform",
|
||||
"--enable-wayland-egl-platform"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/cogl.git",
|
||||
"branch": "cogl-1.22"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clutter",
|
||||
"config-opts": [
|
||||
"--enable-egl-backend",
|
||||
"--enable-wayland-backend"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/clutter/1.26/clutter-1.26.4.tar.xz",
|
||||
"sha256": "8b48fac159843f556d0a6be3dbfc6b083fc6d9c58a20a49a6b4919ab4263c4e6"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clutter-gtk",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/clutter-gtk/1.8/clutter-gtk-1.8.4.tar.xz",
|
||||
"sha256": "521493ec038973c77edcb8bc5eac23eed41645117894aaee7300b2487cb42b06"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clutter-gst",
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/clutter-gst.git",
|
||||
"branch": "clutter-gst-3.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "cheese",
|
||||
"buildsystem" : "meson",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"-Dintrospection=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dman=false"
|
||||
"--disable-introspection"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -658,8 +506,25 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gsound",
|
||||
"name" : "libhandy",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dexamples=false",
|
||||
"-Dglade_catalog=disabled",
|
||||
"-Dintrospection=disabled",
|
||||
"-Dtests=false",
|
||||
"-Dvapi=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://source.puri.sm/Librem5/libhandy.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gsound",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
@@ -667,200 +532,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libkmod",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://mirrors.edge.kernel.org/pub/linux/utils/kernel/kmod/kmod-25.tar.xz",
|
||||
"sha256" : "7165e6496656159dcb909a91ed708a0fe273a4b128b4b1dc997ccb5189eef1cd"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "lvm2",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--prefix=/app",
|
||||
"--enable-cmdlib",
|
||||
"--enable-dmeventd",
|
||||
"--enable-pkgconfig",
|
||||
"--with-usrlibdir=/app/lib",
|
||||
"--with-usrbindir=/app/bin",
|
||||
"--with-staticdir=/app/bin"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://www.sourceware.org/pub/lvm2/LVM2.2.02.177.tgz",
|
||||
"sha256" : "4025a23ec9b15c2cb7486d151c29dc953b75efc4d452cfe9dbbc7c0fac8e80f2"
|
||||
}
|
||||
],
|
||||
"post-install" : [
|
||||
"chmod 755 /app/sbin/dm*",
|
||||
"chmod 755 /app/sbin/lvm*",
|
||||
"chmod 755 /app/lib/libdevmapper-event-lvm2.so.2.02",
|
||||
"chmod 755 /app/lib/libdevmapper-event-lvm2mirror.so",
|
||||
"chmod 755 /app/lib/libdevmapper-event-lvm2raid.so",
|
||||
"chmod 755 /app/lib/libdevmapper-event-lvm2snapshot.so",
|
||||
"chmod 755 /app/lib/libdevmapper-event-lvm2thin.so",
|
||||
"chmod 755 /app/lib/libdevmapper-event.so.1.02",
|
||||
"chmod 755 /app/lib/libdevmapper.so.1.02",
|
||||
"chmod 755 /app/lib/liblvm2cmd.so.2.02"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "parted",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "http://ftp.gnu.org/gnu/parted/parted-3.2.tar.xz",
|
||||
"sha256" : "858b589c22297cacdf437f3baff6f04b333087521ab274f7ab677cb8c6bb78e4"
|
||||
},
|
||||
{
|
||||
"type" : "patch",
|
||||
"path" : "libparted-include.patch"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "mpfr",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://www.mpfr.org/mpfr-4.0.2/mpfr-4.0.2.tar.xz",
|
||||
"sha256" : "1d3be708604eae0e42d578ba93b390c2a145f17743a744d8f3f8c2ad5855a38a"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "bytesize",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--with-gtk-doc=no"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/storaged-project/libbytesize.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "popt",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/rpm-software-management/popt",
|
||||
"tag" : "popt-1.18-release"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "cryptsetup",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz",
|
||||
"sha256" : "2b30cd1d0dd606a53ac77b406e1d37798d4b0762fa89de6ea546201906a251bd"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "swig",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/swig/swig.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "volume-key",
|
||||
"buildsystem" : "simple",
|
||||
"build-commands" : [
|
||||
"autoreconf -i",
|
||||
"./configure --prefix=/app",
|
||||
"make install"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://github.com/felixonmars/volume_key/archive/volume_key-0.3.11.tar.gz",
|
||||
"sha256" : "92250506756eca19a0b6f50c16d3502eb5566ea4725645d7c5d87eb5cc8f3fd8"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libblockdev",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--disable-tests",
|
||||
"--with-btrfs=no",
|
||||
"--with-dm=no",
|
||||
"--with-gtk-doc=no",
|
||||
"--with-kbd=no",
|
||||
"--with-lvm=no",
|
||||
"--with-lvm-dbus=no",
|
||||
"--with-mpath=no",
|
||||
"--with-nvdimm=no",
|
||||
"--with-tools=no",
|
||||
"--with-vdo=no"
|
||||
],
|
||||
"build-options" : {
|
||||
"cflags" : "-Wno-error"
|
||||
},
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/storaged-project/libblockdev.git",
|
||||
"commit" : "f90a33aa03a50eff79e2dc932a8e7742f94d5927"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "atasmart",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "http://0pointer.de/public/libatasmart-0.19.tar.xz",
|
||||
"sha256" : "61f0ea345f63d28ab2ff0dc352c22271661b66bf09642db3a4049ac9dbdb0f8d"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "udisks",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"--disable-introspection",
|
||||
"--disable-lvm2",
|
||||
"--with-systemdsystemunitdir=/app/lib/systemd/system",
|
||||
"--with-tmpfilesdir=/app/lib/tmpfiles.d"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/storaged-project/udisks.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gnome-backgrounds",
|
||||
"buildsystem" : "meson",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gnome-backgrounds.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gnome-control-center",
|
||||
"buildsystem" : "meson",
|
||||
@@ -871,8 +542,7 @@
|
||||
}
|
||||
],
|
||||
"config-opts" : [
|
||||
"-Dtracing=true",
|
||||
"-Dprofile=development"
|
||||
"-Dtracing=true"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
gtkdocize --flavour no-tmpl
|
||||
autoreconf -if
|
||||
@@ -1,132 +0,0 @@
|
||||
From 1073a44277316348d40d86ecec908f1d4812f360 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Mon, 27 May 2019 11:49:09 -0700
|
||||
Subject: [PATCH] flatpak: make polkit suitable for use within flatpak
|
||||
|
||||
This is based on patches from Patrick Griffis with additional fixes
|
||||
to allow us to disable use of PAM within Flaptak.
|
||||
---
|
||||
configure.ac | 20 ++++++++++++++++----
|
||||
src/Makefile.am | 6 +++++-
|
||||
src/polkitagent/Makefile.am | 5 +++++
|
||||
test/Makefile.am | 6 +++++-
|
||||
4 files changed, 31 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 5cedb4e..729d78d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -79,11 +79,13 @@ PKG_CHECK_MODULES(GLIB, [gmodule-2.0 gio-unix-2.0 >= 2.30.0])
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
|
||||
-PKG_CHECK_MODULES(LIBJS, [mozjs-60])
|
||||
+AS_IF([test x${enable_polkitd} = yes], [
|
||||
+ PKG_CHECK_MODULES(LIBJS, [mozjs-60])
|
||||
|
||||
-AC_SUBST(LIBJS_CFLAGS)
|
||||
-AC_SUBST(LIBJS_CXXFLAGS)
|
||||
-AC_SUBST(LIBJS_LIBS)
|
||||
+ AC_SUBST(LIBJS_CFLAGS)
|
||||
+ AC_SUBST(LIBJS_CXXFLAGS)
|
||||
+ AC_SUBST(LIBJS_LIBS)
|
||||
+])
|
||||
|
||||
EXPAT_LIB=""
|
||||
AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
|
||||
@@ -236,6 +238,15 @@ if test "x$with_systemdsystemunitdir" != "xno"; then
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$systemdsystemunitdir"])
|
||||
|
||||
+dnl ---------------------------------------------------------------------------
|
||||
+dnl - Disable polkitd when using library alone
|
||||
+dnl ---------------------------------------------------------------------------
|
||||
+
|
||||
+AC_ARG_ENABLE([polkitd],
|
||||
+ [AS_HELP_STRING([--disable-polkitd], [Do not build polkitd])],
|
||||
+ [enable_polkitd=$enableval], [enable_polkitd=yes])
|
||||
+AM_CONDITIONAL(BUILD_POLKITD, [test x${enable_polkitd} = yes])
|
||||
+
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl - User for running polkitd
|
||||
dnl ---------------------------------------------------------------------------
|
||||
@@ -579,6 +590,7 @@ echo "
|
||||
Session tracking: ${SESSION_TRACKING}
|
||||
PAM support: ${have_pam}
|
||||
systemdsystemunitdir: ${systemdsystemunitdir}
|
||||
+ polkitd: ${enable_polkitd}
|
||||
polkitd user: ${POLKITD_USER}"
|
||||
|
||||
if test "$have_pam" = yes ; then
|
||||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||||
index 09fc7b3..c6fe91b 100644
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -1,5 +1,9 @@
|
||||
|
||||
-SUBDIRS = polkit polkitbackend polkitagent programs
|
||||
+SUBDIRS = polkit polkitagent programs
|
||||
+
|
||||
+if BUILD_POLKITD
|
||||
+SUBDIRS += polkitbackend
|
||||
+endif
|
||||
|
||||
if BUILD_EXAMPLES
|
||||
SUBDIRS += examples
|
||||
diff --git a/src/polkitagent/Makefile.am b/src/polkitagent/Makefile.am
|
||||
index 49720db..633f9d4 100644
|
||||
--- a/src/polkitagent/Makefile.am
|
||||
+++ b/src/polkitagent/Makefile.am
|
||||
@@ -79,6 +79,7 @@ libpolkit_agent_1_la_LIBADD = \
|
||||
|
||||
libpolkit_agent_1_la_LDFLAGS = -export-symbols-regex '(^polkit_.*)'
|
||||
|
||||
+if !POLKIT_AUTHFW_NONE
|
||||
libprivdir = $(prefix)/lib/polkit-1
|
||||
libpriv_PROGRAMS = polkit-agent-helper-1
|
||||
|
||||
@@ -113,6 +114,8 @@ polkit_agent_helper_1_LDFLAGS = \
|
||||
$(AM_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
+endif # !POLKIT_AUTHFW_NONE
|
||||
+
|
||||
if HAVE_INTROSPECTION
|
||||
|
||||
girdir = $(INTROSPECTION_GIRDIR)
|
||||
@@ -142,6 +145,7 @@ include $(INTROSPECTION_MAKEFILE)
|
||||
|
||||
endif # HAVE_INTROSPECTION
|
||||
|
||||
+if !POLKIT_AUTHFW_NONE
|
||||
# polkit-agent-helper-1 need to be setuid root because it's used to
|
||||
# authenticate not only the invoking user, but possibly also root
|
||||
# and/or other users.
|
||||
@@ -149,6 +153,7 @@ endif # HAVE_INTROSPECTION
|
||||
install-data-hook:
|
||||
-chown root $(DESTDIR)$(libprivdir)/polkit-agent-helper-1
|
||||
-chmod 4755 $(DESTDIR)$(libprivdir)/polkit-agent-helper-1
|
||||
+endif # !POLKIT_AUTHFW_NONE
|
||||
|
||||
EXTRA_DIST = polkitagentmarshal.list polkitagentenumtypes.h.template polkitagentenumtypes.c.template
|
||||
CLEANFILES = $(gir_DATA) $(typelibs_DATA)
|
||||
diff --git a/test/Makefile.am b/test/Makefile.am
|
||||
index 59d0680..d43b0fe 100644
|
||||
--- a/test/Makefile.am
|
||||
+++ b/test/Makefile.am
|
||||
@@ -1,7 +1,11 @@
|
||||
|
||||
-SUBDIRS = mocklibc . polkit polkitbackend
|
||||
+SUBDIRS = mocklibc . polkit
|
||||
AM_CFLAGS = $(GLIB_CFLAGS)
|
||||
|
||||
+if BUILD_POLKITD
|
||||
+SUBDIRS += polkitbackend
|
||||
+endif
|
||||
+
|
||||
noinst_LTLIBRARIES = libpolkit-test-helper.la
|
||||
libpolkit_test_helper_la_SOURCES = polkittesthelper.c polkittesthelper.h
|
||||
libpolkit_test_helper_la_LIBADD = $(GLIB_LIBS)
|
||||
--
|
||||
2.21.0
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
update_from_gsd = find_program('meson/update-from-gsd.sh')
|
||||
update_from_gsd_in = files('meson/update-from-gsd.in')
|
||||
update_from_nma_in = files('meson/update-from-nma.in')
|
||||
|
||||
meson.add_install_script('meson/meson_post_install.py', control_center_datadir)
|
||||
|
||||
10
build-aux/meson/update-from-gsd.in
Executable file
10
build-aux/meson/update-from-gsd.in
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd @working_dir@
|
||||
|
||||
export FILES="@source_files@"
|
||||
export DIR="@input_dir@"
|
||||
|
||||
@program@ &&
|
||||
git add @source_files@ &&
|
||||
git commit -m "@source_message@"
|
||||
26
build-aux/meson/update-from-gsd.sh
Executable file
26
build-aux/meson/update-from-gsd.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
function die() {
|
||||
echo $*
|
||||
exit 1
|
||||
}
|
||||
|
||||
if test -z "$DIR"; then
|
||||
echo "Must set DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$FILES"; then
|
||||
echo "Must set FILES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for FILE in $FILES; do
|
||||
if cmp -s $DIR/$FILE $FILE; then
|
||||
echo "File $FILE is unchanged"
|
||||
else
|
||||
cp $DIR/$FILE $FILE || die "Could not move $DIR/$FILE to $FILE"
|
||||
echo "Updated $FILE"
|
||||
git add $FILE
|
||||
fi
|
||||
done
|
||||
19
build-aux/meson/update-from-nma.in
Executable file
19
build-aux/meson/update-from-nma.in
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd @working_dir@
|
||||
|
||||
export FILES="@source_files@"
|
||||
export DIR="@input_dir@"
|
||||
|
||||
@program@ &&
|
||||
patch -p4 < @source_patch@ &&
|
||||
git add @source_files@ &&
|
||||
git commit -m "@source_message@"
|
||||
|
||||
export FILES="@resource_data@"
|
||||
export DIR="@input_dir@"
|
||||
|
||||
@program@ &&
|
||||
patch -p4 < @resource_patch@ &&
|
||||
git add @resource_data@ &&
|
||||
git commit -m "@resource_message@"
|
||||
@@ -1,109 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="64" x2="64" y1="262.5" y2="232">
|
||||
<stop offset="0" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#77767b"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="b" cx="-243.066583" cy="-74.599978" gradientUnits="userSpaceOnUse" r="28.266656">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#949390"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="203.999985" x2="267.999985" y1="-64" y2="-64">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#f6f5f4"/>
|
||||
</linearGradient>
|
||||
<clipPath id="d">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="e">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<filter id="f" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="g">
|
||||
<g clip-path="url(#e)" filter="url(#f)">
|
||||
<g clip-path="url(#d)">
|
||||
<path d="m 667 292 h -6 l -2 -16 h 10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(1 0 0 1 -600 -170)"/>
|
||||
<path d="m 661 180 h 6 l 2 16 h -10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(1 0 0 1 -600 -170)"/>
|
||||
<path d="m 667.000092 291.999908 h -6 l -2 -16 h 10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 299.999908 -598.000092)"/>
|
||||
<path d="m 661.000092 179.999908 h 6 l 2 16 h -10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 299.999908 -598.000092)"/>
|
||||
<path d="m 666.999051 291.998922 l -5.999272 -0.00042 l -2.001544 -15.998026 l 9.999915 0.000049 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -391.041005)"/>
|
||||
<path d="m 661.001107 180.000804 l 5.999273 0.000419 l 2.001544 15.998026 l -10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -391.041005)"/>
|
||||
<path d="m 667.000347 291.998468 l -5.999273 0.00042 l -2.002482 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -61.618176)"/>
|
||||
<path d="m 660.999745 180.00119 l 5.999273 -0.00042 l 2.002481 16.00035 l -10.003298 -0.001904 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -61.618176)"/>
|
||||
<path d="m 666.999018 291.999047 l -5.999273 -0.00042 l -2.001544 -15.998026 l 10.003298 -0.001904 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -470.382008)"/>
|
||||
<path d="m 661.001074 180.000929 l 5.999273 0.00042 l 2.001543 15.998025 l -10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -470.382008)"/>
|
||||
<path d="m 667.00038 291.998593 l -5.999273 0.00042 l -2.002481 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -627.040914)"/>
|
||||
<path d="m 660.999779 180.001315 l 5.999272 -0.00042 l 1.999099 15.998397 l -9.999915 0.000049 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -627.040914)"/>
|
||||
<path d="m 667 292 h -6 l -2 -16 h 10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(1 0 0 1 -600 -172)"/>
|
||||
<path d="m 661 180 h 6 l 2 16 h -10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(1 0 0 1 -600 -172)"/>
|
||||
<path d="m 667.000092 291.999908 h -6 l -2 -16 h 10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 299.999908 -600.000092)"/>
|
||||
<path d="m 661.000092 179.999908 h 6 l 2 16 h -10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 299.999908 -600.000092)"/>
|
||||
<path d="m 666.999051 291.998922 l -5.999272 -0.00042 l -2.001544 -15.998026 l 9.999915 0.000049 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -393.041005)"/>
|
||||
<path d="m 661.001107 180.000804 l 5.999273 0.000419 l 2.001544 15.998026 l -10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -393.041005)"/>
|
||||
<path d="m 667.000347 291.998468 l -5.999273 0.00042 l -2.002482 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -63.618176)"/>
|
||||
<path d="m 660.999745 180.00119 l 5.999273 -0.00042 l 2.002481 16.00035 l -10.003298 -0.001904 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -63.618176)"/>
|
||||
<path d="m 666.999018 291.999047 l -5.999273 -0.00042 l -2.001544 -15.998026 l 10.003298 -0.001904 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -472.382008)"/>
|
||||
<path d="m 661.001074 180.000929 l 5.999273 0.00042 l 2.001543 15.998025 l -10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -472.382008)"/>
|
||||
<path d="m 667.00038 291.998593 l -5.999273 0.00042 l -2.002481 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -629.040914)"/>
|
||||
<path d="m 660.999779 180.001315 l 5.999272 -0.00042 l 1.999099 15.998397 l -9.999915 0.000049 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -629.040914)"/>
|
||||
<path d="m 100 238 c 0 19.882812 -16.117188 36 -36 36 s -36 -16.117188 -36 -36 s 16.117188 -36 36 -36 s 36 16.117188 36 36 z m 0 0" fill="none" stroke="url(#a)" stroke-width="24" transform="matrix(1 0 0 1 0 -172)"/>
|
||||
<path d="m 102 236 c 0 20.988281 -17.011719 38 -38 38 s -38 -17.011719 -38 -38 s 17.011719 -38 38 -38 s 38 17.011719 38 38 z m 0 0" fill="none" stroke="#f6f5f4" stroke-width="20" transform="matrix(1 0 0 1 0 -172)"/>
|
||||
<path d="m -209.5 -64 c 0 14.636719 -11.863281 26.5 -26.5 26.5 s -26.5 -11.863281 -26.5 -26.5 s 11.863281 -26.5 26.5 -26.5 s 26.5 11.863281 26.5 26.5 z m 0 0" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round" stroke-width="5" transform="matrix(0 -1 -1 0 0 -172)"/>
|
||||
<path d="m 268 -64 c 0 17.671875 -14.328125 32 -32 32 s -32 -14.328125 -32 -32 s 14.328125 -32 32 -32 s 32 14.328125 32 32 z m 0 0" fill="none" stroke="url(#c)" stroke-linecap="square" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 0 -172)"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<mask id="h">
|
||||
<g filter="url(#f)">
|
||||
<rect fill-opacity="0.8" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="i" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
|
||||
<stop offset="0" stop-color="#f9f06b"/>
|
||||
<stop offset="1" stop-color="#f5c211"/>
|
||||
</linearGradient>
|
||||
<clipPath id="j">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="k">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<g stroke-linecap="round" stroke-linejoin="round" stroke-width="8">
|
||||
<path d="m 67 122 h -6 l -2 -16 h 10 z m 0 0" fill="#9a9996" stroke="#9a9996"/>
|
||||
<path d="m 61 10 h 6 l 2 16 h -10 z m 0 0" fill="#9a9996" stroke="#9a9996"/>
|
||||
<path d="m 667.000092 291.999908 h -6 l -2 -16 h 10 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(0 1 -1 0 299.999908 -598.000092)"/>
|
||||
<path d="m 661.000092 179.999908 h 6 l 2 16 h -10 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(0 1 -1 0 299.999908 -598.000092)"/>
|
||||
<path d="m 666.999051 291.998922 l -5.999272 -0.00042 l -2.001544 -15.998026 l 9.999915 0.000049 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -391.041005)"/>
|
||||
<path d="m 661.001107 180.000804 l 5.999273 0.000419 l 2.001544 15.998026 l -10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -391.041005)"/>
|
||||
<path d="m 667.000347 291.998468 l -5.999273 0.00042 l -2.002482 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -61.618176)"/>
|
||||
<path d="m 660.999745 180.00119 l 5.999273 -0.00042 l 2.002481 16.00035 l -10.003298 -0.001904 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -61.618176)"/>
|
||||
<path d="m 666.999018 291.999047 l -5.999273 -0.00042 l -2.001544 -15.998026 l 10.003298 -0.001904 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -470.382008)"/>
|
||||
<path d="m 661.001074 180.000929 l 5.999273 0.00042 l 2.001543 15.998025 l -10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -470.382008)"/>
|
||||
<path d="m 667.00038 291.998593 l -5.999273 0.00042 l -2.002481 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -627.040914)"/>
|
||||
<path d="m 660.999779 180.001315 l 5.999272 -0.00042 l 1.999099 15.998397 l -9.999915 0.000049 z m 0 0" fill="#9a9996" stroke="#9a9996" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -627.040914)"/>
|
||||
<path d="m 67 120 h -6 l -2 -16 h 10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4"/>
|
||||
<path d="m 61 8 h 6 l 2 16 h -10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4"/>
|
||||
<path d="m 667.000092 291.999908 h -6 l -2 -16 h 10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(0 1 -1 0 299.999908 -600.000092)"/>
|
||||
<path d="m 661.000092 179.999908 h 6 l 2 16 h -10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(0 1 -1 0 299.999908 -600.000092)"/>
|
||||
<path d="m 666.999051 291.998922 l -5.999272 -0.00042 l -2.001544 -15.998026 l 9.999915 0.000049 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -393.041005)"/>
|
||||
<path d="m 661.001107 180.000804 l 5.999273 0.000419 l 2.001544 15.998026 l -10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -393.041005)"/>
|
||||
<path d="m 667.000347 291.998468 l -5.999273 0.00042 l -2.002482 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -63.618176)"/>
|
||||
<path d="m 660.999745 180.00119 l 5.999273 -0.00042 l 2.002481 16.00035 l -10.003298 -0.001904 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -63.618176)"/>
|
||||
<path d="m 666.999018 291.999047 l -5.999273 -0.00042 l -2.001544 -15.998026 l 10.003298 -0.001904 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -472.382008)"/>
|
||||
<path d="m 661.001074 180.000929 l 5.999273 0.00042 l 2.001543 15.998025 l -10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -472.382008)"/>
|
||||
<path d="m 667.00038 291.998593 l -5.999273 0.00042 l -2.002481 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -629.040914)"/>
|
||||
<path d="m 660.999779 180.001315 l 5.999272 -0.00042 l 1.999099 15.998397 l -9.999915 0.000049 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -629.040914)"/>
|
||||
</g>
|
||||
<path d="m 100 238 c 0 19.882812 -16.117188 36 -36 36 s -36 -16.117188 -36 -36 s 16.117188 -36 36 -36 s 36 16.117188 36 36 z m 0 0" fill="none" stroke="url(#a)" stroke-width="24" transform="matrix(1 0 0 1 0 -172)"/>
|
||||
<path d="m 102 64 c 0 20.988281 -17.011719 38 -38 38 s -38 -17.011719 -38 -38 s 17.011719 -38 38 -38 s 38 17.011719 38 38 z m 0 0" fill="none" stroke="#f6f5f4" stroke-width="20"/>
|
||||
<path d="m -209.5 -64 c 0 14.636719 -11.863281 26.5 -26.5 26.5 s -26.5 -11.863281 -26.5 -26.5 s 11.863281 -26.5 26.5 -26.5 s 26.5 11.863281 26.5 26.5 z m 0 0" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round" stroke-width="5" transform="matrix(0 -1 -1 0 0 -172)"/>
|
||||
<path d="m 268 -64 c 0 17.671875 -14.328125 32 -32 32 s -32 -14.328125 -32 -32 s 14.328125 -32 32 -32 s 32 14.328125 32 32 z m 0 0" fill="none" stroke="url(#c)" stroke-linecap="square" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 0 -172)"/>
|
||||
<g clip-path="url(#k)" mask="url(#g)">
|
||||
<g clip-path="url(#j)" mask="url(#h)">
|
||||
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#i)"/>
|
||||
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,45 +1,453 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="64" x2="64" y1="262.5" y2="232">
|
||||
<stop offset="0" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#77767b"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 128 128"
|
||||
style="display:inline;enable-background:new"
|
||||
version="1.0"
|
||||
id="svg11300"
|
||||
height="128"
|
||||
width="128">
|
||||
<title
|
||||
id="title4162">Adwaita Icon Template</title>
|
||||
<defs
|
||||
id="defs3">
|
||||
<linearGradient
|
||||
id="linearGradient1025">
|
||||
<stop
|
||||
id="stop1021"
|
||||
offset="0"
|
||||
style="stop-color:#9a9996;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop1023"
|
||||
offset="1"
|
||||
style="stop-color:#77767b;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<radialGradient id="b" cx="-243.066583" cy="-74.599978" gradientUnits="userSpaceOnUse" r="28.266656">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#949390"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="203.999985" x2="267.999985" y1="-64" y2="-64">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#f6f5f4"/>
|
||||
<linearGradient
|
||||
id="linearGradient1069">
|
||||
<stop
|
||||
id="stop1065"
|
||||
offset="0"
|
||||
style="stop-color:#d5d3cf;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop1067"
|
||||
offset="1"
|
||||
style="stop-color:#949390;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<g stroke-width="8">
|
||||
<path d="m 67 122 h -6 l -2 -16 h 10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="m 61 10 h 6 l 2 16 h -10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="m 667.000092 291.999908 h -6 l -2 -16 h 10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0 1 -1 0 299.999908 -598.000092)"/>
|
||||
<path d="m 661.000092 179.999908 h 6 l 2 16 h -10 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0 1 -1 0 299.999908 -598.000092)"/>
|
||||
<path d="m 666.999051 291.998922 l -5.999272 -0.00042 l -2.001544 -15.998026 l 9.999915 0.000049 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -391.041005)"/>
|
||||
<path d="m 661.001107 180.000804 l 5.999273 0.000419 l 2.001544 15.998026 l -10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -391.041005)"/>
|
||||
<path d="m 667.000347 291.998468 l -5.999273 0.00042 l -2.002482 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -61.618176)"/>
|
||||
<path d="m 660.999745 180.00119 l 5.999273 -0.00042 l 2.002481 16.00035 l -10.003298 -0.001904 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -61.618176)"/>
|
||||
<path d="m 666.999018 291.999047 l -5.999273 -0.00042 l -2.001544 -15.998026 l 10.003298 -0.001904 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -470.382008)"/>
|
||||
<path d="m 661.001074 180.000929 l 5.999273 0.00042 l 2.001543 15.998025 l -10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -470.382008)"/>
|
||||
<path d="m 667.00038 291.998593 l -5.999273 0.00042 l -2.002481 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -627.040914)"/>
|
||||
<path d="m 660.999779 180.001315 l 5.999272 -0.00042 l 1.999099 15.998397 l -9.999915 0.000049 z m 0 0" fill="#9a9996" stroke="#9a9996" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -627.040914)"/>
|
||||
<path d="m 67 120 h -6 l -2 -16 h 10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="m 61 8 h 6 l 2 16 h -10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="m 667.000092 291.999908 h -6 l -2 -16 h 10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0 1 -1 0 299.999908 -600.000092)"/>
|
||||
<path d="m 661.000092 179.999908 h 6 l 2 16 h -10 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0 1 -1 0 299.999908 -600.000092)"/>
|
||||
<path d="m 666.999051 291.998922 l -5.999272 -0.00042 l -2.001544 -15.998026 l 9.999915 0.000049 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -393.041005)"/>
|
||||
<path d="m 661.001107 180.000804 l 5.999273 0.000419 l 2.001544 15.998026 l -10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.5 0.866025 -0.866025 -0.5 600.381916 -393.041005)"/>
|
||||
<path d="m 667.000347 291.998468 l -5.999273 0.00042 l -2.002482 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -63.618176)"/>
|
||||
<path d="m 660.999745 180.00119 l 5.999273 -0.00042 l 2.002481 16.00035 l -10.003298 -0.001904 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(-0.866025 0.5 -0.5 -0.866025 757.040822 -63.618176)"/>
|
||||
<path d="m 666.999018 291.999047 l -5.999273 -0.00042 l -2.001544 -15.998026 l 10.003298 -0.001904 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -472.382008)"/>
|
||||
<path d="m 661.001074 180.000929 l 5.999273 0.00042 l 2.001543 15.998025 l -10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.866025 0.5 -0.5 0.866025 -393.040914 -472.382008)"/>
|
||||
<path d="m 667.00038 291.998593 l -5.999273 0.00042 l -2.002481 -16.00035 l 10.003298 0.001905 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -629.040914)"/>
|
||||
<path d="m 660.999779 180.001315 l 5.999272 -0.00042 l 1.999099 15.998397 l -9.999915 0.000049 z m 0 0" fill="#f6f5f4" stroke="#f6f5f4" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0.5 0.866025 -0.866025 0.5 -63.618084 -629.040914)"/>
|
||||
<linearGradient
|
||||
id="linearGradient1036">
|
||||
<stop
|
||||
id="stop1032"
|
||||
offset="0"
|
||||
style="stop-color:#d5d3cf;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop1034"
|
||||
offset="1"
|
||||
style="stop-color:#f6f5f4;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
id="clipPath4929-3"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<circle
|
||||
transform="rotate(90)"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;color-interpolation:sRGB;color-interpolation-filters:linearRGB;fill:#ad7fa8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.0071969;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="circle4931-6"
|
||||
cx="908"
|
||||
cy="-2632"
|
||||
r="28.000305" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath4967-7"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<circle
|
||||
r="28.000305"
|
||||
cy="-2702"
|
||||
cx="980"
|
||||
id="circle4969-5"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;color-interpolation:sRGB;color-interpolation-filters:linearRGB;fill:#ede3ec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.0071969;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
transform="rotate(90)" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
y2="236"
|
||||
x2="96"
|
||||
y1="236"
|
||||
x1="32"
|
||||
gradientTransform="translate(171.99999,-299.99999)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1099"
|
||||
xlink:href="#linearGradient1036" />
|
||||
<radialGradient
|
||||
r="32"
|
||||
fy="-76"
|
||||
fx="-244"
|
||||
cy="-76"
|
||||
cx="-244"
|
||||
gradientTransform="matrix(0.88333331,0,0,0.88333331,-27.533334,-7.4666741)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1103"
|
||||
xlink:href="#linearGradient1069" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="232"
|
||||
x2="64"
|
||||
y1="262.5"
|
||||
x1="64"
|
||||
id="linearGradient1027"
|
||||
xlink:href="#linearGradient1025" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>GNOME Design Team</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:source />
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
<dc:title>Adwaita Icon Template</dc:title>
|
||||
<dc:subject>
|
||||
<rdf:Bag />
|
||||
</dc:subject>
|
||||
<dc:date />
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier />
|
||||
<dc:relation />
|
||||
<dc:language />
|
||||
<dc:coverage />
|
||||
<dc:description />
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(0,-172)"
|
||||
style="display:inline"
|
||||
id="layer1">
|
||||
<g
|
||||
style="display:none"
|
||||
id="layer2">
|
||||
<text
|
||||
id="context"
|
||||
y="145.34863"
|
||||
x="7.906189"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.77367783px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.64332354;enable-background:new"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.64332354"
|
||||
y="145.34863"
|
||||
x="7.906189"
|
||||
id="tspan2716">apps</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.77367783px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.64332354;enable-background:new"
|
||||
x="7.5258484"
|
||||
y="161.94572"
|
||||
id="text3021"><tspan
|
||||
style="stroke-width:0.64332354"
|
||||
id="tspan3023"
|
||||
x="7.5258484"
|
||||
y="161.94572">org.gnome.Settings</tspan></text>
|
||||
<g
|
||||
id="g12027"
|
||||
transform="matrix(7.9911709,0,0,8.0036407,-167.79091,-4846.0776)"
|
||||
style="display:inline;fill:#000000;enable-background:new" />
|
||||
<g
|
||||
transform="translate(-24.000009,23.999992)"
|
||||
style="display:inline;fill:none;fill-opacity:0.25098039;stroke:#a579b3;stroke-opacity:1;enable-background:new"
|
||||
id="g883" />
|
||||
<g
|
||||
transform="translate(-24.000009,23.999992)"
|
||||
style="display:inline;fill:none;fill-opacity:0.25098039;stroke:#a579b3;stroke-opacity:1;enable-background:new"
|
||||
id="g900" />
|
||||
<rect
|
||||
y="172"
|
||||
x="0"
|
||||
height="128"
|
||||
width="128"
|
||||
id="rect13805"
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:#f0f0f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
transform="matrix(0.25,0,0,0.25,-9.3066406e-6,224.99999)"
|
||||
id="g1168"
|
||||
style="display:inline;enable-background:new">
|
||||
<rect
|
||||
style="opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect1110"
|
||||
width="319.99979"
|
||||
height="448"
|
||||
x="96"
|
||||
y="-180"
|
||||
rx="32"
|
||||
ry="32" />
|
||||
<rect
|
||||
style="display:inline;opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1110-8"
|
||||
width="416"
|
||||
height="416"
|
||||
x="48"
|
||||
y="-164"
|
||||
rx="32"
|
||||
ry="32" />
|
||||
<rect
|
||||
style="display:inline;opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1110-8-9"
|
||||
width="448"
|
||||
height="320"
|
||||
x="32"
|
||||
y="-116"
|
||||
rx="32"
|
||||
ry="32" />
|
||||
<circle
|
||||
style="opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="path1142"
|
||||
r="240"
|
||||
cy="44"
|
||||
cx="256" />
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 100 238 c 0 19.882812 -16.117188 36 -36 36 s -36 -16.117188 -36 -36 s 16.117188 -36 36 -36 s 36 16.117188 36 36 z m 0 0" fill="none" stroke="url(#a)" stroke-width="24" transform="matrix(1 0 0 1 0 -172)"/>
|
||||
<path d="m 102 64 c 0 20.988281 -17.011719 38 -38 38 s -38 -17.011719 -38 -38 s 17.011719 -38 38 -38 s 38 17.011719 38 38 z m 0 0" fill="none" stroke="#f6f5f4" stroke-width="20"/>
|
||||
<path d="m -209.5 -64 c 0 14.636719 -11.863281 26.5 -26.5 26.5 s -26.5 -11.863281 -26.5 -26.5 s 11.863281 -26.5 26.5 -26.5 s 26.5 11.863281 26.5 26.5 z m 0 0" fill="none" stroke="url(#b)" stroke-linecap="square" stroke-linejoin="round" stroke-width="5" transform="matrix(0 -1 -1 0 0 -172)"/>
|
||||
<path d="m 268 -64 c 0 17.671875 -14.328125 32 -32 32 s -32 -14.328125 -32 -32 s 14.328125 -32 32 -32 s 32 14.328125 32 32 z m 0 0" fill="none" stroke="url(#c)" stroke-linecap="square" stroke-linejoin="round" stroke-width="8" transform="matrix(0 1 -1 0 0 -172)"/>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="layer9">
|
||||
<g
|
||||
transform="translate(140,2)"
|
||||
id="g1084"
|
||||
style="fill:#77767b">
|
||||
<rect
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="176"
|
||||
x="-88"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1068"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1070"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-88"
|
||||
y="272"
|
||||
rx="8"
|
||||
ry="8" />
|
||||
<rect
|
||||
transform="rotate(-45)"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1072"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-232.61731"
|
||||
y="53.137085"
|
||||
rx="8"
|
||||
ry="8" />
|
||||
<rect
|
||||
transform="rotate(-45)"
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="149.13708"
|
||||
x="-232.61731"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1074"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
<rect
|
||||
transform="rotate(-90)"
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="-136"
|
||||
x="-248"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1076"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
<rect
|
||||
transform="rotate(-90)"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1078"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-248"
|
||||
y="-40"
|
||||
rx="8"
|
||||
ry="8" />
|
||||
<rect
|
||||
transform="rotate(-135)"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1080"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-125.13708"
|
||||
y="-280.61731"
|
||||
rx="8"
|
||||
ry="8" />
|
||||
<rect
|
||||
transform="rotate(-135)"
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="-184.61731"
|
||||
x="-125.13708"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1082"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
</g>
|
||||
<g
|
||||
id="g1166" />
|
||||
<g
|
||||
transform="rotate(45,64,236)"
|
||||
id="g1172" />
|
||||
<g
|
||||
id="g1178"
|
||||
transform="rotate(90,64,236)" />
|
||||
<g
|
||||
transform="translate(140)"
|
||||
style="fill:#f6f5f4"
|
||||
id="g1066">
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect991-5-3"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-88"
|
||||
y="176"
|
||||
rx="8"
|
||||
ry="8" />
|
||||
<rect
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="272"
|
||||
x="-88"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1023"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
<rect
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="53.137085"
|
||||
x="-232.61731"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1029"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
transform="rotate(-45)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1031"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-232.61731"
|
||||
y="149.13708"
|
||||
rx="8"
|
||||
ry="8"
|
||||
transform="rotate(-45)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1035"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-248"
|
||||
y="-136"
|
||||
rx="8"
|
||||
ry="8"
|
||||
transform="rotate(-90)" />
|
||||
<rect
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="-40"
|
||||
x="-248"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1037"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
transform="rotate(-90)" />
|
||||
<rect
|
||||
ry="8"
|
||||
rx="8"
|
||||
y="-280.61731"
|
||||
x="-125.13708"
|
||||
height="24"
|
||||
width="24"
|
||||
id="rect1041"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
transform="rotate(-135)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.53571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="rect1043"
|
||||
width="24"
|
||||
height="24"
|
||||
x="-125.13708"
|
||||
y="-184.61731"
|
||||
rx="8"
|
||||
ry="8"
|
||||
transform="rotate(-135)" />
|
||||
</g>
|
||||
<ellipse
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:url(#linearGradient1027);stroke-width:24;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
id="ellipse1093"
|
||||
cx="64"
|
||||
cy="238"
|
||||
rx="36"
|
||||
ry="36.000008" />
|
||||
<ellipse
|
||||
ry="38.000011"
|
||||
rx="38"
|
||||
cy="236.00002"
|
||||
cx="64"
|
||||
id="path1023-6-6"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#f6f5f4;stroke-width:20.00000191;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
<circle
|
||||
transform="matrix(0,-1,-1,0,0,0)"
|
||||
r="26.5"
|
||||
cy="-64"
|
||||
cx="-236"
|
||||
id="circle1101"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient1103);stroke-width:5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<circle
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:url(#linearGradient1099);stroke-width:7.99999905;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="circle1097"
|
||||
cx="236"
|
||||
cy="-64"
|
||||
r="32"
|
||||
transform="rotate(90)" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 20 KiB |
@@ -1,13 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="64" x2="64" y1="262.5" y2="232">
|
||||
<stop offset="0" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#77767b"/>
|
||||
</linearGradient>
|
||||
<path d="m 7.480469 0.015625 h 1.066406 c 0.589844 0 1.066406 0.476563 1.066406 1.066406 v 1.066407 c 0 0.589843 -0.476562 1.066406 -1.066406 1.066406 h -1.066406 c -0.589844 0 -1.066407 -0.476563 -1.066407 -1.066406 v -1.066407 c 0 -0.589843 0.476563 -1.066406 1.066407 -1.066406 z m 0 12.796875 h 1.066406 c 0.589844 0 1.066406 0.476562 1.066406 1.070312 v 1.0625 c 0 0.59375 -0.476562 1.070313 -1.066406 1.070313 h -1.066406 c -0.589844 0 -1.066407 -0.476563 -1.066407 -1.070313 v -1.0625 c 0 -0.59375 0.476563 -1.070312 1.066407 -1.070312 z m -5.5 -10.078125 l 0.753906 -0.753906 c 0.199219 -0.199219 0.46875 -0.3125 0.753906 -0.3125 c 0.28125 0 0.554688 0.113281 0.753907 0.3125 l 0.753906 0.753906 c 0.417968 0.417969 0.417968 1.089844 0 1.507813 l -0.753906 0.753906 c -0.199219 0.203125 -0.472657 0.316406 -0.753907 0.316406 c -0.285156 0 -0.554687 -0.113281 -0.753906 -0.316406 l -0.753906 -0.753906 c -0.203125 -0.199219 -0.316407 -0.46875 -0.316407 -0.753907 c 0 -0.28125 0.113282 -0.554687 0.316407 -0.753906 z m 9.050781 9.050781 l 0.753906 -0.753906 c 0.199219 -0.199219 0.472656 -0.3125 0.753906 -0.3125 c 0.285157 0 0.554688 0.113281 0.753907 0.3125 l 0.753906 0.753906 c 0.417969 0.417969 0.417969 1.089844 0 1.507813 l -0.753906 0.753906 c -0.199219 0.203125 -0.46875 0.316406 -0.753907 0.316406 c -0.28125 0 -0.554687 -0.113281 -0.753906 -0.316406 l -0.753906 -0.753906 c -0.203125 -0.199219 -0.3125 -0.46875 -0.3125 -0.753907 c 0 -0.28125 0.109375 -0.554687 0.3125 -0.753906 z m -11.015625 -3.238281 v -1.066406 c 0 -0.589844 0.472656 -1.066407 1.066406 -1.066407 h 1.066407 c 0.589843 0 1.066406 0.476563 1.066406 1.066407 v 1.066406 c 0 0.589844 -0.476563 1.066406 -1.066406 1.066406 h -1.066407 c -0.59375 0 -1.066406 -0.476562 -1.066406 -1.066406 z m 12.796875 0 v -1.066406 c 0 -0.589844 0.476562 -1.066407 1.066406 -1.066407 h 1.066406 c 0.59375 0 1.070313 0.476563 1.070313 1.066407 v 1.066406 c 0 0.589844 -0.476563 1.066406 -1.070313 1.066406 h -1.066406 c -0.589844 0 -1.066406 -0.476562 -1.066406 -1.066406 z m -10.078125 5.5 l -0.753906 -0.753906 c -0.203125 -0.199219 -0.316407 -0.46875 -0.316407 -0.753907 c 0 -0.28125 0.113282 -0.554687 0.316407 -0.753906 l 0.753906 -0.753906 c 0.199219 -0.199219 0.46875 -0.3125 0.753906 -0.3125 c 0.28125 0 0.554688 0.113281 0.753907 0.3125 l 0.753906 0.753906 c 0.417968 0.417969 0.417968 1.089844 0 1.507813 l -0.753906 0.753906 c -0.199219 0.203125 -0.472657 0.316406 -0.753907 0.316406 c -0.285156 0 -0.554687 -0.113281 -0.753906 -0.316406 z m 9.050781 -9.050781 l -0.753906 -0.753906 c -0.203125 -0.199219 -0.3125 -0.46875 -0.3125 -0.753907 c 0 -0.28125 0.109375 -0.554687 0.3125 -0.753906 l 0.753906 -0.753906 c 0.199219 -0.199219 0.472656 -0.3125 0.753906 -0.3125 c 0.285157 0 0.554688 0.113281 0.753907 0.3125 l 0.753906 0.753906 c 0.417969 0.417969 0.417969 1.089844 0 1.507813 l -0.753906 0.753906 c -0.199219 0.203125 -0.46875 0.316406 -0.753907 0.316406 c -0.28125 0 -0.554687 -0.113281 -0.753906 -0.316406 z m 0 0" fill="#241f31"/>
|
||||
<path d="m 8.015625 1.515625 c -3.574219 0 -6.5 2.925781 -6.5 6.5 c 0 3.570313 2.925781 6.5 6.5 6.5 c 3.570313 0 6.5 -2.929687 6.5 -6.5 c 0 -3.574219 -2.929687 -6.5 -6.5 -6.5 z m 0 3 c 1.949219 0 3.5 1.546875 3.5 3.5 c 0 1.949219 -1.550781 3.5 -3.5 3.5 c -1.953125 0 -3.5 -1.550781 -3.5 -3.5 c 0 -1.953125 1.546875 -3.5 3.5 -3.5 z m 0 0" fill="#241f31"/>
|
||||
<g fill="none">
|
||||
<path d="m 100 238 c 0 19.882812 -16.117188 36 -36 36 s -36 -16.117188 -36 -36 s 16.117188 -36 36 -36 s 36 16.117188 36 36 z m 0 0" stroke="url(#a)" stroke-width="24" transform="matrix(1 0 0 1 -160 -172)"/>
|
||||
<path d="m -58 64 c 0 20.988281 -17.011719 38 -38 38 s -38 -17.011719 -38 -38 s 17.011719 -38 38 -38 s 38 17.011719 38 38 z m 0 0" stroke="#f6f5f4" stroke-width="20"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
|
||||
<g fill="#2e3436">
|
||||
<path d="M7.467 0h1.066C9.124 0 9.6.476 9.6 1.067v1.066c0 .591-.476 1.067-1.067 1.067H7.467C6.876 3.2 6.4 2.724 6.4 2.133V1.067C6.4.476 6.876 0 7.467 0zM7.467 12.8h1.066c.591 0 1.067.476 1.067 1.067v1.066C9.6 15.524 9.124 16 8.533 16H7.467c-.591 0-1.067-.476-1.067-1.067v-1.066c0-.591.476-1.067 1.067-1.067zM1.966 2.72l.754-.754a1.064 1.064 0 0 1 1.509 0l.754.754c.418.418.418 1.09 0 1.509l-.754.754a1.064 1.064 0 0 1-1.509 0l-.754-.754a1.064 1.064 0 0 1 0-1.509zM11.017 11.771l.754-.754a1.064 1.064 0 0 1 1.509 0l.754.754c.418.418.418 1.09 0 1.509l-.754.754a1.064 1.064 0 0 1-1.509 0l-.754-.754a1.064 1.064 0 0 1 0-1.509zM0 8.533V7.467C0 6.876.476 6.4 1.067 6.4h1.066c.591 0 1.067.476 1.067 1.067v1.066c0 .591-.476 1.067-1.067 1.067H1.067C.476 9.6 0 9.124 0 8.533zM12.8 8.533V7.467c0-.591.476-1.067 1.067-1.067h1.066c.591 0 1.067.476 1.067 1.067v1.066c0 .591-.476 1.067-1.067 1.067h-1.066c-.591 0-1.067-.476-1.067-1.067zM2.72 14.034l-.754-.754a1.064 1.064 0 0 1 0-1.509l.754-.754a1.064 1.064 0 0 1 1.509 0l.754.754c.418.418.418 1.09 0 1.509l-.754.754a1.064 1.064 0 0 1-1.509 0zM11.771 4.983l-.754-.754a1.064 1.064 0 0 1 0-1.509l.754-.754a1.064 1.064 0 0 1 1.509 0l.754.754c.418.418.418 1.09 0 1.509l-.754.754a1.064 1.064 0 0 1-1.509 0z" style="marker:none"/>
|
||||
<path d="M8 1.5C4.428 1.5 1.5 4.428 1.5 8s2.928 6.5 6.5 6.5 6.5-2.928 6.5-6.5S11.572 1.5 8 1.5zm0 3c1.95 0 3.5 1.55 3.5 3.5S9.95 11.5 8 11.5 4.5 9.95 4.5 8 6.05 4.5 8 4.5z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;shape-padding:0;isolation:auto;mix-blend-mode:normal;marker:none" color="#000" font-weight="400" font-family="sans-serif" white-space="normal" overflow="visible"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -2,12 +2,3 @@ install_subdir(
|
||||
'hicolor',
|
||||
install_dir : control_center_icondir
|
||||
)
|
||||
|
||||
if get_option('profile') == 'development'
|
||||
icondir = join_paths('hicolor', 'scalable', 'apps')
|
||||
install_data(
|
||||
join_paths(icondir, 'org.gnome.Settings.Devel.svg'),
|
||||
install_dir: join_paths(control_center_icondir, icondir),
|
||||
rename: 'org.gnome.Settings.svg'
|
||||
)
|
||||
endif
|
||||
|
||||
@@ -18,9 +18,9 @@ Please note we have a Code of Conduct, please follow it in all your interactions
|
||||
component: <summary>
|
||||
|
||||
A paragraph explaining the problem and its context.
|
||||
|
||||
|
||||
Another one explaining how you solved that.
|
||||
|
||||
|
||||
<link to the issue>
|
||||
```
|
||||
4. You may merge the pull request in once you have the sign-off of the maintainers, or if you
|
||||
@@ -28,8 +28,7 @@ Please note we have a Code of Conduct, please follow it in all your interactions
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
GNOME Settings is a project developed based on GNOME Code of Conduct and GitHub's community
|
||||
guidelines. You can read it below:
|
||||
GNOME Settings is a project developed based on GNOME Code of Conduct. You can read it below:
|
||||
|
||||
### Summary
|
||||
|
||||
@@ -66,142 +65,6 @@ size, disability, ethnicity, gender identity and expression, level of experience
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
### Communication Guideline
|
||||
|
||||
It is of ultimate importance to maintain a community in which everyone feels free to express
|
||||
themselves, review, and comment on each others ideas, both technical and otherwise. Correspondingly,
|
||||
an environment in which individuals are silenced, berated, or are otherwise afraid to speak up is
|
||||
unlikely to foster fruitful dialog.
|
||||
|
||||
Everyone interacting with members of the community should always keep in mind the asymmetry of
|
||||
communication: while your interaction with community members (and in particular, maintainers and
|
||||
long-term contributors) may be singular and fleeting, these members generally interact with a high
|
||||
volume of individuals each day. Before writing a comment, opening a new issue, or engaging as part
|
||||
of any forum or IRC discussion, please take a moment to appreciate that fact.
|
||||
|
||||
While communicating, it is expected that all involved participants be respectful and civil at all
|
||||
times and refrain from personal attacks.
|
||||
|
||||
#### Communication Rules
|
||||
|
||||
The following behavior will not be tolerated on any occasion:
|
||||
|
||||
* **Threats of violence**: You may not threaten violence towards others or use the site to organize,
|
||||
promote, or incite acts of real-world violence or terrorism. Think carefully about the words you
|
||||
use, the images you post, and even the software you write, and how they may be interpreted by
|
||||
others. Even if you mean something as a joke, it might not be received that way. If you think
|
||||
that someone else might interpret the content you post as a threat or as promoting violence or
|
||||
terrorism, stop. Don't post it. In extraordinary cases, we may report threats of violence to law
|
||||
enforcement if we think there may be a genuine risk of physical harm or a threat to public safety.
|
||||
|
||||
* **Hate speech and discrimination**: While it is not forbidden to broach topics such as age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience, nationality,
|
||||
personal appearance, race, religion, or sexual identity and orientation, we do not tolerate speech
|
||||
that attacks a person or group of people on the basis of who they are. When approached in an
|
||||
aggressive or insulting manner these (and other) sensitive topics can make others feel unwelcome,
|
||||
or perhaps even unsafe. While there's always the potential for misunderstandings, we expect our
|
||||
community members to remain respectful and civil when discussing sensitive topics.
|
||||
|
||||
* **Bullying and harassment**: We do not tolerate bullying, harassment, or any other means of
|
||||
habitual badgering or intimidation targeted at a specific person or group of people. In general,
|
||||
if your actions are unwanted and you cease to terminate this form of engagement, there is a good
|
||||
chance that your behavior will be classified as bullying or harassment.
|
||||
|
||||
* **Impersonation**: You may not seek to mislead others as to your identity by copying another
|
||||
person's avatar, posting content under their email address, using a similar username, or otherwise
|
||||
posing as someone else. Impersonation and identity theft is a form of harassment.
|
||||
|
||||
* **Doxxing and invasion of privacy**: Don't post other people's personal information, such as phone
|
||||
numbers, private email addresses, physical addresses, credit card numbers, Social Security/National
|
||||
Identity numbers, or passwords. Depending on the context, we may consider such behavior to be an
|
||||
invasion of privacy, with particularly egregious examples potentially escalating to the point of
|
||||
legal action, such as when the released material presents a safety risk to the subject.
|
||||
|
||||
* **Obscene content**: In essence, do not post pornography, gore, or any other depiction of violence.
|
||||
|
||||
#### General Advice
|
||||
|
||||
The following advice will help to increase the efficiency of communication with community members:
|
||||
|
||||
* Do not post "me too" comments. Use the GitLab reactions instead, e.g. “thumbs up” or “thumbs down”.
|
||||
* Avoid adding priority, time, or relevance hints if you are not involved with the development of
|
||||
the application. For example, `“This is an urgent issue”`, or `“This should be fixed now”`, or
|
||||
even `“The majority of users need this feature”`.
|
||||
* Do not use passive-aggressive communication tactics.
|
||||
* When reporting technical problems with the application, such as misbehavior or crashes, focus on
|
||||
sharing as many details as possible and avoid adding non-technical information to it.
|
||||
|
||||
An example of a **good** issue report:
|
||||
|
||||
```
|
||||
GNOME Settings crashes when opening the Wi-Fi panel with 3+ Wi-Fi adapters
|
||||
|
||||
Steps to reproduce (assuming 3+ Wi-Fi adapters are present):
|
||||
|
||||
1. Open GNOME Settings
|
||||
2. Select the Wi-Fi panel
|
||||
3. Observe the crash
|
||||
|
||||
This does not happen with 2 or less adapters. Here is a backtrace of the
|
||||
crash: backtrace.txt
|
||||
```
|
||||
|
||||
In contrast, here is an example of a **bad** issue report:
|
||||
|
||||
```
|
||||
GNOME Settings crashed while I was trying to connect to the internet. How can such
|
||||
a thing happen and nobody notice? Did you not test it before releasing it?
|
||||
|
||||
This should be fixed as quick as possible!
|
||||
```
|
||||
|
||||
* When asking for new features, try and add as much information as possible to justify its relevance,
|
||||
why should it not be implemented as an auxiliary program, what problems it would solve, and offer
|
||||
suggestions about how you think it should be implemented.
|
||||
|
||||
Example of a **good** feature request:
|
||||
|
||||
```
|
||||
GNOME Settings needs to expose IPv6 options
|
||||
|
||||
As of now, the connection editor dialog does not allow editing various IPv6
|
||||
options. This is relevant because without some of these options, it is not
|
||||
possible to have a valid IPv6 configuration and, consequently, not have access
|
||||
to various websites and services.
|
||||
|
||||
The list of missing configurations that are essential is:
|
||||
|
||||
* <Feature A>
|
||||
* <Feature B>
|
||||
|
||||
Optionally, the following configurations can also be added:
|
||||
|
||||
* <Feature C>
|
||||
* <Feature D>
|
||||
|
||||
Here is a quick sketch I have made showing how I think these options
|
||||
should be exposed as a user interface: sketch.png.
|
||||
```
|
||||
|
||||
Example of a **bad** feature request:
|
||||
|
||||
```
|
||||
Merge GNOME Tweaks in GNOME Settings
|
||||
|
||||
The options in GNOME Tweaks are absolutely essential to the majority of us
|
||||
users. Why was it not merged already? This is an urgent issue and should
|
||||
have been addressed years ago. You should allocate all your resources on
|
||||
merging those two applications.
|
||||
```
|
||||
|
||||
#### What happens if someone breaks these rules or guidelines?
|
||||
|
||||
Actions that may be taken in response to an abusive comment include but are not limited to:
|
||||
|
||||
* Content removal (when breaking any of the guidelines or rules)
|
||||
* Content blocking (when breaking any of the guidelines or rules)
|
||||
* Formal report to the Code of Conduct Committee (when breaking any of the rules)
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
|
||||
<programming-language>C</programming-language>
|
||||
|
||||
<!-- General, Multitasking -->
|
||||
<!-- General -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Georges Basile Stavracas Neto</foaf:name>
|
||||
@@ -84,6 +84,15 @@
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- User Accounts -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Ondrej Holy</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:oholy@gnome.org" />
|
||||
<gnome:userid>oholy</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- Wacom -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
|
||||
@@ -115,9 +115,9 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>info-overview</option></term>
|
||||
<term><option>info</option></term>
|
||||
|
||||
<listitem><para>The info-overview panel shows a general
|
||||
<listitem><para>The info panel shows a general
|
||||
overview of the system configuration. It also
|
||||
lets you change the default applications for
|
||||
various tasks and the handling of removable
|
||||
|
||||
114
meson.build
114
meson.build
@@ -1,8 +1,8 @@
|
||||
project(
|
||||
'gnome-control-center', 'c',
|
||||
version : '41.beta',
|
||||
version : '3.32.2',
|
||||
license : 'GPL2+',
|
||||
meson_version : '>= 0.53.0'
|
||||
meson_version : '>= 0.48.0'
|
||||
)
|
||||
|
||||
control_center_prefix = get_option('prefix')
|
||||
@@ -30,8 +30,8 @@ enable_tracing = get_option('tracing')
|
||||
|
||||
config_h = configuration_data()
|
||||
|
||||
py = import('python')
|
||||
python = py.find_installation('python3')
|
||||
py3 = import('python3')
|
||||
python = py3.find_python()
|
||||
|
||||
config_h.set_quoted('TEST_NM_PYTHON', python.path())
|
||||
|
||||
@@ -41,7 +41,6 @@ set_defines = [
|
||||
['PACKAGE', meson.project_name()],
|
||||
['PACKAGE_VERSION', meson.project_version()],
|
||||
['VERSION', meson.project_version()],
|
||||
['PROFILE', get_option('profile')],
|
||||
# i18n
|
||||
['GETTEXT_PACKAGE', control_center_gettext]
|
||||
]
|
||||
@@ -93,13 +92,11 @@ libgvc = subproject(
|
||||
default_options: [
|
||||
'static=true',
|
||||
'alsa=false',
|
||||
'package_name=' + control_center_gettext,
|
||||
'package_version=' + meson.project_version(),
|
||||
]
|
||||
)
|
||||
libgvc_dep = libgvc.get_variable('libgvc_dep')
|
||||
|
||||
libhandy_dep = dependency('libhandy-1', version: '>= 1.2.0', required: false)
|
||||
libhandy_dep = dependency('libhandy-0.0', version: '>= 0.0.9', required: false)
|
||||
if not libhandy_dep.found()
|
||||
libhandy = subproject(
|
||||
'libhandy',
|
||||
@@ -107,6 +104,7 @@ if not libhandy_dep.found()
|
||||
'examples=false',
|
||||
'glade_catalog=disabled',
|
||||
'introspection=disabled',
|
||||
'static=true',
|
||||
'tests=false',
|
||||
'vapi=false',
|
||||
]
|
||||
@@ -121,20 +119,18 @@ 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.64.0')
|
||||
gnome_desktop_dep = dependency('gnome-desktop-3.0', version: '>= 3.33.4')
|
||||
gnome_settings_dep = dependency('gnome-settings-daemon', version: '>= 3.27.90')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.53.0')
|
||||
gnome_desktop_dep = dependency('gnome-desktop-3.0', version: '>= 3.27.90')
|
||||
gnome_settings_dep = dependency('gnome-settings-daemon', version: '>= 3.25.90')
|
||||
goa_dep = dependency('goa-1.0', version: goa_req_version)
|
||||
gsettings_desktop_dep = dependency('gsettings-desktop-schemas', version: '>= 40.alpha')
|
||||
gsettings_desktop_dep = dependency('gsettings-desktop-schemas', version: '>= 3.31.0')
|
||||
libxml_dep = dependency('libxml-2.0')
|
||||
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.114')
|
||||
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.103')
|
||||
pulse_dep = dependency('libpulse', version: pulse_req_version)
|
||||
pulse_mainloop_dep = dependency('libpulse-mainloop-glib', version: pulse_req_version)
|
||||
upower_glib_dep = dependency('upower-glib', version: '>= 0.99.8')
|
||||
gudev_dep = dependency('gudev-1.0', version: '>= 232')
|
||||
x11_dep = dependency('x11')
|
||||
xi_dep = dependency('xi', version: '>= 1.2')
|
||||
epoxy_dep = dependency('epoxy')
|
||||
|
||||
m_dep = cc.find_library('m')
|
||||
|
||||
@@ -155,7 +151,7 @@ assert(cups_dep.found(), 'CUPS 1.4 or newer not found')
|
||||
# https://bugzilla.gnome.org/show_bug.cgi?id=696766
|
||||
cups_cflags = []
|
||||
if cups_dep.version().version_compare('>= 1.6')
|
||||
cups_cflags += '-D_PPD_DEPRECATED='
|
||||
cups_cflags += '-D_PPD_DEPRECATED=""'
|
||||
endif
|
||||
|
||||
# cups headers
|
||||
@@ -168,10 +164,6 @@ foreach header: check_headers
|
||||
assert(cc.has_header(header[1], args: cups_cflags), 'CUPS headers not found: ' + header[1])
|
||||
endforeach
|
||||
|
||||
config_h.set10('HAVE_CUPS_HTTPCONNECT2',
|
||||
cc.has_function('httpConnect2', dependencies: cups_dep),
|
||||
description: 'Define if httpConnect2() is available in CUPS')
|
||||
|
||||
# Optional dependency for the user accounts panel
|
||||
enable_cheese = get_option('cheese')
|
||||
if enable_cheese
|
||||
@@ -191,35 +183,26 @@ endif
|
||||
config_h.set('HAVE_IBUS', enable_ibus,
|
||||
description: 'Defined if IBus support is enabled')
|
||||
|
||||
# wayland
|
||||
enable_wayland = get_option('wayland')
|
||||
if enable_wayland
|
||||
wayland_deps = [
|
||||
dependency('gdk-wayland-3.0'),
|
||||
dependency('gudev-1.0')
|
||||
]
|
||||
endif
|
||||
config_h.set('HAVE_WAYLAND', enable_wayland,
|
||||
description: 'Define to 1 if Wayland is enabled')
|
||||
|
||||
# thunderbolt
|
||||
config_h.set10('HAVE_FN_EXPLICIT_BZERO',
|
||||
cc.has_function('explicit_bzero', prefix: '''#include <string.h>'''),
|
||||
description: 'Define if explicit_bzero is available')
|
||||
|
||||
# Snap support
|
||||
enable_snap = get_option('snap')
|
||||
if enable_snap
|
||||
snapd_glib_deps = [
|
||||
dependency('snapd-glib', version: '>= 1.57')
|
||||
]
|
||||
endif
|
||||
config_h.set('HAVE_SNAP', enable_snap,
|
||||
description: 'Define to 1 if Snap support is enabled')
|
||||
|
||||
# malcontent support
|
||||
enable_malcontent = get_option('malcontent')
|
||||
if enable_malcontent
|
||||
malcontent_dep = dependency('malcontent-0', version: '>= 0.7.0')
|
||||
config_h.set('HAVE_MALCONTENT_0_10', malcontent_dep.version().version_compare('>= 0.10.0'),
|
||||
description: 'Define to 1 if malcontent ≥ 0.10.0')
|
||||
endif
|
||||
config_h.set('HAVE_MALCONTENT', enable_malcontent,
|
||||
description: 'Define to 1 if malcontent support is enabled')
|
||||
|
||||
if host_is_linux
|
||||
# network manager
|
||||
network_manager_deps = [
|
||||
dependency('libnm', version: '>= 1.24.0'),
|
||||
dependency('libnm', version: '>= 1.10.0'),
|
||||
dependency('libnma', version: '>= 1.8.0'),
|
||||
dependency('mm-glib', version: '>= 0.7')
|
||||
]
|
||||
@@ -228,10 +211,6 @@ config_h.set('BUILD_NETWORK', host_is_linux,
|
||||
description: 'Define to 1 to build the Network panel')
|
||||
config_h.set('HAVE_NETWORK_MANAGER', host_is_linux,
|
||||
description: 'Define to 1 if NetworkManager is available')
|
||||
config_h.set('BUILD_WWAN', host_is_linux,
|
||||
description: 'Define to 1 to build the WWan panel')
|
||||
config_h.set('HAVE_WWAN', host_is_linux,
|
||||
description: 'Define to 1 if WWan is available')
|
||||
|
||||
if host_is_linux_not_s390
|
||||
# gnome-bluetooth
|
||||
@@ -259,6 +238,12 @@ config_h.set('HAVE_WACOM', host_is_linux_not_s390,
|
||||
config_h.set('BUILD_THUNDERBOLT', host_is_linux_not_s390,
|
||||
description: 'Define to 1 to build the Thunderbolt panel')
|
||||
|
||||
# Check for info panel
|
||||
gnome_session_libexecdir = get_option('gnome_session_libexecdir')
|
||||
if gnome_session_libexecdir == ''
|
||||
gnome_session_libexecdir = control_center_libexecdir
|
||||
endif
|
||||
|
||||
gnome = import('gnome')
|
||||
i18n = import('i18n')
|
||||
pkg = import('pkgconfig')
|
||||
@@ -283,10 +268,7 @@ subdir('po')
|
||||
subdir('panels')
|
||||
subdir('shell')
|
||||
subdir('search-provider')
|
||||
|
||||
if get_option('tests')
|
||||
subdir('tests')
|
||||
endif
|
||||
subdir('tests')
|
||||
|
||||
if get_option('documentation')
|
||||
subdir('man')
|
||||
@@ -297,22 +279,20 @@ configure_file(
|
||||
configuration: config_h
|
||||
)
|
||||
|
||||
summary({
|
||||
'Documentation': get_option('documentation'),
|
||||
'Tests': get_option('tests'),
|
||||
'Tracing': enable_tracing,
|
||||
'Optimized': control_center_optimized,
|
||||
})
|
||||
output = ''
|
||||
output += '\n ' + meson.project_name() + ' - ' + meson.project_version() + '\n'
|
||||
output += ' ===================================\n'
|
||||
output += ' Options \n'
|
||||
output += ' Documentation .............................. ' + get_option('documentation').to_string() + '\n'
|
||||
output += ' Tracing .................................... ' + enable_tracing.to_string() + '\n'
|
||||
output += ' gnome-session libexecdir ................... ' + gnome_session_libexecdir + '\n'
|
||||
output += ' Optimized .................................. ' + control_center_optimized.to_string() + '\n'
|
||||
output += ' Panels \n'
|
||||
output += ' GNOME Bluetooth (Bluetooth panel) .......... ' + host_is_linux_not_s390.to_string() + '\n'
|
||||
output += ' Cheese (Users panel webcam support) ........ ' + enable_cheese.to_string() + '\n'
|
||||
output += ' IBus (Region panel IBus support) ........... ' + enable_ibus.to_string() + '\n'
|
||||
output += ' NetworkManager (Network panel) ............. ' + host_is_linux.to_string() + '\n'
|
||||
output += ' Wacom (Wacom tablet panel) ................. ' + host_is_linux_not_s390.to_string() + '\n'
|
||||
output += ' Wayland .................................... ' + enable_wayland.to_string() + '\n'
|
||||
|
||||
summary({
|
||||
'GNOME Bluetooth': host_is_linux_not_s390,
|
||||
'NetworkManager': host_is_linux,
|
||||
'Wacom': host_is_linux_not_s390,
|
||||
}, section: 'Dependencies')
|
||||
|
||||
summary({
|
||||
'Cheese': enable_cheese,
|
||||
'IBus': enable_ibus,
|
||||
'Snap': enable_snap,
|
||||
'Malcontent': enable_malcontent,
|
||||
}, section: 'Optional Dependencies')
|
||||
message(output)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
option('cheese', type: 'boolean', value: true, description: 'build with cheese webcam support')
|
||||
option('documentation', type: 'boolean', value: false, description: 'build documentation')
|
||||
option('gnome_session_libexecdir', type: 'string', value: '', description: 'Directory for gnome-session\'s libexecdir')
|
||||
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: false, description: 'build with Snap support')
|
||||
option('tests', type: 'boolean', value: true, description: 'build tests')
|
||||
option('tracing', type: 'boolean', value: false, description: 'add extra debugging information')
|
||||
option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
|
||||
option('profile', type: 'combo', choices: ['default','development'], value: 'default')
|
||||
option('malcontent', type: 'boolean', value: false, description: 'build with malcontent support')
|
||||
option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
|
||||
@@ -5,7 +5,6 @@
|
||||
<file preprocess="xml-stripblanks">cc-applications-panel.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>
|
||||
<file preprocess="xml-stripblanks">cc-toggle-row.ui</file>
|
||||
<file>cc-applications-panel.css</file>
|
||||
</gresource>
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">1</property>
|
||||
@@ -30,7 +29,6 @@
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,8 +8,10 @@
|
||||
<property name="visible">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="HdyClamp">
|
||||
<object class="HdyColumn">
|
||||
<property name="visible">True</property>
|
||||
<property name="maximum_width">600</property>
|
||||
<property name="linear_growth_width">400</property>
|
||||
<property name="margin_top">32</property>
|
||||
<property name="margin_bottom">32</property>
|
||||
<property name="margin_start">12</property>
|
||||
@@ -18,7 +20,7 @@
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">1</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="empty_box">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="valign">center</property>
|
||||
@@ -53,13 +55,13 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="install_button">
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Install some…</property>
|
||||
<property name="visible">1</property>
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="halign">center</property>
|
||||
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="clicked" handler="open_software_cb"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="fill">0</property>
|
||||
@@ -67,9 +69,12 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">empty</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="settings_box">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">24</property>
|
||||
@@ -115,11 +120,11 @@
|
||||
<object class="GtkListBox" id="permission_list">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="permission_row_activated_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="row-activated" handler="permission_row_activated_cb"/>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<signal name="notify::allowed" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="notify::allowed" handler="camera_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -131,7 +136,7 @@
|
||||
<child>
|
||||
<object class="CcToggleRow" id="microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<signal name="notify::allowed" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="notify::allowed" handler="microphone_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -143,7 +148,7 @@
|
||||
<child>
|
||||
<object class="CcToggleRow" id="location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<signal name="notify::allowed" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="notify::allowed" handler="location_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -174,7 +179,7 @@
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="label" translatable="yes">Individual permissions for applications can be reviewed in the <a href="privacy">Privacy</a> Settings.</property>
|
||||
<property name="use-markup">1</property>
|
||||
<signal name="activate-link" handler="privacy_link_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="activate-link" handler="privacy_link_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -223,7 +228,7 @@
|
||||
<child>
|
||||
<object class="CcToggleRow" id="search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<signal name="notify::allowed" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="notify::allowed" handler="search_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -235,25 +240,13 @@
|
||||
<child>
|
||||
<object class="CcToggleRow" id="notification">
|
||||
<property name="title" translatable="yes">Notifications</property>
|
||||
<signal name="notify::allowed" handler="notification_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="background">
|
||||
<property name="title" translatable="yes">Run in background</property>
|
||||
<signal name="notify::allowed" handler="background_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="wallpaper">
|
||||
<property name="title" translatable="yes">Set Desktop Background</property>
|
||||
<signal name="notify::allowed" handler="wallpaper_cb" swapped="yes"/>
|
||||
<signal name="notify::allowed" handler="notification_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<signal name="notify::allowed" handler="sound_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="notify::allowed" handler="sound_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -262,12 +255,6 @@
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="shortcuts">
|
||||
<property name="title" translatable="yes">Inhibit system keyboard shortcuts</property>
|
||||
<signal name="notify::allowed" handler="shortcuts_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
@@ -326,7 +313,7 @@
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
<signal name="clicked" handler="handler_reset_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="clicked" handler="handler_reset_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -335,7 +322,7 @@
|
||||
<object class="GtkListBox" id="handler_list">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="handler_row_activated_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="row-activated" handler="handler_row_activated_cb"/>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
@@ -385,7 +372,7 @@
|
||||
<object class="GtkListBox" id="usage_list">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="storage_row_activated_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="row-activated" handler="storage_row_activated_cb"/>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="storage">
|
||||
<property name="title" translatable="yes">Storage</property>
|
||||
@@ -403,6 +390,9 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">settings</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -414,7 +404,6 @@
|
||||
<object class="GtkLabel" id="title_label">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Applications</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
@@ -423,76 +412,9 @@
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Open in Software</property>
|
||||
</object>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<object class="GtkBox" id="sidebar_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="sidebar_search_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="has-focus">True</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="margin-bottom">6</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>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="sidebar_listbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="selection-mode">browse</property>
|
||||
|
||||
<child type="placeholder">
|
||||
<object class="GtkBox" id="empty_search_placeholder">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="border_width">18</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<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="visible">True</property>
|
||||
<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="visible">True</property>
|
||||
<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>
|
||||
</child>
|
||||
<object class="GtkListBox" id="sidebar_listbox">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">browse</property>
|
||||
</object>
|
||||
|
||||
<!-- Built-in Permissions dialog -->
|
||||
@@ -512,7 +434,6 @@
|
||||
<child>
|
||||
<object class="GtkLabel" id="builtin_label">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="label">Yadda Yadda</property>
|
||||
@@ -549,7 +470,6 @@
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="label" translatable="yes">How much disk space this application is occupying with app data and caches.</property>
|
||||
@@ -597,7 +517,7 @@
|
||||
<object class="GtkButton" id="clear_cache_button">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Clear Cache…</property>
|
||||
<signal name="clicked" handler="clear_cache_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<signal name="clicked" handler="clear_cache_cb" swapped="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
|
||||
@@ -75,7 +75,6 @@ cc_applications_row_new (GAppInfo *info)
|
||||
{
|
||||
CcApplicationsRow *self;
|
||||
g_autofree gchar *key = NULL;
|
||||
GIcon *icon;
|
||||
|
||||
self = g_object_new (CC_TYPE_APPLICATIONS_ROW, NULL);
|
||||
|
||||
@@ -84,12 +83,7 @@ cc_applications_row_new (GAppInfo *info)
|
||||
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)
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (self->image), g_app_info_get_icon (info), GTK_ICON_SIZE_BUTTON);
|
||||
else
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (self->image), "application-x-executable", GTK_ICON_SIZE_BUTTON);
|
||||
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (self->image), g_app_info_get_icon (info), GTK_ICON_SIZE_BUTTON);
|
||||
gtk_label_set_label (GTK_LABEL (self->label), g_app_info_get_display_name (info));
|
||||
|
||||
return self;
|
||||
|
||||
@@ -27,10 +27,10 @@ G_BEGIN_DECLS
|
||||
#define CC_TYPE_APPLICATIONS_ROW (cc_applications_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcApplicationsRow, cc_applications_row, CC, APPLICATIONS_ROW, GtkListBoxRow)
|
||||
|
||||
CcApplicationsRow* cc_applications_row_new (GAppInfo *info);
|
||||
CcApplicationsRow *cc_applications_row_new (GAppInfo *info);
|
||||
|
||||
GAppInfo* cc_applications_row_get_info (CcApplicationsRow *row);
|
||||
GAppInfo *cc_applications_row_get_info (CcApplicationsRow *row);
|
||||
|
||||
const gchar* cc_applications_row_get_sort_key (CcApplicationsRow *row);
|
||||
const gchar *cc_applications_row_get_sort_key (CcApplicationsRow *row);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -1,316 +0,0 @@
|
||||
/* cc-snap-row.c
|
||||
*
|
||||
* Copyright 2019 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 <config.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "cc-snap-row.h"
|
||||
#include "cc-applications-resources.h"
|
||||
|
||||
struct _CcSnapRow
|
||||
{
|
||||
GtkListBoxRow parent;
|
||||
|
||||
GtkLabel *title_label;
|
||||
GtkSwitch *slot_toggle;
|
||||
GtkComboBox *slots_combo;
|
||||
GtkListStore *slots_combo_model;
|
||||
|
||||
GCancellable *cancellable;
|
||||
|
||||
SnapdPlug *plug;
|
||||
SnapdSlot *connected_slot;
|
||||
GPtrArray *slots;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcSnapRow, cc_snap_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CcSnapRow *self;
|
||||
SnapdSlot *slot;
|
||||
} ConnectData;
|
||||
|
||||
static void
|
||||
update_state (CcSnapRow *self)
|
||||
{
|
||||
gboolean have_single_option;
|
||||
GtkTreeIter iter;
|
||||
|
||||
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);
|
||||
|
||||
gtk_switch_set_active (self->slot_toggle, self->connected_slot != NULL);
|
||||
|
||||
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->slots_combo_model), &iter))
|
||||
{
|
||||
do
|
||||
{
|
||||
SnapdSlot *slot;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (self->slots_combo_model), &iter, 0, &slot, -1);
|
||||
if (slot == self->connected_slot)
|
||||
gtk_combo_box_set_active_iter (self->slots_combo, &iter);
|
||||
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->slots_combo_model), &iter));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disable_controls (CcSnapRow *self)
|
||||
{
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->slot_toggle), FALSE);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->slots_combo), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_controls (CcSnapRow *self)
|
||||
{
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->slot_toggle), TRUE);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->slots_combo), TRUE);
|
||||
}
|
||||
|
||||
static ConnectData *
|
||||
connect_data_new (CcSnapRow *self, SnapdSlot *slot)
|
||||
{
|
||||
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 void
|
||||
connect_plug (CcSnapRow *self, SnapdSlot *slot)
|
||||
{
|
||||
g_autoptr(SnapdClient) client = NULL;
|
||||
|
||||
/* already connected */
|
||||
if (self->connected_slot == slot)
|
||||
return;
|
||||
|
||||
disable_controls (self);
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
update_state (self);
|
||||
enable_controls (self);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_plug (CcSnapRow *self)
|
||||
{
|
||||
g_autoptr(SnapdClient) client = NULL;
|
||||
|
||||
/* already disconnected */
|
||||
if (self->connected_slot == NULL)
|
||||
return;
|
||||
|
||||
disable_controls (self);
|
||||
|
||||
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
|
||||
switch_changed_cb (CcSnapRow *self)
|
||||
{
|
||||
if (gtk_switch_get_active (self->slot_toggle))
|
||||
{
|
||||
if (self->slots->len == 1)
|
||||
connect_plug (self, g_ptr_array_index (self->slots, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect_plug (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
combo_changed_cb (CcSnapRow *self)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
SnapdSlot *slot = NULL;
|
||||
|
||||
if (!gtk_combo_box_get_active_iter (self->slots_combo, &iter))
|
||||
return;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (self->slots_combo_model), &iter, 0, &slot, -1);
|
||||
if (slot != NULL)
|
||||
connect_plug (self, slot);
|
||||
else
|
||||
disconnect_plug (self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_snap_row_finalize (GObject *object)
|
||||
{
|
||||
CcSnapRow *self = CC_SNAP_ROW (object);
|
||||
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->plug);
|
||||
g_clear_pointer (&self->slots, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (cc_snap_row_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_snap_row_class_init (CcSnapRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = cc_snap_row_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-snap-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSnapRow, title_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSnapRow, slot_toggle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSnapRow, slots_combo);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSnapRow, slots_combo_model);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, combo_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, switch_changed_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_snap_row_init (CcSnapRow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
CcSnapRow *
|
||||
cc_snap_row_new (GCancellable *cancellable, SnapdInterface *interface, SnapdPlug *plug, GPtrArray *slots)
|
||||
{
|
||||
CcSnapRow *self;
|
||||
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 = g_object_ref (plug);
|
||||
self->slots = g_ptr_array_ref (slots);
|
||||
|
||||
connected_slots = snapd_plug_get_connected_slots (plug);
|
||||
if (connected_slots->len > 0)
|
||||
{
|
||||
SnapdSlotRef *connected_slot_ref = g_ptr_array_index (connected_slots, 0);
|
||||
|
||||
for (int i = 0; i < slots->len; i++)
|
||||
{
|
||||
SnapdSlot *slot = g_ptr_array_index (slots, i);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (interface != NULL)
|
||||
label = snapd_interface_make_label (interface);
|
||||
else
|
||||
label = g_strdup (snapd_plug_get_interface (plug));
|
||||
gtk_label_set_label (self->title_label, 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 (int i = 0; i < slots->len; i++)
|
||||
{
|
||||
SnapdSlot *slot = g_ptr_array_index (slots, i);
|
||||
g_autofree gchar *label = NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
update_state (self);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* cc-snap-row.h
|
||||
*
|
||||
* Copyright 2019 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 <gtk/gtk.h>
|
||||
#include <snapd-glib/snapd-glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_SNAP_ROW (cc_snap_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcSnapRow, cc_snap_row, CC, SNAP_ROW, GtkListBoxRow)
|
||||
|
||||
CcSnapRow* cc_snap_row_new (GCancellable *cancellable,
|
||||
SnapdInterface *interface,
|
||||
SnapdPlug *plug,
|
||||
GPtrArray *slots);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,54 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkListStore" id="slots_combo_model">
|
||||
<columns>
|
||||
<!-- column-name slot -->
|
||||
<column type="GObject"/>
|
||||
<!-- column-name label -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<template class="CcSnapRow" parent="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="activatable">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="border-width">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="slot_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::active" handler="switch_changed_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="slots_combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">slots_combo_model</property>
|
||||
<signal name="changed" handler="combo_changed_cb" swapped="yes"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -14,7 +14,6 @@
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -4,7 +4,7 @@ Comment=Control various application permissions and settings
|
||||
Exec=gnome-control-center applications
|
||||
# FIXME
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=preferences-desktop-apps
|
||||
Icon=application-x-executable
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
@@ -13,4 +13,3 @@ Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-Acc
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
# Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=application;flatpak;permission;setting;
|
||||
X-GNOME-ControlCenter-HasSidebar=true
|
||||
@@ -38,21 +38,12 @@ sources += gnome.compile_resources(
|
||||
export : true
|
||||
)
|
||||
|
||||
deps = common_deps
|
||||
|
||||
if enable_snap
|
||||
deps += snapd_glib_deps
|
||||
sources += files('cc-snap-row.c')
|
||||
endif
|
||||
|
||||
if enable_malcontent
|
||||
deps += malcontent_dep
|
||||
endif
|
||||
cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir)
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
sources : sources,
|
||||
include_directories : [ top_inc, common_inc ],
|
||||
dependencies : deps,
|
||||
dependencies : common_deps,
|
||||
c_args : cflags
|
||||
)
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -213,7 +210,7 @@ get_flatpak_app_size (const gchar *app_id)
|
||||
return 0;
|
||||
|
||||
data = g_strstrip (data);
|
||||
|
||||
|
||||
if (g_str_has_suffix (data, "kB") || g_str_has_suffix (data, "kb"))
|
||||
factor = 1000;
|
||||
else if (g_str_has_suffix (data, "MB") || g_str_has_suffix (data, "Mb"))
|
||||
@@ -226,7 +223,7 @@ get_flatpak_app_size (const gchar *app_id)
|
||||
factor = 1024 * 1024;
|
||||
else if (g_str_has_suffix (data, "GiB") || g_str_has_suffix (data, "Gib"))
|
||||
factor = 1024 * 1024 * 1024;
|
||||
else
|
||||
else
|
||||
factor = 1;
|
||||
|
||||
val = g_ascii_strtod (data, NULL);
|
||||
@@ -234,28 +231,6 @@ get_flatpak_app_size (const gchar *app_id)
|
||||
return (guint64)(val * factor);
|
||||
}
|
||||
|
||||
guint64
|
||||
get_snap_app_size (const gchar *snap_name)
|
||||
{
|
||||
#ifdef HAVE_SNAP
|
||||
g_autoptr(SnapdClient) client = NULL;
|
||||
g_autoptr(SnapdSnap) snap = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
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 snapd_snap_get_installed_size (snap);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
get_app_id (GAppInfo *info)
|
||||
{
|
||||
|
||||
@@ -50,8 +50,6 @@ GKeyFile* get_flatpak_metadata (const gchar *app_id);
|
||||
|
||||
guint64 get_flatpak_app_size (const gchar *app_id);
|
||||
|
||||
guint64 get_snap_app_size (const gchar *snap_name);
|
||||
|
||||
gchar* get_app_id (GAppInfo *info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/control-center/background">
|
||||
<file preprocess="xml-stripblanks">cc-background-chooser.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-background-panel.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-background-preview.ui</file>
|
||||
<file>preview.css</file>
|
||||
<file preprocess="xml-stripblanks">background.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
300
panels/background/background.ui
Normal file
300
panels/background/background.ui
Normal file
@@ -0,0 +1,300 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkBox" id="background-panel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin">32</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">24</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="background-set-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="background-desktop-drawingarea">
|
||||
<property name="width_request">310</property>
|
||||
<property name="height_request">170</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Background</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">background-set-button</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="bottom-hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="slide_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">slideshow-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="strut">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label"> </property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="slide-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="background-lock-set-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="background-lock-drawingarea">
|
||||
<property name="width_request">310</property>
|
||||
<property name="height_request">170</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes" comments="To translators: This is a noun, not a verb">_Lock Screen</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">background-lock-set-button</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="bottom-hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="slide_image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">slideshow-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="strut1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label"> </property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="slide-label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="sources-liststore">
|
||||
<columns>
|
||||
<!-- column-name source-name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name source-id -->
|
||||
<column type="guint"/>
|
||||
<!-- column-name source-pointer -->
|
||||
<column type="gpointer"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkListStore" id="style-liststore">
|
||||
<columns>
|
||||
<!-- column-name name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name value -->
|
||||
<column type="gint"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes" context="background, style">Tile</col>
|
||||
<col id="1">1</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes" context="background, style">Zoom</col>
|
||||
<col id="1">5</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes" context="background, style">Center</col>
|
||||
<col id="1">2</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes" context="background, style">Scale</col>
|
||||
<col id="1">3</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes" context="background, style">Fill</col>
|
||||
<col id="1">4</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes" context="background, style">Span</col>
|
||||
<col id="1">6</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="sizegroup">
|
||||
<property name="mode">vertical</property>
|
||||
<widgets>
|
||||
<widget name="slide-label"/>
|
||||
<widget name="strut"/>
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -71,11 +71,21 @@ get_colors_dir (void)
|
||||
|
||||
static void
|
||||
bg_colors_source_add_color (BgColorsSource *self,
|
||||
GListStore *store,
|
||||
const char *color)
|
||||
GnomeDesktopThumbnailFactory *thumb_factory,
|
||||
GtkListStore *store,
|
||||
const char *color,
|
||||
GtkTreeRowReference **ret_row_ref)
|
||||
{
|
||||
CcBackgroundItemFlags flags;
|
||||
g_autoptr(CcBackgroundItem) item = NULL;
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
cairo_surface_t *surface;
|
||||
int scale_factor;
|
||||
int thumbnail_height, thumbnail_width;
|
||||
GtkTreeIter iter;
|
||||
|
||||
thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (self));
|
||||
thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (self));
|
||||
|
||||
item = cc_background_item_new (NULL);
|
||||
flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
|
||||
@@ -96,24 +106,47 @@ bg_colors_source_add_color (BgColorsSource *self,
|
||||
cc_background_item_load (item, NULL);
|
||||
|
||||
/* insert the item into the liststore */
|
||||
g_list_store_append (store, item);
|
||||
scale_factor = bg_source_get_scale_factor (BG_SOURCE (self));
|
||||
pixbuf = cc_background_item_get_thumbnail (item,
|
||||
thumb_factory,
|
||||
thumbnail_width, thumbnail_height,
|
||||
scale_factor);
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
|
||||
gtk_list_store_insert_with_values (store, &iter, 0,
|
||||
0, surface,
|
||||
1, item,
|
||||
-1);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
if (ret_row_ref)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
|
||||
*ret_row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bg_colors_source_constructed (GObject *object)
|
||||
{
|
||||
BgColorsSource *self = BG_COLORS_SOURCE (object);
|
||||
g_autoptr(GnomeDesktopThumbnailFactory) thumb_factory = NULL;
|
||||
guint i;
|
||||
GListStore *store;
|
||||
GtkListStore *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));
|
||||
thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (items); i++)
|
||||
bg_colors_source_add_color (self, store, items[i].pcolor);
|
||||
{
|
||||
bg_colors_source_add_color (self, thumb_factory, store, items[i].pcolor, NULL);
|
||||
}
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
path = get_colors_path ();
|
||||
@@ -123,7 +156,9 @@ bg_colors_source_constructed (GObject *object)
|
||||
|
||||
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]);
|
||||
{
|
||||
bg_colors_source_add_color (self, thumb_factory, store, colors[i], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +167,8 @@ bg_colors_source_add (BgColorsSource *self,
|
||||
GdkRGBA *rgba,
|
||||
GtkTreeRowReference **ret_row_ref)
|
||||
{
|
||||
GListStore *store;
|
||||
g_autoptr(GnomeDesktopThumbnailFactory) thumb_factory = NULL;
|
||||
GtkListStore *store;
|
||||
g_autofree gchar *c = NULL;
|
||||
g_auto(GStrv) colors = NULL;
|
||||
gsize len;
|
||||
@@ -146,9 +182,10 @@ bg_colors_source_add (BgColorsSource *self,
|
||||
(int)(255*rgba->green),
|
||||
(int)(255*rgba->blue));
|
||||
|
||||
thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
store = bg_source_get_liststore (BG_SOURCE (self));
|
||||
|
||||
bg_colors_source_add_color (self, store, c);
|
||||
bg_colors_source_add_color (self, thumb_factory, store, c, ret_row_ref);
|
||||
|
||||
/* Save to the keyfile */
|
||||
dir = get_colors_dir ();
|
||||
@@ -212,8 +249,8 @@ bg_colors_source_class_init (BgColorsSourceClass *klass)
|
||||
}
|
||||
|
||||
BgColorsSource *
|
||||
bg_colors_source_new (GtkWidget *widget)
|
||||
bg_colors_source_new (GtkWindow *window)
|
||||
{
|
||||
return g_object_new (BG_TYPE_COLORS_SOURCE, "widget", widget, NULL);
|
||||
return g_object_new (BG_TYPE_COLORS_SOURCE, "window", window, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _BG_COLORS_SOURCE_H
|
||||
#define _BG_COLORS_SOURCE_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "bg-source.h"
|
||||
@@ -29,10 +30,12 @@ G_BEGIN_DECLS
|
||||
#define BG_TYPE_COLORS_SOURCE (bg_colors_source_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (BgColorsSource, bg_colors_source, BG, COLORS_SOURCE, BgSource)
|
||||
|
||||
BgColorsSource *bg_colors_source_new (GtkWidget *widget);
|
||||
BgColorsSource *bg_colors_source_new (GtkWindow *window);
|
||||
|
||||
gboolean bg_colors_source_add (BgColorsSource *self,
|
||||
GdkRGBA *rgba,
|
||||
GtkTreeRowReference **ret_row_ref);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _BG_COLORS_SOURCE_H */
|
||||
|
||||
1001
panels/background/bg-pictures-source.c
Normal file
1001
panels/background/bg-pictures-source.c
Normal file
File diff suppressed because it is too large
Load Diff
50
panels/background/bg-pictures-source.h
Normal file
50
panels/background/bg-pictures-source.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* bg-pictures-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
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BG_PICTURES_SOURCE_H
|
||||
#define _BG_PICTURES_SOURCE_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "bg-source.h"
|
||||
#include "cc-background-item.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BG_TYPE_PICTURES_SOURCE (bg_pictures_source_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (BgPicturesSource, bg_pictures_source, BG, PICTURES_SOURCE, BgSource)
|
||||
|
||||
BgPicturesSource *bg_pictures_source_new (GtkWindow *window);
|
||||
char *bg_pictures_source_get_cache_path (void);
|
||||
char *bg_pictures_source_get_unique_path(const char *uri);
|
||||
gboolean bg_pictures_source_add (BgPicturesSource *bg_source,
|
||||
const char *uri,
|
||||
GtkTreeRowReference **ret_row_ref);
|
||||
gboolean bg_pictures_source_remove (BgPicturesSource *bg_source,
|
||||
const char *uri);
|
||||
gboolean bg_pictures_source_is_known (BgPicturesSource *bg_source,
|
||||
const char *uri);
|
||||
|
||||
const char * const * bg_pictures_get_support_content_types (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _BG_PICTURES_SOURCE_H */
|
||||
@@ -1,470 +0,0 @@
|
||||
/* bg-recent-source.c
|
||||
*
|
||||
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@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
|
||||
* 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
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "bg-recent-source"
|
||||
|
||||
#include "bg-recent-source.h"
|
||||
#include "cc-background-item.h"
|
||||
|
||||
#define ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_NAME "," \
|
||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED
|
||||
|
||||
struct _BgRecentSource
|
||||
{
|
||||
BgSource parent;
|
||||
|
||||
GFile *backgrounds_folder;
|
||||
GFileMonitor *monitor;
|
||||
|
||||
GCancellable *cancellable;
|
||||
GHashTable *items;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (BgRecentSource, bg_recent_source, BG_TYPE_SOURCE)
|
||||
|
||||
|
||||
static const gchar * const content_types[] = {
|
||||
"image/png",
|
||||
"image/jp2",
|
||||
"image/jpeg",
|
||||
"image/bmp",
|
||||
"image/svg+xml",
|
||||
"image/x-portable-anymap",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
sort_func (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundItem *item_a;
|
||||
CcBackgroundItem *item_b;
|
||||
guint64 modified_a;
|
||||
guint64 modified_b;
|
||||
int retval;
|
||||
|
||||
item_a = (CcBackgroundItem *) a;
|
||||
item_b = (CcBackgroundItem *) b;
|
||||
modified_a = cc_background_item_get_modified (item_a);
|
||||
modified_b = cc_background_item_get_modified (item_b);
|
||||
|
||||
retval = modified_b - modified_a;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
add_file_from_info (BgRecentSource *self,
|
||||
GFile *file,
|
||||
GFileInfo *info)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) item = NULL;
|
||||
CcBackgroundItemFlags flags = 0;
|
||||
g_autofree gchar *source_uri = NULL;
|
||||
g_autofree gchar *uri = NULL;
|
||||
GListStore *store;
|
||||
const gchar *content_type;
|
||||
guint64 mtime;
|
||||
|
||||
content_type = g_file_info_get_content_type (info);
|
||||
mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||
|
||||
if (!content_type || !g_strv_contains (content_types, content_type))
|
||||
return;
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
item = cc_background_item_new (uri);
|
||||
flags |= CC_BACKGROUND_ITEM_HAS_SHADING | CC_BACKGROUND_ITEM_HAS_PLACEMENT;
|
||||
g_object_set (G_OBJECT (item),
|
||||
"flags", flags,
|
||||
"shading", G_DESKTOP_BACKGROUND_SHADING_SOLID,
|
||||
"placement", G_DESKTOP_BACKGROUND_STYLE_ZOOM,
|
||||
"modified", mtime,
|
||||
"needs-download", FALSE,
|
||||
"source-url", source_uri,
|
||||
NULL);
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (self));
|
||||
g_list_store_insert_sorted (store, item, sort_func, self);
|
||||
|
||||
g_hash_table_insert (self->items, g_strdup (uri), g_object_ref (item));
|
||||
}
|
||||
|
||||
static void
|
||||
remove_item (BgRecentSource *self,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
GListStore *store;
|
||||
const gchar *uri;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (BG_IS_RECENT_SOURCE (self));
|
||||
g_return_if_fail (CC_IS_BACKGROUND_ITEM (item));
|
||||
|
||||
uri = cc_background_item_get_uri (item);
|
||||
store = bg_source_get_liststore (BG_SOURCE (self));
|
||||
|
||||
g_debug ("Removing wallpaper %s", uri);
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (store)); i++)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) tmp = NULL;
|
||||
|
||||
tmp = g_list_model_get_item (G_LIST_MODEL (store), i);
|
||||
|
||||
if (tmp == item)
|
||||
{
|
||||
g_list_store_remove (store, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_remove (self->items, cc_background_item_get_uri (item));
|
||||
}
|
||||
|
||||
static void
|
||||
query_info_finished_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgRecentSource *self;
|
||||
g_autoptr(GFileInfo) file_info = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GFile *file = NULL;
|
||||
|
||||
file = G_FILE (source);
|
||||
file_info = g_file_query_info_finish (file, result, &error);
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Could not get pictures file information: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
self = BG_RECENT_SOURCE (user_data);
|
||||
|
||||
g_debug ("Adding wallpaper %s (%d)",
|
||||
g_file_info_get_name (file_info),
|
||||
G_IS_FILE (self->backgrounds_folder));
|
||||
|
||||
add_file_from_info (self, file, file_info);
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_changed_cb (BgRecentSource *self,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event_type)
|
||||
{
|
||||
g_autofree gchar *uri = NULL;
|
||||
|
||||
switch (event_type)
|
||||
{
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
g_file_query_info_async (file,
|
||||
ATTRIBUTES,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
query_info_finished_cb,
|
||||
self);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
uri = g_file_get_uri (file);
|
||||
remove_item (self, g_hash_table_lookup (self->items, uri));
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
file_sort_func (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
GFileInfo *file_a = G_FILE_INFO (a);
|
||||
GFileInfo *file_b = G_FILE_INFO (b);
|
||||
guint64 modified_a, modified_b;
|
||||
|
||||
modified_a = g_file_info_get_attribute_uint64 (file_a, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||
modified_b = g_file_info_get_attribute_uint64 (file_b, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||
|
||||
return modified_b - modified_a;
|
||||
}
|
||||
|
||||
static void
|
||||
file_info_async_ready_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgRecentSource *self;
|
||||
g_autolist(GFileInfo) file_infos = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GFile *parent = NULL;
|
||||
GList *l;
|
||||
|
||||
file_infos = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source),
|
||||
result,
|
||||
&error);
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Could not get pictures file information: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
self = BG_RECENT_SOURCE (user_data);
|
||||
parent = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source));
|
||||
|
||||
file_infos = g_list_sort (file_infos, file_sort_func);
|
||||
|
||||
for (l = file_infos; l; l = l->next)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
GFileInfo *info;
|
||||
|
||||
info = l->data;
|
||||
file = g_file_get_child (parent, g_file_info_get_name (info));
|
||||
|
||||
g_debug ("Found recent wallpaper %s", g_file_info_get_name (info));
|
||||
|
||||
add_file_from_info (self, file, info);
|
||||
}
|
||||
|
||||
g_file_enumerator_close (G_FILE_ENUMERATOR (source), self->cancellable, &error);
|
||||
|
||||
if (error)
|
||||
g_warning ("Error closing file enumerator: %s", error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
enumerate_children_finished_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgRecentSource *self;
|
||||
g_autoptr(GFileEnumerator) enumerator = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
enumerator = g_file_enumerate_children_finish (G_FILE (source), result, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Could not fill pictures source: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
self = BG_RECENT_SOURCE (user_data);
|
||||
g_file_enumerator_next_files_async (enumerator,
|
||||
G_MAXINT,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
file_info_async_ready_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
load_backgrounds (BgRecentSource *self)
|
||||
{
|
||||
g_autofree gchar *backgrounds_path = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (!g_file_make_directory_with_parents (self->backgrounds_folder, self->cancellable, &error) &&
|
||||
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
|
||||
{
|
||||
g_critical ("Failed to create local background directory: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
backgrounds_path = g_file_get_path (self->backgrounds_folder);
|
||||
g_debug ("Enumerating wallpapers under %s", backgrounds_path);
|
||||
|
||||
g_file_enumerate_children_async (self->backgrounds_folder,
|
||||
ATTRIBUTES,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
enumerate_children_finished_cb,
|
||||
self);
|
||||
|
||||
self->monitor = g_file_monitor_directory (self->backgrounds_folder,
|
||||
G_FILE_MONITOR_WATCH_MOVES,
|
||||
self->cancellable,
|
||||
&error);
|
||||
|
||||
if (!self->monitor)
|
||||
{
|
||||
g_critical ("Failed to monitor background directory: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
g_signal_connect_object (self->monitor, "changed", G_CALLBACK (on_file_changed_cb), self, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static void
|
||||
on_file_copied_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(BgRecentSource) self = BG_RECENT_SOURCE (user_data);
|
||||
g_autofree gchar *original_file = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_file_copy_finish (G_FILE (source), result, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_critical ("Failed to copy file: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
original_file = g_file_get_path (G_FILE (source));
|
||||
g_debug ("Successfully copied wallpaper: %s", original_file);
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_deleted_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(BgRecentSource) self = BG_RECENT_SOURCE (user_data);
|
||||
g_autofree gchar *original_file = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_file_delete_finish (G_FILE (source), result, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_critical ("Failed to delete wallpaper: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
original_file = g_file_get_path (G_FILE (source));
|
||||
g_debug ("Successfully deleted wallpaper: %s", original_file);
|
||||
}
|
||||
|
||||
/* GObject overrides */
|
||||
|
||||
static void
|
||||
bg_recent_source_finalize (GObject *object)
|
||||
{
|
||||
BgRecentSource *self = (BgRecentSource *)object;
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->monitor);
|
||||
|
||||
G_OBJECT_CLASS (bg_recent_source_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
bg_recent_source_class_init (BgRecentSourceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = bg_recent_source_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
bg_recent_source_init (BgRecentSource *self)
|
||||
{
|
||||
g_autofree gchar *backgrounds_path = NULL;
|
||||
|
||||
backgrounds_path = g_build_filename (g_get_user_data_dir (), "backgrounds", NULL);
|
||||
|
||||
self->items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
self->cancellable = g_cancellable_new ();
|
||||
self->backgrounds_folder = g_file_new_for_path (backgrounds_path);
|
||||
|
||||
load_backgrounds (self);
|
||||
}
|
||||
|
||||
BgRecentSource*
|
||||
bg_recent_source_new (GtkWidget *widget)
|
||||
{
|
||||
return g_object_new (BG_TYPE_RECENT_SOURCE,
|
||||
"widget", widget,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
bg_recent_source_add_file (BgRecentSource *self,
|
||||
const gchar *path)
|
||||
{
|
||||
g_autoptr(GDateTime) now = NULL;
|
||||
g_autofree gchar *destination_name = NULL;
|
||||
g_autofree gchar *formatted_now = NULL;
|
||||
g_autofree gchar *basename = NULL;
|
||||
g_autoptr(GFile) destination = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
|
||||
g_return_if_fail (BG_IS_RECENT_SOURCE (self));
|
||||
g_return_if_fail (path && *path);
|
||||
|
||||
g_debug ("Importing wallpaper %s", path);
|
||||
|
||||
now = g_date_time_new_now_local ();
|
||||
formatted_now = g_date_time_format (now, "%Y-%m-%d-%H-%M-%S");
|
||||
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
basename = g_file_get_basename (file);
|
||||
destination_name = g_strdup_printf ("%s-%s", formatted_now, basename);
|
||||
destination = g_file_get_child (self->backgrounds_folder, destination_name);
|
||||
|
||||
g_file_copy_async (file,
|
||||
destination,
|
||||
G_FILE_COPY_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
NULL, NULL,
|
||||
on_file_copied_cb,
|
||||
g_object_ref (self));
|
||||
}
|
||||
|
||||
void
|
||||
bg_recent_source_remove_item (BgRecentSource *self,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
const gchar *uri;
|
||||
|
||||
g_return_if_fail (BG_IS_RECENT_SOURCE (self));
|
||||
g_return_if_fail (CC_IS_BACKGROUND_ITEM (item));
|
||||
|
||||
uri = cc_background_item_get_uri (item);
|
||||
file = g_file_new_for_uri (uri);
|
||||
|
||||
g_file_delete_async (file,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_file_deleted_cb,
|
||||
g_object_ref (self));
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* bg-recent-source.h
|
||||
*
|
||||
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@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
|
||||
* 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 "bg-source.h"
|
||||
#include "cc-background-item.h"
|
||||
|
||||
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 (GtkWidget *widget);
|
||||
|
||||
void bg_recent_source_add_file (BgRecentSource *self,
|
||||
const gchar *path);
|
||||
|
||||
void bg_recent_source_remove_item (BgRecentSource *self,
|
||||
CcBackgroundItem *item);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -23,14 +23,13 @@
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#define THUMBNAIL_WIDTH 154
|
||||
#define THUMBNAIL_WIDTH 256
|
||||
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
GListStore *store;
|
||||
GtkWidget *widget;
|
||||
GtkListStore *store;
|
||||
GtkWidget *window;
|
||||
gint thumbnail_height;
|
||||
gint thumbnail_width;
|
||||
} BgSourcePrivate;
|
||||
@@ -40,7 +39,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (BgSource, bg_source, G_TYPE_OBJECT)
|
||||
enum
|
||||
{
|
||||
PROP_LISTSTORE = 1,
|
||||
PROP_WIDGET
|
||||
PROP_WINDOW
|
||||
};
|
||||
|
||||
|
||||
@@ -53,10 +52,10 @@ bg_source_calculate_thumbnail_dimensions (BgSource *source)
|
||||
priv->thumbnail_height = THUMBNAIL_HEIGHT;
|
||||
priv->thumbnail_width = THUMBNAIL_WIDTH;
|
||||
|
||||
if (priv->widget == NULL)
|
||||
if (priv->window == NULL)
|
||||
return;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (priv->widget);
|
||||
scale_factor = gtk_widget_get_scale_factor (priv->window);
|
||||
if (scale_factor > 1)
|
||||
{
|
||||
priv->thumbnail_height *= scale_factor;
|
||||
@@ -102,8 +101,8 @@ bg_source_set_property (GObject *object,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_WIDGET:
|
||||
priv->widget = GTK_WIDGET (g_value_get_object (value));
|
||||
case PROP_WINDOW:
|
||||
priv->window = GTK_WIDGET (g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -117,7 +116,6 @@ 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);
|
||||
@@ -137,27 +135,26 @@ bg_source_class_init (BgSourceClass *klass)
|
||||
pspec = g_param_spec_object ("liststore",
|
||||
"Liststore",
|
||||
"Liststore used in the source",
|
||||
G_TYPE_LIST_STORE,
|
||||
GTK_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,
|
||||
pspec = g_param_spec_object ("window",
|
||||
"Window",
|
||||
"Toplevel window used to view the source",
|
||||
GTK_TYPE_WINDOW,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_WIDGET, pspec);
|
||||
g_object_class_install_property (object_class, PROP_WINDOW, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
priv->store = gtk_list_store_new (3, CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_OBJECT, G_TYPE_STRING);
|
||||
}
|
||||
|
||||
GListStore*
|
||||
GtkListStore*
|
||||
bg_source_get_liststore (BgSource *source)
|
||||
{
|
||||
BgSourcePrivate *priv;
|
||||
@@ -176,7 +173,7 @@ bg_source_get_scale_factor (BgSource *source)
|
||||
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);
|
||||
return gtk_widget_get_scale_factor (priv->window);
|
||||
}
|
||||
|
||||
gint
|
||||
@@ -200,14 +197,3 @@ bg_source_get_thumbnail_width (BgSource *source)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _BG_SOURCE_H
|
||||
#define _BG_SOURCE_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -33,7 +33,7 @@ struct _BgSourceClass
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GListStore* bg_source_get_liststore (BgSource *source);
|
||||
GtkListStore* bg_source_get_liststore (BgSource *source);
|
||||
|
||||
gint bg_source_get_scale_factor (BgSource *source);
|
||||
|
||||
@@ -41,6 +41,6 @@ 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
|
||||
|
||||
#endif /* _BG_SOURCE_H */
|
||||
|
||||
@@ -25,11 +25,13 @@
|
||||
#include "cc-background-xml.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
struct _BgWallpapersSource
|
||||
{
|
||||
BgSource parent_instance;
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
CcBackgroundXml *xml;
|
||||
};
|
||||
|
||||
@@ -40,15 +42,38 @@ load_wallpapers (gchar *key,
|
||||
CcBackgroundItem *item,
|
||||
BgWallpapersSource *source)
|
||||
{
|
||||
GListStore *store = bg_source_get_liststore (BG_SOURCE (source));
|
||||
GtkTreeIter iter;
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
GtkListStore *store = bg_source_get_liststore (BG_SOURCE (source));
|
||||
cairo_surface_t *surface;
|
||||
gboolean deleted;
|
||||
gint scale_factor;
|
||||
gint thumbnail_height;
|
||||
gint thumbnail_width;
|
||||
|
||||
g_object_get (G_OBJECT (item), "is-deleted", &deleted, NULL);
|
||||
|
||||
if (deleted)
|
||||
return;
|
||||
|
||||
g_list_store_append (store, item);
|
||||
gtk_list_store_append (store, &iter);
|
||||
|
||||
scale_factor = bg_source_get_scale_factor (BG_SOURCE (source));
|
||||
thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (source));
|
||||
thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (source));
|
||||
pixbuf = cc_background_item_get_thumbnail (item, source->thumb_factory,
|
||||
thumbnail_width, thumbnail_height,
|
||||
scale_factor);
|
||||
if (pixbuf == NULL)
|
||||
return;
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
|
||||
gtk_list_store_set (store, &iter,
|
||||
0, surface,
|
||||
1, item,
|
||||
2, cc_background_item_get_name (item),
|
||||
-1);
|
||||
g_clear_pointer (&surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -62,8 +87,9 @@ list_load_cb (GObject *source_object,
|
||||
}
|
||||
|
||||
static void
|
||||
item_added (BgWallpapersSource *self,
|
||||
CcBackgroundItem *item)
|
||||
item_added (CcBackgroundXml *xml,
|
||||
CcBackgroundItem *item,
|
||||
BgWallpapersSource *self)
|
||||
{
|
||||
load_wallpapers (NULL, item, self);
|
||||
}
|
||||
@@ -96,8 +122,8 @@ bg_wallpapers_source_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (bg_wallpapers_source_parent_class)->constructed (object);
|
||||
|
||||
g_signal_connect_object (G_OBJECT (self->xml), "added",
|
||||
G_CALLBACK (item_added), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (G_OBJECT (self->xml), "added",
|
||||
G_CALLBACK (item_added), self);
|
||||
|
||||
/* Try adding the default background first */
|
||||
load_default_bg (self);
|
||||
@@ -110,6 +136,7 @@ bg_wallpapers_source_dispose (GObject *object)
|
||||
{
|
||||
BgWallpapersSource *self = BG_WALLPAPERS_SOURCE (object);
|
||||
|
||||
g_clear_object (&self->thumb_factory);
|
||||
g_clear_object (&self->xml);
|
||||
|
||||
G_OBJECT_CLASS (bg_wallpapers_source_parent_class)->dispose (object);
|
||||
@@ -118,6 +145,8 @@ bg_wallpapers_source_dispose (GObject *object)
|
||||
static void
|
||||
bg_wallpapers_source_init (BgWallpapersSource *self)
|
||||
{
|
||||
self->thumb_factory =
|
||||
gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
self->xml = cc_background_xml_new ();
|
||||
}
|
||||
|
||||
@@ -131,8 +160,8 @@ bg_wallpapers_source_class_init (BgWallpapersSourceClass *klass)
|
||||
}
|
||||
|
||||
BgWallpapersSource *
|
||||
bg_wallpapers_source_new (GtkWidget *widget)
|
||||
bg_wallpapers_source_new (GtkWindow *window)
|
||||
{
|
||||
return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, "widget", widget, NULL);
|
||||
return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, "window", window, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _BG_WALLPAPERS_SOURCE_H
|
||||
#define _BG_WALLPAPERS_SOURCE_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "bg-source.h"
|
||||
@@ -29,6 +31,8 @@ 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 (GtkWidget *widget);
|
||||
BgWallpapersSource *bg_wallpapers_source_new (GtkWindow *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _BG_WALLPAPERS_SOURCE_H */
|
||||
|
||||
608
panels/background/cc-background-chooser-dialog.c
Normal file
608
panels/background/cc-background-chooser-dialog.c
Normal file
@@ -0,0 +1,608 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "cc-background-chooser-dialog.h"
|
||||
#include "bg-wallpapers-source.h"
|
||||
#include "bg-pictures-source.h"
|
||||
#include "bg-colors-source.h"
|
||||
|
||||
#include "cc-background-item.h"
|
||||
#include "cc-background-xml.h"
|
||||
|
||||
#define WP_PATH_ID "org.gnome.desktop.background"
|
||||
#define WP_URI_KEY "picture-uri"
|
||||
#define WP_OPTIONS_KEY "picture-options"
|
||||
#define WP_SHADING_KEY "color-shading-type"
|
||||
#define WP_PCOLOR_KEY "primary-color"
|
||||
#define WP_SCOLOR_KEY "secondary-color"
|
||||
|
||||
enum
|
||||
{
|
||||
SOURCE_WALLPAPERS,
|
||||
SOURCE_PICTURES,
|
||||
SOURCE_COLORS,
|
||||
};
|
||||
|
||||
struct _CcBackgroundChooserDialog
|
||||
{
|
||||
GtkDialog parent_instance;
|
||||
|
||||
GtkListStore *sources;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *pictures_stack;
|
||||
|
||||
BgWallpapersSource *wallpapers_source;
|
||||
BgPicturesSource *pictures_source;
|
||||
BgColorsSource *colors_source;
|
||||
|
||||
GtkTreeRowReference *item_to_focus;
|
||||
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
|
||||
GCancellable *copy_cancellable;
|
||||
|
||||
GtkWidget *spinner;
|
||||
|
||||
gulong row_inserted_id;
|
||||
gulong row_deleted_id;
|
||||
gulong row_modified_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundChooserDialog, cc_background_chooser_dialog, GTK_TYPE_DIALOG)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
URI_LIST,
|
||||
COLOR
|
||||
};
|
||||
|
||||
static const GtkTargetEntry color_targets[] =
|
||||
{
|
||||
{ "application/x-color", 0, COLOR }
|
||||
};
|
||||
|
||||
static void
|
||||
cc_background_chooser_dialog_realize (GtkWidget *widget)
|
||||
{
|
||||
CcBackgroundChooserDialog *chooser = CC_BACKGROUND_CHOOSER_DIALOG (widget);
|
||||
GtkWindow *parent;
|
||||
|
||||
parent = gtk_window_get_transient_for (GTK_WINDOW (chooser));
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
gtk_window_set_default_size (GTK_WINDOW (chooser), -1, 550);
|
||||
}
|
||||
else
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
gtk_window_get_size (parent, &width, &height);
|
||||
gtk_window_set_default_size (GTK_WINDOW (chooser), -1, (gint) (0.66 * height));
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (cc_background_chooser_dialog_parent_class)->realize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_chooser_dialog_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundChooserDialog *chooser = CC_BACKGROUND_CHOOSER_DIALOG (object);
|
||||
|
||||
if (chooser->copy_cancellable)
|
||||
{
|
||||
/* cancel any copy operation */
|
||||
g_cancellable_cancel (chooser->copy_cancellable);
|
||||
|
||||
g_clear_object (&chooser->copy_cancellable);
|
||||
}
|
||||
|
||||
g_clear_pointer (&chooser->item_to_focus, gtk_tree_row_reference_free);
|
||||
g_clear_object (&chooser->pictures_source);
|
||||
g_clear_object (&chooser->colors_source);
|
||||
g_clear_object (&chooser->wallpapers_source);
|
||||
g_clear_object (&chooser->thumb_factory);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_chooser_dialog_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
get_visible_view (CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GtkWidget *visible;
|
||||
GtkWidget *icon_view = NULL;
|
||||
|
||||
visible = gtk_stack_get_visible_child (GTK_STACK (chooser->stack));
|
||||
if (GTK_IS_STACK (visible))
|
||||
{
|
||||
GtkWidget *sw;
|
||||
|
||||
sw = gtk_stack_get_child_by_name (GTK_STACK (visible), "view");
|
||||
icon_view = gtk_bin_get_child (GTK_BIN (sw));
|
||||
}
|
||||
else if (GTK_IS_SCROLLED_WINDOW (visible))
|
||||
{
|
||||
icon_view = gtk_bin_get_child (GTK_BIN (visible));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return icon_view;
|
||||
}
|
||||
|
||||
static void
|
||||
possibly_show_empty_pictures_box (GtkTreeModel *model,
|
||||
CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (gtk_tree_model_get_iter_first (model, &iter))
|
||||
{
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (chooser->pictures_stack), "view");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (chooser->pictures_stack), "empty");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_source_modified_cb (GtkTreeModel *tree_model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundChooserDialog *chooser = user_data;
|
||||
GtkTreePath *to_focus_path;
|
||||
GtkWidget *icon_view;
|
||||
|
||||
if (chooser->item_to_focus == NULL)
|
||||
return;
|
||||
|
||||
to_focus_path = gtk_tree_row_reference_get_path (chooser->item_to_focus);
|
||||
|
||||
if (gtk_tree_path_compare (to_focus_path, path) != 0)
|
||||
goto out;
|
||||
|
||||
/* Change source */
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (chooser->stack), "pictures");
|
||||
|
||||
/* And select the newly added item */
|
||||
icon_view = get_visible_view (chooser);
|
||||
gtk_icon_view_select_path (GTK_ICON_VIEW (icon_view), to_focus_path);
|
||||
gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (icon_view),
|
||||
to_focus_path, TRUE, 1.0, 1.0);
|
||||
g_clear_pointer (&chooser->item_to_focus, gtk_tree_row_reference_free);
|
||||
|
||||
out:
|
||||
gtk_tree_path_free (to_focus_path);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
on_source_added_cb (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data)
|
||||
{
|
||||
possibly_show_empty_pictures_box (model, CC_BACKGROUND_CHOOSER_DIALOG (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
on_source_removed_cb (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
gpointer user_data)
|
||||
{
|
||||
possibly_show_empty_pictures_box (model, CC_BACKGROUND_CHOOSER_DIALOG (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
monitor_pictures_model (CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
|
||||
model = GTK_TREE_MODEL (bg_source_get_liststore (BG_SOURCE (chooser->pictures_source)));
|
||||
|
||||
g_signal_connect (model, "row-inserted", G_CALLBACK (on_source_added_cb), chooser);
|
||||
g_signal_connect (model, "row-deleted", G_CALLBACK (on_source_removed_cb), chooser);
|
||||
g_signal_connect (model, "row-changed", G_CALLBACK (on_source_modified_cb), chooser);
|
||||
|
||||
possibly_show_empty_pictures_box (model, chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
on_visible_child_notify (CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GtkWidget *icon_view;
|
||||
|
||||
icon_view = get_visible_view (chooser);
|
||||
gtk_icon_view_unselect_all (GTK_ICON_VIEW (icon_view));
|
||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_OK, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_selection_changed (GtkIconView *icon_view,
|
||||
CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
list = gtk_icon_view_get_selected_items (icon_view);
|
||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
|
||||
GTK_RESPONSE_OK,
|
||||
(list != NULL));
|
||||
|
||||
g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
|
||||
}
|
||||
|
||||
static void
|
||||
on_item_activated (GtkIconView *icon_view,
|
||||
GtkTreePath *path,
|
||||
CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
add_custom_wallpaper (CcBackgroundChooserDialog *chooser,
|
||||
const char *uri)
|
||||
{
|
||||
g_clear_pointer (&chooser->item_to_focus, gtk_tree_row_reference_free);
|
||||
|
||||
bg_pictures_source_add (chooser->pictures_source, uri, &chooser->item_to_focus);
|
||||
/* and wait for the item to get added */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_background_panel_drag_color (CcBackgroundChooserDialog *chooser,
|
||||
GtkSelectionData *data)
|
||||
{
|
||||
gint length;
|
||||
guint16 *dropped;
|
||||
GdkRGBA rgba;
|
||||
GtkTreeRowReference *row_ref;
|
||||
GtkTreePath *to_focus_path;
|
||||
GtkWidget *icon_view;
|
||||
|
||||
length = gtk_selection_data_get_length (data);
|
||||
|
||||
if (length < 0)
|
||||
return FALSE;
|
||||
|
||||
if (length != 8)
|
||||
{
|
||||
g_warning ("%s: Received invalid color data", G_STRFUNC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dropped = (guint16 *) gtk_selection_data_get_data (data);
|
||||
rgba.red = dropped[0] / 65535.;
|
||||
rgba.green = dropped[1] / 65535.;
|
||||
rgba.blue = dropped[2] / 65535.;
|
||||
rgba.alpha = dropped[3] / 65535.;
|
||||
|
||||
if (bg_colors_source_add (chooser->colors_source, &rgba, &row_ref) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
/* Change source */
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (chooser->stack), "colors");
|
||||
|
||||
/* And select the newly added item */
|
||||
to_focus_path = gtk_tree_row_reference_get_path (row_ref);
|
||||
icon_view = get_visible_view (chooser);
|
||||
gtk_icon_view_select_path (GTK_ICON_VIEW (icon_view), to_focus_path);
|
||||
gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (icon_view),
|
||||
to_focus_path, TRUE, 1.0, 1.0);
|
||||
gtk_tree_row_reference_free (row_ref);
|
||||
gtk_tree_path_free (to_focus_path);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_drag_items (GtkWidget *widget,
|
||||
GdkDragContext *context, gint x, gint y,
|
||||
GtkSelectionData *data, guint info, guint time,
|
||||
CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
gint i;
|
||||
char *uri;
|
||||
g_auto(GStrv) uris = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (info == COLOR)
|
||||
{
|
||||
ret = cc_background_panel_drag_color (chooser, data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
uris = gtk_selection_data_get_uris (data);
|
||||
if (!uris)
|
||||
goto out;
|
||||
|
||||
for (i = 0; uris[i] != NULL; i++)
|
||||
{
|
||||
uri = uris[i];
|
||||
if (!bg_pictures_source_is_known (chooser->pictures_source, uri))
|
||||
{
|
||||
add_custom_wallpaper (chooser, uri);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
gtk_drag_finish (context, ret, FALSE, time);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_view (CcBackgroundChooserDialog *chooser, GtkTreeModel *model)
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
GtkWidget *icon_view;
|
||||
GtkWidget *sw;
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_show (sw);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
|
||||
icon_view = gtk_icon_view_new ();
|
||||
gtk_widget_show (icon_view);
|
||||
gtk_icon_view_set_model (GTK_ICON_VIEW (icon_view), model);
|
||||
gtk_widget_set_hexpand (icon_view, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (sw), icon_view);
|
||||
g_signal_connect (icon_view, "selection-changed", G_CALLBACK (on_selection_changed), chooser);
|
||||
g_signal_connect (icon_view, "item-activated", G_CALLBACK (on_item_activated), chooser);
|
||||
|
||||
gtk_icon_view_set_columns (GTK_ICON_VIEW (icon_view), 3);
|
||||
|
||||
renderer = gtk_cell_renderer_pixbuf_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (icon_view),
|
||||
renderer,
|
||||
FALSE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (icon_view),
|
||||
renderer,
|
||||
"surface", 0,
|
||||
NULL);
|
||||
|
||||
return sw;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_chooser_dialog_constructed (GObject *object)
|
||||
{
|
||||
CcBackgroundChooserDialog *chooser = CC_BACKGROUND_CHOOSER_DIALOG (object);
|
||||
GtkListStore *model;
|
||||
GtkWidget *sw;
|
||||
|
||||
G_OBJECT_CLASS (cc_background_chooser_dialog_parent_class)->constructed (object);
|
||||
|
||||
model = bg_source_get_liststore (BG_SOURCE (chooser->wallpapers_source));
|
||||
sw = create_view (chooser, GTK_TREE_MODEL (model));
|
||||
gtk_widget_show (sw);
|
||||
gtk_stack_add_titled (GTK_STACK (chooser->stack), sw, "wallpapers", _("Wallpapers"));
|
||||
gtk_container_child_set (GTK_CONTAINER (chooser->stack), sw, "position", 0, NULL);
|
||||
|
||||
model = bg_source_get_liststore (BG_SOURCE (chooser->pictures_source));
|
||||
sw = create_view (chooser, GTK_TREE_MODEL (model));
|
||||
gtk_widget_show (sw);
|
||||
gtk_stack_add_named (GTK_STACK (chooser->pictures_stack), sw, "view");
|
||||
|
||||
model = bg_source_get_liststore (BG_SOURCE (chooser->colors_source));
|
||||
sw = create_view (chooser, GTK_TREE_MODEL (model));
|
||||
gtk_widget_show (sw);
|
||||
gtk_stack_add_titled (GTK_STACK (chooser->stack), sw, "colors", _("Colors"));
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (chooser->stack), "wallpapers");
|
||||
monitor_pictures_model (chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GtkWidget *empty_pictures_box;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *headerbar;
|
||||
GtkWidget *img;
|
||||
GtkWidget *labels_grid;
|
||||
GtkWidget *label;
|
||||
GtkWidget *switcher;
|
||||
GtkStyleContext *context;
|
||||
g_autofree gchar *markup = NULL;
|
||||
g_autofree gchar *markup2 = NULL;
|
||||
g_autofree gchar *href = NULL;
|
||||
const gchar *pictures_dir;
|
||||
g_autofree gchar *pictures_dir_basename = NULL;
|
||||
g_autofree gchar *pictures_dir_uri = NULL;
|
||||
GtkTargetList *target_list;
|
||||
|
||||
chooser->wallpapers_source = bg_wallpapers_source_new (GTK_WINDOW (chooser));
|
||||
chooser->pictures_source = bg_pictures_source_new (GTK_WINDOW (chooser));
|
||||
chooser->colors_source = bg_colors_source_new (GTK_WINDOW (chooser));
|
||||
|
||||
gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
|
||||
gtk_window_set_resizable (GTK_WINDOW (chooser), FALSE);
|
||||
/* translators: This is the title of the wallpaper chooser dialog. */
|
||||
gtk_window_set_title (GTK_WINDOW (chooser), _("Select Background"));
|
||||
|
||||
vbox = gtk_dialog_get_content_area (GTK_DIALOG (chooser));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
|
||||
|
||||
chooser->stack = gtk_stack_new ();
|
||||
gtk_widget_show (chooser->stack);
|
||||
gtk_stack_set_homogeneous (GTK_STACK (chooser->stack), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), chooser->stack);
|
||||
|
||||
/* Add drag and drop support for bg images */
|
||||
gtk_drag_dest_set (chooser->stack, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
|
||||
target_list = gtk_target_list_new (NULL, 0);
|
||||
gtk_target_list_add_uri_targets (target_list, URI_LIST);
|
||||
gtk_target_list_add_table (target_list, color_targets, 1);
|
||||
gtk_drag_dest_set_target_list (chooser->stack, target_list);
|
||||
gtk_target_list_unref (target_list);
|
||||
g_signal_connect (chooser->stack, "drag-data-received", G_CALLBACK (cc_background_panel_drag_items), chooser);
|
||||
|
||||
headerbar = gtk_dialog_get_header_bar (GTK_DIALOG (chooser));
|
||||
|
||||
switcher = gtk_stack_switcher_new ();
|
||||
gtk_widget_show (switcher);
|
||||
gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER (switcher), GTK_STACK (chooser->stack));
|
||||
gtk_header_bar_set_custom_title (GTK_HEADER_BAR (headerbar), switcher);
|
||||
|
||||
chooser->pictures_stack = gtk_stack_new ();
|
||||
gtk_widget_show (chooser->pictures_stack);
|
||||
gtk_stack_set_homogeneous (GTK_STACK (chooser->pictures_stack), TRUE);
|
||||
gtk_stack_add_titled (GTK_STACK (chooser->stack), chooser->pictures_stack, "pictures", _("Pictures"));
|
||||
|
||||
empty_pictures_box = gtk_grid_new ();
|
||||
gtk_widget_show (empty_pictures_box);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (empty_pictures_box), 12);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (empty_pictures_box),
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
context = gtk_widget_get_style_context (empty_pictures_box);
|
||||
gtk_style_context_add_class (context, "dim-label");
|
||||
gtk_stack_add_named (GTK_STACK (chooser->pictures_stack), empty_pictures_box, "empty");
|
||||
img = gtk_image_new_from_icon_name ("emblem-photos-symbolic", GTK_ICON_SIZE_DIALOG);
|
||||
gtk_widget_show (img);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (img), 64);
|
||||
gtk_widget_set_halign (img, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (img, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (img, TRUE);
|
||||
gtk_widget_set_vexpand (img, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (empty_pictures_box), img);
|
||||
labels_grid = gtk_grid_new ();
|
||||
gtk_widget_show (labels_grid);
|
||||
gtk_widget_set_halign (labels_grid, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (labels_grid, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (labels_grid, TRUE);
|
||||
gtk_widget_set_vexpand (labels_grid, TRUE);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (labels_grid), 6);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (labels_grid),
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
gtk_widget_show (labels_grid);
|
||||
gtk_container_add (GTK_CONTAINER (empty_pictures_box), labels_grid);
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_show (label);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
markup = g_markup_printf_escaped ("<b><span size='large'>%s</span></b>",
|
||||
/* translators: No pictures were found */
|
||||
_("No Pictures Found"));
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
gtk_container_add (GTK_CONTAINER (labels_grid), label);
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_show (label);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (label), 24);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
|
||||
pictures_dir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
|
||||
if (pictures_dir == NULL)
|
||||
{
|
||||
pictures_dir = g_get_home_dir ();
|
||||
/* translators: "Home" is used in place of the Pictures
|
||||
* directory in the string below when XDG_PICTURES_DIR is
|
||||
* undefined */
|
||||
pictures_dir_basename = g_strdup (_("Home"));
|
||||
}
|
||||
else
|
||||
pictures_dir_basename = g_path_get_basename (pictures_dir);
|
||||
|
||||
pictures_dir_uri = g_filename_to_uri (pictures_dir, NULL, NULL);
|
||||
href = g_markup_printf_escaped ("<a href=\"%s\">%s</a>", pictures_dir_uri, pictures_dir_basename);
|
||||
|
||||
/* translators: %s here is the name of the Pictures directory, the string should be translated in
|
||||
* the context "You can add images to your Pictures folder and they will show up here" */
|
||||
markup2 = g_strdup_printf (_("You can add images to your %s folder and they will show up here"), href);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup2);
|
||||
gtk_container_add (GTK_CONTAINER (labels_grid), label);
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (chooser), _("_Cancel"), GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (GTK_DIALOG (chooser), _("_Select"), GTK_RESPONSE_OK);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
|
||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_OK, FALSE);
|
||||
|
||||
g_signal_connect_object (chooser->stack, "notify::visible-child", G_CALLBACK (on_visible_child_notify), chooser, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_chooser_dialog_class_init (CcBackgroundChooserDialogClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->constructed = cc_background_chooser_dialog_constructed;
|
||||
object_class->dispose = cc_background_chooser_dialog_dispose;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (klass);
|
||||
widget_class->realize = cc_background_chooser_dialog_realize;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
cc_background_chooser_dialog_new (GtkWindow *transient_for)
|
||||
{
|
||||
return g_object_new (CC_TYPE_BACKGROUND_CHOOSER_DIALOG,
|
||||
"transient-for", transient_for,
|
||||
"use-header-bar", TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
CcBackgroundItem *
|
||||
cc_background_chooser_dialog_get_item (CcBackgroundChooserDialog *chooser)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkWidget *icon_view;
|
||||
GList *list;
|
||||
CcBackgroundItem *item;
|
||||
|
||||
item = NULL;
|
||||
icon_view = get_visible_view (chooser);
|
||||
list = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (icon_view));
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
model = gtk_icon_view_get_model (GTK_ICON_VIEW (icon_view));
|
||||
|
||||
if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) list->data) == FALSE)
|
||||
goto bail;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 1, &item, -1);
|
||||
|
||||
bail:
|
||||
g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
|
||||
|
||||
return item;
|
||||
}
|
||||
38
panels/background/cc-background-chooser-dialog.h
Normal file
38
panels/background/cc-background-chooser-dialog.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CC_PANEL_CHOOSER_DIALOG_H__
|
||||
#define __CC_PANEL_CHOOSER_DIALOG_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "cc-background-item.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_BACKGROUND_CHOOSER_DIALOG (cc_background_chooser_dialog_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundChooserDialog, cc_background_chooser_dialog, CC, BACKGROUND_CHOOSER_DIALOG, GtkDialog)
|
||||
|
||||
GtkWidget * cc_background_chooser_dialog_new (GtkWindow *transient_for);
|
||||
|
||||
CcBackgroundItem * cc_background_chooser_dialog_get_item (CcBackgroundChooserDialog *chooser);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CC_BACKGROUND_CHOOSER_DIALOG_H__ */
|
||||
@@ -1,384 +0,0 @@
|
||||
/* cc-background-chooser.c
|
||||
*
|
||||
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@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
|
||||
* 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
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "cc-background-chooser"
|
||||
|
||||
#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"
|
||||
|
||||
struct _CcBackgroundChooser
|
||||
{
|
||||
GtkBox parent;
|
||||
|
||||
GtkFlowBox *flowbox;
|
||||
GtkWidget *recent_box;
|
||||
GtkFlowBox *recent_flowbox;
|
||||
|
||||
gboolean recent_selected;
|
||||
|
||||
BgWallpapersSource *wallpapers_source;
|
||||
BgRecentSource *recent_source;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundChooser, cc_background_chooser, GTK_TYPE_BOX)
|
||||
|
||||
enum
|
||||
{
|
||||
BACKGROUND_CHOSEN,
|
||||
N_SIGNALS,
|
||||
};
|
||||
|
||||
static guint signals [N_SIGNALS];
|
||||
|
||||
static void
|
||||
emit_background_chosen (CcBackgroundChooser *self)
|
||||
{
|
||||
g_autoptr(GList) list = NULL;
|
||||
CcBackgroundItem *item;
|
||||
GtkFlowBox *flowbox;
|
||||
|
||||
flowbox = self->recent_selected ? self->recent_flowbox : self->flowbox;
|
||||
list = gtk_flow_box_get_selected_children (flowbox);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
|
||||
item = g_object_get_data (list->data, "item");
|
||||
|
||||
g_signal_emit (self, signals[BACKGROUND_CHOSEN], 0, item);
|
||||
}
|
||||
|
||||
static void
|
||||
on_delete_background_clicked_cb (GtkButton *button,
|
||||
BgRecentSource *source)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
CcBackgroundItem *item;
|
||||
|
||||
parent = gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (button)));
|
||||
g_assert (GTK_IS_FLOW_BOX_CHILD (parent));
|
||||
|
||||
item = g_object_get_data (G_OBJECT (parent), "item");
|
||||
|
||||
bg_recent_source_remove_item (source, item);
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_widget_func (gpointer model_item,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
CcBackgroundItem *item;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *child;
|
||||
GtkWidget *image;
|
||||
GtkWidget *icon;
|
||||
GtkWidget *button = NULL;
|
||||
BgSource *source;
|
||||
|
||||
source = BG_SOURCE (user_data);
|
||||
item = CC_BACKGROUND_ITEM (model_item);
|
||||
pixbuf = cc_background_item_get_thumbnail (item,
|
||||
bg_source_get_thumbnail_factory (source),
|
||||
bg_source_get_thumbnail_width (source),
|
||||
bg_source_get_thumbnail_height (source),
|
||||
bg_source_get_scale_factor (source));
|
||||
image = gtk_image_new_from_gicon (G_ICON (pixbuf), GTK_ICON_SIZE_DIALOG);
|
||||
gtk_widget_show (image);
|
||||
|
||||
icon = gtk_image_new_from_icon_name("slideshow-emblem", GTK_ICON_SIZE_BUTTON);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (icon), 16);
|
||||
gtk_widget_set_margin_start (icon, 8);
|
||||
gtk_widget_set_margin_end (icon, 8);
|
||||
gtk_widget_set_margin_top (icon, 8);
|
||||
gtk_widget_set_margin_bottom (icon, 8);
|
||||
gtk_widget_set_halign (icon, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (icon, GTK_ALIGN_END);
|
||||
gtk_widget_set_visible (icon, cc_background_item_changes_with_time (item));
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (icon), "slideshow-emblem");
|
||||
|
||||
|
||||
if (BG_IS_RECENT_SOURCE (source))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_BUTTON);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_START);
|
||||
gtk_widget_set_margin_start (icon, 6);
|
||||
gtk_widget_set_margin_end (icon, 6);
|
||||
gtk_widget_set_margin_top (icon, 6);
|
||||
gtk_widget_set_margin_bottom (icon, 6);
|
||||
gtk_widget_show (button);
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "osd");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "remove-button");
|
||||
|
||||
g_signal_connect (button,
|
||||
"clicked",
|
||||
G_CALLBACK (on_delete_background_clicked_cb),
|
||||
source);
|
||||
}
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (overlay), image);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), icon);
|
||||
if (button)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_widget_show (overlay);
|
||||
|
||||
child = gtk_flow_box_child_new();
|
||||
gtk_widget_set_halign (child, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (child), overlay);
|
||||
gtk_widget_show (child);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (child), "item", g_object_ref (item), g_object_unref);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
static void
|
||||
update_recent_visibility (CcBackgroundChooser *self)
|
||||
{
|
||||
GListStore *store;
|
||||
gboolean has_items;
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (self->recent_source));
|
||||
has_items = g_list_model_get_n_items (G_LIST_MODEL (store)) != 0;
|
||||
|
||||
gtk_widget_set_visible (self->recent_box, has_items);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_flowbox (CcBackgroundChooser *self)
|
||||
{
|
||||
GListStore *store;
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (self->wallpapers_source));
|
||||
|
||||
gtk_flow_box_bind_model (self->flowbox,
|
||||
G_LIST_MODEL (store),
|
||||
create_widget_func,
|
||||
self->wallpapers_source,
|
||||
NULL);
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (self->recent_source));
|
||||
|
||||
gtk_flow_box_bind_model (self->recent_flowbox,
|
||||
G_LIST_MODEL (store),
|
||||
create_widget_func,
|
||||
self->recent_source,
|
||||
NULL);
|
||||
|
||||
update_recent_visibility (self);
|
||||
g_signal_connect_object (store,
|
||||
"items-changed",
|
||||
G_CALLBACK (update_recent_visibility),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
on_item_activated_cb (GtkFlowBox *flowbox,
|
||||
GtkFlowBoxChild *child,
|
||||
CcBackgroundChooser *self)
|
||||
{
|
||||
self->recent_selected = flowbox == self->recent_flowbox;
|
||||
if (self->recent_selected)
|
||||
gtk_flow_box_unselect_all (self->flowbox);
|
||||
else
|
||||
gtk_flow_box_unselect_all (self->recent_flowbox);
|
||||
emit_background_chosen (self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_chooser_response_cb (GtkDialog *filechooser,
|
||||
gint response,
|
||||
CcBackgroundChooser *self)
|
||||
{
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
g_autoptr(GSList) filenames = NULL;
|
||||
GSList *l;
|
||||
|
||||
filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (filechooser));
|
||||
for (l = filenames; l != NULL; l = l->next)
|
||||
{
|
||||
g_autofree gchar *filename = l->data;
|
||||
|
||||
bg_recent_source_add_file (self->recent_source, filename);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (filechooser));
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_chooser_selection_changed_cb (GtkFileChooser *chooser,
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory)
|
||||
{
|
||||
g_autofree gchar *uri = NULL;
|
||||
|
||||
uri = gtk_file_chooser_get_uri (chooser);
|
||||
|
||||
if (uri)
|
||||
{
|
||||
g_autoptr(GFileInfo) file_info = NULL;
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
g_autofree gchar *mime_type = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
GtkWidget *preview;
|
||||
|
||||
preview = gtk_file_chooser_get_preview_widget (chooser);
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
file_info = g_file_query_info (file,
|
||||
"standard::*",
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (file_info && g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
|
||||
mime_type = g_strdup (g_file_info_get_content_type (file_info));
|
||||
|
||||
if (mime_type)
|
||||
{
|
||||
pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnail_factory,
|
||||
uri,
|
||||
mime_type);
|
||||
}
|
||||
|
||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
pixbuf != NULL);
|
||||
|
||||
if (pixbuf)
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
|
||||
else
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (preview), "dialog-question", GTK_ICON_SIZE_DIALOG);
|
||||
}
|
||||
|
||||
gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
|
||||
}
|
||||
|
||||
/* GObject overrides */
|
||||
|
||||
static void
|
||||
cc_background_chooser_finalize (GObject *object)
|
||||
{
|
||||
CcBackgroundChooser *self = (CcBackgroundChooser *)object;
|
||||
|
||||
g_clear_object (&self->recent_source);
|
||||
g_clear_object (&self->wallpapers_source);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_chooser_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_chooser_class_init (CcBackgroundChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = cc_background_chooser_finalize;
|
||||
|
||||
signals[BACKGROUND_CHOSEN] = g_signal_new ("background-chosen",
|
||||
CC_TYPE_BACKGROUND_CHOOSER,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
CC_TYPE_BACKGROUND_ITEM);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-chooser.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, flowbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, recent_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, recent_flowbox);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_item_activated_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_chooser_init (CcBackgroundChooser *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->recent_source = bg_recent_source_new (GTK_WIDGET (self));
|
||||
self->wallpapers_source = bg_wallpapers_source_new (GTK_WIDGET (self));
|
||||
setup_flowbox (self);
|
||||
}
|
||||
|
||||
void
|
||||
cc_background_chooser_select_file (CcBackgroundChooser *self)
|
||||
{
|
||||
g_autoptr(GnomeDesktopThumbnailFactory) factory = NULL;
|
||||
GtkFileFilter *filter;
|
||||
GtkWidget *filechooser;
|
||||
GtkWindow *toplevel;
|
||||
GtkWidget *preview;
|
||||
|
||||
g_return_if_fail (CC_IS_BACKGROUND_CHOOSER (self));
|
||||
|
||||
toplevel = (GtkWindow*) gtk_widget_get_toplevel (GTK_WIDGET (self));
|
||||
filechooser = gtk_file_chooser_dialog_new (_("Select a picture"),
|
||||
toplevel,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_Open"), GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_window_set_modal (GTK_WINDOW (filechooser), TRUE);
|
||||
|
||||
preview = gtk_image_new ();
|
||||
gtk_widget_set_size_request (preview, 154, -1);
|
||||
gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (filechooser), preview);
|
||||
gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (filechooser), FALSE);
|
||||
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (filechooser), TRUE);
|
||||
gtk_widget_show (preview);
|
||||
|
||||
factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
g_signal_connect_after (filechooser,
|
||||
"selection-changed",
|
||||
G_CALLBACK (on_file_chooser_selection_changed_cb),
|
||||
factory);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (filechooser),
|
||||
"factory",
|
||||
g_object_ref (factory),
|
||||
g_object_unref);
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_pixbuf_formats (filter);
|
||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (filechooser), filter);
|
||||
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser),
|
||||
g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
|
||||
|
||||
g_signal_connect_object (filechooser,
|
||||
"response",
|
||||
G_CALLBACK (on_file_chooser_response_cb),
|
||||
self,
|
||||
0);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (filechooser));
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/* cc-background-chooser.h
|
||||
*
|
||||
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@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
|
||||
* 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 <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_BACKGROUND_CHOOSER (cc_background_chooser_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundChooser, cc_background_chooser, CC, BACKGROUND_CHOOSER, GtkBox)
|
||||
|
||||
void cc_background_chooser_select_file (CcBackgroundChooser *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,90 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcBackgroundChooser" parent="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="shadow-type">none</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="expand">True</property>
|
||||
<style>
|
||||
<class name="view" />
|
||||
</style>
|
||||
|
||||
<!-- Recent -->
|
||||
<child>
|
||||
<object class="GtkBox" id="recent_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="halign">center</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="recent_flowbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="min-children-per-line">1</property>
|
||||
<property name="max-children-per-line">8</property>
|
||||
<property name="activate-on-single-click">True</property>
|
||||
<property name="selection-mode">single</property>
|
||||
<signal name="child-activated" handler="on_item_activated_cb" object="CcBackgroundChooser" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="flowbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="min-children-per-line">1</property>
|
||||
<property name="max-children-per-line">8</property>
|
||||
<property name="activate-on-single-click">True</property>
|
||||
<property name="selection-mode">single</property>
|
||||
<signal name="child-activated" handler="on_item_activated_cb" object="CcBackgroundChooser" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</template>
|
||||
</interface>
|
||||
315
panels/background/cc-background-grilo-miner.c
Normal file
315
panels/background/cc-background-grilo-miner.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <grilo.h>
|
||||
|
||||
#define GOA_API_IS_SUBJECT_TO_CHANGE
|
||||
#include <goa/goa.h>
|
||||
|
||||
#include "bg-pictures-source.h"
|
||||
#include "cc-background-grilo-miner.h"
|
||||
|
||||
struct _CcBackgroundGriloMiner
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GCancellable *cancellable;
|
||||
GList *accounts;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundGriloMiner, cc_background_grilo_miner, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
MEDIA_FOUND,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
#define REMOTE_ITEM_COUNT 50
|
||||
|
||||
static gchar *
|
||||
get_grilo_id (GoaObject *goa_object)
|
||||
{
|
||||
GoaAccount *account;
|
||||
|
||||
account = goa_object_peek_account (goa_object);
|
||||
return g_strdup_printf ("grl-flickr-%s", goa_account_get_id (account));
|
||||
}
|
||||
|
||||
static void
|
||||
is_online_data_cached (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundGriloMiner *self;
|
||||
GError *error = NULL;
|
||||
GFileInfo *info = NULL;
|
||||
GFile *cache_file = G_FILE (object);
|
||||
GrlMedia *media;
|
||||
const gchar *uri;
|
||||
|
||||
info = g_file_query_info_finish (cache_file, res, &error);
|
||||
if (info == NULL)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
goto out;
|
||||
}
|
||||
|
||||
self = CC_BACKGROUND_GRILO_MINER (user_data);
|
||||
|
||||
media = g_object_get_data (G_OBJECT (cache_file), "grl-media");
|
||||
uri = grl_media_get_url (media);
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
g_debug ("Ignored URL '%s' as it is already in the cache", uri);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[MEDIA_FOUND], 0, media);
|
||||
|
||||
out:
|
||||
g_clear_object (&info);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
searched_online_source (GrlSource *source,
|
||||
guint operation_id,
|
||||
GrlMedia *media,
|
||||
guint remaining,
|
||||
gpointer user_data,
|
||||
const GError *error)
|
||||
{
|
||||
CcBackgroundGriloMiner *self = CC_BACKGROUND_GRILO_MINER (user_data);
|
||||
g_autoptr(GFile) cache_file = NULL;
|
||||
const gchar *uri;
|
||||
g_autofree gchar *cache_path = NULL;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
const gchar *source_id;
|
||||
|
||||
source_id = grl_source_get_id (source);
|
||||
g_warning ("Error searching %s: %s", source_id, error->message);
|
||||
grl_operation_cancel (operation_id);
|
||||
remaining = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uri = grl_media_get_url (media);
|
||||
cache_path = bg_pictures_source_get_unique_path (uri);
|
||||
cache_file = g_file_new_for_path (cache_path);
|
||||
g_object_set_data_full (G_OBJECT (cache_file), "grl-media", media, g_object_unref);
|
||||
g_file_query_info_async (cache_file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
is_online_data_cached,
|
||||
self);
|
||||
|
||||
out:
|
||||
if (remaining == 0)
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
static void
|
||||
query_online_source (CcBackgroundGriloMiner *self, GrlSource *source)
|
||||
{
|
||||
const GList *keys;
|
||||
GrlCaps *caps;
|
||||
GrlOperationOptions *options;
|
||||
|
||||
keys = grl_source_supported_keys (source);
|
||||
caps = grl_source_get_caps (source, GRL_OP_BROWSE);
|
||||
options = grl_operation_options_new (caps);
|
||||
grl_operation_options_set_count (options, REMOTE_ITEM_COUNT);
|
||||
grl_operation_options_set_resolution_flags (options, GRL_RESOLVE_FAST_ONLY);
|
||||
grl_operation_options_set_type_filter (options, GRL_TYPE_FILTER_IMAGE);
|
||||
|
||||
grl_source_search (source, NULL, keys, options, searched_online_source, g_object_ref (self));
|
||||
g_object_unref (options);
|
||||
}
|
||||
|
||||
static void
|
||||
add_online_source_cb (CcBackgroundGriloMiner *self,
|
||||
GrlSource *source)
|
||||
{
|
||||
GList *l;
|
||||
gboolean found = FALSE;
|
||||
const gchar *source_id;
|
||||
|
||||
source_id = grl_source_get_id (source);
|
||||
for (l = self->accounts; l != NULL && !found; l = l->next)
|
||||
{
|
||||
GoaObject *goa_object = GOA_OBJECT (l->data);
|
||||
g_autofree gchar *account_id = NULL;
|
||||
|
||||
account_id = get_grilo_id (goa_object);
|
||||
if (g_strcmp0 (source_id, account_id) == 0)
|
||||
{
|
||||
query_online_source (self, source);
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_async_ready (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundGriloMiner *self;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GList *accounts = NULL;
|
||||
GList *photo_accounts = NULL;
|
||||
GList *l;
|
||||
GoaClient *client = NULL;
|
||||
GrlRegistry *registry;
|
||||
|
||||
client = goa_client_new_finish (res, &error);
|
||||
if (client == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to create GoaClient: %s", error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
self = CC_BACKGROUND_GRILO_MINER (user_data);
|
||||
|
||||
accounts = goa_client_get_accounts (client);
|
||||
for (l = accounts; l != NULL; l = l->next)
|
||||
{
|
||||
GoaObject *goa_object = GOA_OBJECT (l->data);
|
||||
GoaAccount *account;
|
||||
GoaPhotos *photos;
|
||||
const gchar *provider_type;
|
||||
|
||||
account = goa_object_peek_account (goa_object);
|
||||
provider_type = goa_account_get_provider_type (account);
|
||||
|
||||
photos = goa_object_peek_photos (goa_object);
|
||||
if (photos != NULL && g_strcmp0 (provider_type, "flickr") == 0)
|
||||
photo_accounts = g_list_prepend (photo_accounts, g_object_ref (goa_object));
|
||||
}
|
||||
|
||||
if (photo_accounts == NULL)
|
||||
goto out;
|
||||
|
||||
registry = grl_registry_get_default ();
|
||||
|
||||
for (l = photo_accounts; l != NULL; l = l->next)
|
||||
{
|
||||
GoaObject *goa_object = GOA_OBJECT (l->data);
|
||||
GrlSource *source;
|
||||
g_autofree gchar *account_id = NULL;
|
||||
|
||||
account_id = get_grilo_id (goa_object);
|
||||
source = grl_registry_lookup_source (registry, account_id);
|
||||
if (source != NULL)
|
||||
query_online_source (self, source);
|
||||
}
|
||||
|
||||
self->accounts = photo_accounts;
|
||||
photo_accounts = NULL;
|
||||
|
||||
g_signal_connect_object (registry, "source-added", G_CALLBACK (add_online_source_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
out:
|
||||
g_list_free_full (photo_accounts, g_object_unref);
|
||||
g_list_free_full (accounts, g_object_unref);
|
||||
g_clear_object (&client);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_online_accounts (CcBackgroundGriloMiner *self)
|
||||
{
|
||||
goa_client_new (self->cancellable, client_async_ready, self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_grilo_miner_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundGriloMiner *self = CC_BACKGROUND_GRILO_MINER (object);
|
||||
|
||||
if (self->cancellable)
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
}
|
||||
|
||||
if (self->accounts)
|
||||
{
|
||||
g_list_free_full (self->accounts, g_object_unref);
|
||||
self->accounts = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (cc_background_grilo_miner_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_grilo_miner_init (CcBackgroundGriloMiner *self)
|
||||
{
|
||||
self->cancellable = g_cancellable_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_grilo_miner_class_init (CcBackgroundGriloMinerClass *klass)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GrlRegistry *registry;
|
||||
|
||||
object_class->dispose = cc_background_grilo_miner_dispose;
|
||||
|
||||
signals[MEDIA_FOUND] = g_signal_new ("media-found",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, /* class_offset */
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accu_data */
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
GRL_TYPE_MEDIA);
|
||||
|
||||
grl_init (NULL, NULL);
|
||||
registry = grl_registry_get_default ();
|
||||
|
||||
error = NULL;
|
||||
if (!grl_registry_load_all_plugins (registry, FALSE, &error) ||
|
||||
!grl_registry_activate_plugin_by_id (registry, "grl-flickr", &error))
|
||||
g_warning ("%s", error->message);
|
||||
}
|
||||
|
||||
CcBackgroundGriloMiner *
|
||||
cc_background_grilo_miner_new (void)
|
||||
{
|
||||
return g_object_new (CC_TYPE_BACKGROUND_GRILO_MINER, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cc_background_grilo_miner_start (CcBackgroundGriloMiner *self)
|
||||
{
|
||||
setup_online_accounts (self);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2018 Red Hat, Inc
|
||||
/*
|
||||
* Copyright (C) 2014 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
|
||||
@@ -14,19 +13,23 @@
|
||||
*
|
||||
* 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: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shell/cc-panel.h>
|
||||
#ifndef _CC_BACKGROUND_GRILO_MINER_H
|
||||
#define _CC_BACKGROUND_GRILO_MINER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_DIAGNOSTICS_PANEL (cc_diagnostics_panel_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcDiagnosticsPanel, cc_diagnostics_panel, CC, DIAGNOSTICS_PANEL, CcPanel)
|
||||
#define CC_TYPE_BACKGROUND_GRILO_MINER (cc_background_grilo_miner_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundGriloMiner, cc_background_grilo_miner, CC, BACKGROUND_GRILO_MINER, GObject);
|
||||
|
||||
void cc_diagnostics_panel_static_init_func (void);
|
||||
CcBackgroundGriloMiner *cc_background_grilo_miner_new (void);
|
||||
|
||||
void cc_background_grilo_miner_start (CcBackgroundGriloMiner *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _CC_BACKGROUND_GRILO_MINER_H */
|
||||
@@ -52,18 +52,11 @@ struct _CcBackgroundItem
|
||||
guint64 modified;
|
||||
|
||||
/* internal */
|
||||
GdkPixbuf *slideshow_emblem;
|
||||
GnomeBG *bg;
|
||||
char *mime_type;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
struct {
|
||||
int width;
|
||||
int height;
|
||||
int frame;
|
||||
int scale_factor;
|
||||
GdkPixbuf *thumbnail;
|
||||
} cached_thumbnail;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -87,6 +80,64 @@ static void cc_background_item_finalize (GObject *object
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundItem, cc_background_item, G_TYPE_OBJECT)
|
||||
|
||||
static GdkPixbuf *slideshow_emblem = NULL;
|
||||
|
||||
static GdkPixbuf *
|
||||
get_emblemed_pixbuf (CcBackgroundItem *item, GdkPixbuf *pixbuf, gint scale_factor)
|
||||
{
|
||||
int eh;
|
||||
int ew;
|
||||
int h;
|
||||
int w;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
if (item->slideshow_emblem == NULL) {
|
||||
if (slideshow_emblem == NULL) {
|
||||
g_autoptr(GIcon) icon = NULL;
|
||||
GtkIconTheme *theme;
|
||||
g_autoptr(GtkIconInfo) icon_info = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
icon = g_themed_icon_new ("slideshow-emblem");
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme,
|
||||
icon,
|
||||
16,
|
||||
scale_factor,
|
||||
GTK_ICON_LOOKUP_FORCE_SIZE |
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
if (icon_info == NULL) {
|
||||
g_warning ("Your icon theme is missing the slideshow-emblem icon, "
|
||||
"please file a bug against it");
|
||||
return g_object_ref (pixbuf);
|
||||
}
|
||||
|
||||
slideshow_emblem = gtk_icon_info_load_icon (icon_info, &error);
|
||||
if (slideshow_emblem == NULL) {
|
||||
g_warning ("Failed to load slideshow emblem: %s", error->message);
|
||||
return g_object_ref (pixbuf);
|
||||
}
|
||||
|
||||
g_object_add_weak_pointer (G_OBJECT (slideshow_emblem), (gpointer *) (&slideshow_emblem));
|
||||
item->slideshow_emblem = slideshow_emblem;
|
||||
} else {
|
||||
item->slideshow_emblem = g_object_ref (slideshow_emblem);
|
||||
}
|
||||
}
|
||||
|
||||
eh = gdk_pixbuf_get_height (slideshow_emblem);
|
||||
ew = gdk_pixbuf_get_width (slideshow_emblem);
|
||||
h = gdk_pixbuf_get_height (pixbuf);
|
||||
w = gdk_pixbuf_get_width (pixbuf);
|
||||
x = w - ew;
|
||||
y = h - eh;
|
||||
|
||||
gdk_pixbuf_composite (slideshow_emblem, pixbuf, x, y, ew, eh, x, y, 1.0, 1.0, GDK_INTERP_BILINEAR, 255);
|
||||
|
||||
return g_object_ref (pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
set_bg_properties (CcBackgroundItem *item)
|
||||
{
|
||||
@@ -156,11 +207,7 @@ render_at_size (GnomeBG *bg,
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
|
||||
#ifdef GNOME_DESKTOP_BG_API_BREAK
|
||||
gnome_bg_draw (bg, pixbuf);
|
||||
#else
|
||||
gnome_bg_draw (bg, pixbuf, gdk_screen_get_default (), FALSE);
|
||||
#endif
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
@@ -180,14 +227,6 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
|
||||
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
||||
|
||||
/* Use the cached thumbnail if the sizes match */
|
||||
if (item->cached_thumbnail.thumbnail &&
|
||||
item->cached_thumbnail.width == width &&
|
||||
item->cached_thumbnail.height == height &&
|
||||
item->cached_thumbnail.scale_factor == scale_factor &&
|
||||
item->cached_thumbnail.frame == frame)
|
||||
return g_object_ref (item->cached_thumbnail.thumbnail);
|
||||
|
||||
set_bg_properties (item);
|
||||
|
||||
if (force_size) {
|
||||
@@ -216,7 +255,13 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
}
|
||||
}
|
||||
|
||||
retval = g_steal_pointer (&pixbuf);
|
||||
if (pixbuf != NULL
|
||||
&& frame != -2
|
||||
&& gnome_bg_changes_with_time (item->bg)) {
|
||||
retval = get_emblemed_pixbuf (item, pixbuf, scale_factor);
|
||||
} else {
|
||||
retval = g_steal_pointer (&pixbuf);
|
||||
}
|
||||
|
||||
gnome_bg_get_image_size (item->bg,
|
||||
thumbs,
|
||||
@@ -227,13 +272,6 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
|
||||
update_size (item);
|
||||
|
||||
/* Cache the new thumbnail */
|
||||
g_set_object (&item->cached_thumbnail.thumbnail, retval);
|
||||
item->cached_thumbnail.width = width;
|
||||
item->cached_thumbnail.height = height;
|
||||
item->cached_thumbnail.scale_factor = scale_factor;
|
||||
item->cached_thumbnail.frame = frame;
|
||||
|
||||
return g_steal_pointer (&retval);
|
||||
}
|
||||
|
||||
@@ -782,7 +820,6 @@ cc_background_item_finalize (GObject *object)
|
||||
|
||||
g_return_if_fail (item != NULL);
|
||||
|
||||
g_clear_object (&item->cached_thumbnail.thumbnail);
|
||||
g_free (item->name);
|
||||
g_free (item->uri);
|
||||
g_free (item->primary_color);
|
||||
@@ -795,6 +832,8 @@ cc_background_item_finalize (GObject *object)
|
||||
if (item->bg != NULL)
|
||||
g_object_unref (item->bg);
|
||||
|
||||
g_clear_object (&item->slideshow_emblem);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_item_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CC_BACKGROUND_ITEM_H
|
||||
#define __CC_BACKGROUND_ITEM_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
@@ -81,3 +82,5 @@ gboolean cc_background_item_compare (CcBackgroundItem *s
|
||||
void cc_background_item_dump (CcBackgroundItem *item);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CC_BACKGROUND_ITEM_H */
|
||||
|
||||
@@ -29,12 +29,13 @@
|
||||
|
||||
#include "cc-background-panel.h"
|
||||
|
||||
#include "cc-background-chooser.h"
|
||||
#include "cc-background-chooser-dialog.h"
|
||||
#include "cc-background-item.h"
|
||||
#include "cc-background-preview.h"
|
||||
#include "cc-background-resources.h"
|
||||
#include "cc-background-xml.h"
|
||||
|
||||
#include "bg-pictures-source.h"
|
||||
|
||||
#define WP_PATH_ID "org.gnome.desktop.background"
|
||||
#define WP_LOCK_PATH_ID "org.gnome.desktop.screensaver"
|
||||
#define WP_URI_KEY "picture-uri"
|
||||
@@ -47,6 +48,7 @@ struct _CcBackgroundPanel
|
||||
{
|
||||
CcPanel parent_instance;
|
||||
|
||||
GtkBuilder *builder;
|
||||
GDBusConnection *connection;
|
||||
|
||||
GSettings *settings;
|
||||
@@ -55,53 +57,232 @@ struct _CcBackgroundPanel
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
|
||||
CcBackgroundItem *current_background;
|
||||
CcBackgroundItem *current_lock_background;
|
||||
|
||||
CcBackgroundChooser *background_chooser;
|
||||
GtkButton *add_picture_button;
|
||||
CcBackgroundPreview *desktop_preview;
|
||||
GCancellable *copy_cancellable;
|
||||
|
||||
GtkWidget *spinner;
|
||||
GtkWidget *chooser;
|
||||
};
|
||||
|
||||
CC_PANEL_REGISTER (CcBackgroundPanel, cc_background_panel)
|
||||
|
||||
static void
|
||||
update_preview (CcBackgroundPanel *panel)
|
||||
#define WID(y) (GtkWidget *) gtk_builder_get_object (panel->builder, y)
|
||||
|
||||
static const char *
|
||||
cc_background_panel_get_help_uri (CcPanel *panel)
|
||||
{
|
||||
return "help:gnome-help/look-background";
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
|
||||
|
||||
g_clear_object (&panel->builder);
|
||||
|
||||
/* destroying the builder object will also destroy the spinner */
|
||||
panel->spinner = NULL;
|
||||
|
||||
g_clear_object (&panel->settings);
|
||||
g_clear_object (&panel->lock_settings);
|
||||
|
||||
if (panel->copy_cancellable)
|
||||
{
|
||||
/* cancel any copy operation */
|
||||
g_cancellable_cancel (panel->copy_cancellable);
|
||||
|
||||
g_clear_object (&panel->copy_cancellable);
|
||||
}
|
||||
|
||||
if (panel->chooser)
|
||||
{
|
||||
gtk_widget_destroy (panel->chooser);
|
||||
panel->chooser = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&panel->thumb_factory);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_finalize (GObject *object)
|
||||
{
|
||||
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
|
||||
|
||||
g_clear_object (&panel->current_background);
|
||||
g_clear_object (&panel->current_lock_background);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_class_init (CcBackgroundPanelClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
|
||||
panel_class->get_help_uri = cc_background_panel_get_help_uri;
|
||||
|
||||
object_class->dispose = cc_background_panel_dispose;
|
||||
object_class->finalize = cc_background_panel_finalize;
|
||||
}
|
||||
|
||||
static CcBackgroundItem *
|
||||
get_current_background (CcBackgroundPanel *panel, GSettings *settings)
|
||||
{
|
||||
if (settings == panel->settings)
|
||||
return panel->current_background;
|
||||
else
|
||||
return panel->current_lock_background;
|
||||
}
|
||||
|
||||
static void
|
||||
update_preview (CcBackgroundPanel *panel,
|
||||
GSettings *settings,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
gboolean changes_with_time;
|
||||
CcBackgroundItem *current_background;
|
||||
|
||||
current_background = panel->current_background;
|
||||
cc_background_preview_set_item (panel->desktop_preview, current_background);
|
||||
current_background = get_current_background (panel, settings);
|
||||
|
||||
if (item && current_background)
|
||||
{
|
||||
g_object_unref (current_background);
|
||||
current_background = cc_background_item_copy (item);
|
||||
if (settings == panel->settings)
|
||||
panel->current_background = current_background;
|
||||
else
|
||||
panel->current_lock_background = current_background;
|
||||
cc_background_item_load (current_background, NULL);
|
||||
}
|
||||
|
||||
changes_with_time = FALSE;
|
||||
|
||||
if (current_background)
|
||||
{
|
||||
changes_with_time = cc_background_item_changes_with_time (current_background);
|
||||
}
|
||||
|
||||
if (settings == panel->settings)
|
||||
{
|
||||
gtk_widget_set_visible (WID ("slide_image"), changes_with_time);
|
||||
gtk_widget_set_visible (WID ("slide-label"), changes_with_time);
|
||||
|
||||
gtk_widget_queue_draw (WID ("background-desktop-drawingarea"));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_visible (WID ("slide_image1"), changes_with_time);
|
||||
gtk_widget_set_visible (WID ("slide-label1"), changes_with_time);
|
||||
|
||||
gtk_widget_queue_draw (WID ("background-lock-drawingarea"));
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_save_path (void)
|
||||
get_save_path (CcBackgroundPanel *panel, GSettings *settings)
|
||||
{
|
||||
return g_build_filename (g_get_user_config_dir (),
|
||||
"gnome-control-center",
|
||||
"backgrounds",
|
||||
"last-edited.xml",
|
||||
settings == panel->settings ? "last-edited.xml" : "last-edited-lock.xml",
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
get_or_create_cached_pixbuf (CcBackgroundPanel *panel,
|
||||
GtkWidget *widget,
|
||||
CcBackgroundItem *background)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
const gint preview_width = 309;
|
||||
const gint preview_height = 168;
|
||||
gint scale_factor;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = g_object_get_data (G_OBJECT (background), "pixbuf");
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
scale_factor = gtk_widget_get_scale_factor (widget);
|
||||
pixbuf = cc_background_item_get_frame_thumbnail (background,
|
||||
panel->thumb_factory,
|
||||
preview_width,
|
||||
preview_height,
|
||||
scale_factor,
|
||||
-2, TRUE);
|
||||
g_object_set_data_full (G_OBJECT (background), "pixbuf", pixbuf, g_object_unref);
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_current_bg (CcBackgroundPanel *panel)
|
||||
update_display_preview (CcBackgroundPanel *panel,
|
||||
GtkWidget *widget,
|
||||
CcBackgroundItem *background)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_t *cr;
|
||||
|
||||
pixbuf = get_or_create_cached_pixbuf (panel, widget, background);
|
||||
|
||||
cr = gdk_cairo_create (gtk_widget_get_window (widget));
|
||||
gdk_cairo_set_source_pixbuf (cr,
|
||||
pixbuf,
|
||||
0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
CcBackgroundPanel *panel)
|
||||
{
|
||||
update_display_preview (panel, widget, panel->current_background);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_lock_preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
CcBackgroundPanel *panel)
|
||||
{
|
||||
update_display_preview (panel, widget, panel->current_lock_background);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_current_bg (CcBackgroundPanel *panel,
|
||||
GSettings *settings)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) saved = NULL;
|
||||
CcBackgroundItem *configured;
|
||||
GSettings *settings = NULL;
|
||||
g_autofree gchar *uri = NULL;
|
||||
g_autofree gchar *pcolor = NULL;
|
||||
g_autofree gchar *scolor = NULL;
|
||||
|
||||
/* Load the saved configuration */
|
||||
uri = get_save_path ();
|
||||
uri = get_save_path (panel, settings);
|
||||
saved = cc_background_xml_get_item (uri);
|
||||
|
||||
/* initalise the current background information from settings */
|
||||
settings = panel->settings;
|
||||
uri = g_settings_get_string (settings, WP_URI_KEY);
|
||||
if (uri && *uri == '\0')
|
||||
g_clear_pointer (&uri, g_free);
|
||||
|
||||
{
|
||||
g_clear_pointer (&uri, g_free);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
file = g_file_new_for_commandline_arg (uri);
|
||||
}
|
||||
configured = cc_background_item_new (uri);
|
||||
|
||||
pcolor = g_settings_get_string (settings, WP_PCOLOR_KEY);
|
||||
@@ -129,8 +310,16 @@ reload_current_bg (CcBackgroundPanel *panel)
|
||||
NULL);
|
||||
}
|
||||
|
||||
g_clear_object (&panel->current_background);
|
||||
panel->current_background = configured;
|
||||
if (settings == panel->settings)
|
||||
{
|
||||
g_clear_object (&panel->current_background);
|
||||
panel->current_background = configured;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_object (&panel->current_lock_background);
|
||||
panel->current_lock_background = configured;
|
||||
}
|
||||
cc_background_item_load (configured, NULL);
|
||||
}
|
||||
|
||||
@@ -151,15 +340,65 @@ create_save_dir (void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_finished_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer pointer)
|
||||
{
|
||||
g_autoptr(GError) err = NULL;
|
||||
g_autoptr(CcBackgroundPanel) panel = (CcBackgroundPanel *) pointer;
|
||||
CcBackgroundItem *item;
|
||||
CcBackgroundItem *current_background;
|
||||
GSettings *settings;
|
||||
|
||||
if (!g_file_copy_finish (G_FILE (source_object), result, &err))
|
||||
{
|
||||
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
return;
|
||||
}
|
||||
g_warning ("Failed to copy image to cache location: %s", err->message);
|
||||
}
|
||||
item = g_object_get_data (source_object, "item");
|
||||
settings = g_object_get_data (source_object, "settings");
|
||||
current_background = get_current_background (panel, settings);
|
||||
|
||||
g_settings_apply (settings);
|
||||
|
||||
/* the panel may have been destroyed before the callback is run, so be sure
|
||||
* to check the widgets are not NULL */
|
||||
|
||||
if (panel->spinner)
|
||||
{
|
||||
gtk_widget_destroy (GTK_WIDGET (panel->spinner));
|
||||
panel->spinner = NULL;
|
||||
}
|
||||
|
||||
if (current_background)
|
||||
cc_background_item_load (current_background, NULL);
|
||||
|
||||
if (panel->builder)
|
||||
{
|
||||
g_autofree gchar *filename = NULL;
|
||||
|
||||
update_preview (panel, settings, item);
|
||||
current_background = get_current_background (panel, settings);
|
||||
|
||||
/* Save the source XML if there is one */
|
||||
filename = get_save_path (panel, settings);
|
||||
if (create_save_dir ())
|
||||
cc_background_xml_save (current_background, filename);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_background (CcBackgroundPanel *panel,
|
||||
GSettings *settings,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
GDesktopBackgroundStyle style;
|
||||
CcBackgroundItemFlags flags;
|
||||
g_autofree gchar *filename = NULL;
|
||||
gboolean save_settings = TRUE;
|
||||
const char *uri;
|
||||
CcBackgroundItemFlags flags;
|
||||
|
||||
if (item == NULL)
|
||||
return;
|
||||
@@ -167,7 +406,86 @@ set_background (CcBackgroundPanel *panel,
|
||||
uri = cc_background_item_get_uri (item);
|
||||
flags = cc_background_item_get_flags (item);
|
||||
|
||||
g_settings_set_string (settings, WP_URI_KEY, uri);
|
||||
if ((flags & CC_BACKGROUND_ITEM_HAS_URI) && uri == NULL)
|
||||
{
|
||||
g_settings_set_enum (settings, WP_OPTIONS_KEY, G_DESKTOP_BACKGROUND_STYLE_NONE);
|
||||
g_settings_set_string (settings, WP_URI_KEY, "");
|
||||
}
|
||||
else if (cc_background_item_get_source_url (item) != NULL &&
|
||||
cc_background_item_get_needs_download (item))
|
||||
{
|
||||
g_autoptr(GFile) source = NULL;
|
||||
g_autoptr(GFile) dest = NULL;
|
||||
g_autofree gchar *cache_path = NULL;
|
||||
g_autofree gchar *basename = NULL;
|
||||
g_autofree gchar *display_name = NULL;
|
||||
g_autofree gchar *dest_path = NULL;
|
||||
g_autofree gchar *dest_uri = NULL;
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
|
||||
cache_path = bg_pictures_source_get_cache_path ();
|
||||
if (g_mkdir_with_parents (cache_path, USER_DIR_MODE) < 0)
|
||||
{
|
||||
g_warning ("Failed to create directory '%s'", cache_path);
|
||||
return;
|
||||
}
|
||||
|
||||
dest_path = bg_pictures_source_get_unique_path (cc_background_item_get_source_url (item));
|
||||
dest = g_file_new_for_path (dest_path);
|
||||
source = g_file_new_for_uri (cc_background_item_get_source_url (item));
|
||||
basename = g_file_get_basename (source);
|
||||
display_name = g_filename_display_name (basename);
|
||||
dest_path = g_file_get_path (dest);
|
||||
|
||||
/* create a blank image to use until the source image is ready */
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
|
||||
gdk_pixbuf_fill (pixbuf, 0x00000000);
|
||||
gdk_pixbuf_save (pixbuf, dest_path, "png", NULL, NULL);
|
||||
|
||||
if (panel->copy_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (panel->copy_cancellable);
|
||||
g_cancellable_reset (panel->copy_cancellable);
|
||||
}
|
||||
|
||||
if (panel->spinner)
|
||||
{
|
||||
gtk_widget_destroy (GTK_WIDGET (panel->spinner));
|
||||
panel->spinner = NULL;
|
||||
}
|
||||
|
||||
/* create a spinner while the file downloads */
|
||||
panel->spinner = gtk_spinner_new ();
|
||||
gtk_spinner_start (GTK_SPINNER (panel->spinner));
|
||||
gtk_box_pack_start (GTK_BOX (WID ("bottom-hbox")), panel->spinner, FALSE,
|
||||
FALSE, 6);
|
||||
gtk_widget_show (panel->spinner);
|
||||
|
||||
/* reference the panel in case it is removed before the copy is
|
||||
* finished */
|
||||
g_object_ref (panel);
|
||||
g_object_set_data_full (G_OBJECT (source), "item", g_object_ref (item), g_object_unref);
|
||||
g_object_set_data (G_OBJECT (source), "settings", settings);
|
||||
g_file_copy_async (source, dest, G_FILE_COPY_OVERWRITE,
|
||||
G_PRIORITY_DEFAULT, panel->copy_cancellable,
|
||||
NULL, NULL,
|
||||
copy_finished_cb, panel);
|
||||
dest_uri = g_file_get_uri (dest);
|
||||
|
||||
g_settings_set_string (settings, WP_URI_KEY, dest_uri);
|
||||
g_object_set (G_OBJECT (item),
|
||||
"uri", dest_uri,
|
||||
"needs-download", FALSE,
|
||||
"name", display_name,
|
||||
NULL);
|
||||
|
||||
/* delay the updated drawing of the preview until the copy finishes */
|
||||
save_settings = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_settings_set_string (settings, WP_URI_KEY, uri);
|
||||
}
|
||||
|
||||
/* Also set the placement if we have a URI and the previous value was none */
|
||||
if (flags & CC_BACKGROUND_ITEM_HAS_PLACEMENT)
|
||||
@@ -187,126 +505,131 @@ set_background (CcBackgroundPanel *panel,
|
||||
g_settings_set_string (settings, WP_PCOLOR_KEY, cc_background_item_get_pcolor (item));
|
||||
g_settings_set_string (settings, WP_SCOLOR_KEY, cc_background_item_get_scolor (item));
|
||||
|
||||
/* Apply all changes */
|
||||
g_settings_apply (settings);
|
||||
/* update the preview information */
|
||||
if (save_settings != FALSE)
|
||||
{
|
||||
g_autofree gchar *filename = NULL;
|
||||
|
||||
/* Save the source XML if there is one */
|
||||
filename = get_save_path ();
|
||||
if (create_save_dir ())
|
||||
cc_background_xml_save (panel->current_background, filename);
|
||||
}
|
||||
/* Apply all changes */
|
||||
g_settings_apply (settings);
|
||||
|
||||
|
||||
static void
|
||||
on_chooser_background_chosen_cb (CcBackgroundPanel *self,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
set_background (self, self->settings, item);
|
||||
set_background (self, self->lock_settings, item);
|
||||
/* Save the source XML if there is one */
|
||||
filename = get_save_path (panel, settings);
|
||||
if (create_save_dir ())
|
||||
cc_background_xml_save (get_current_background (panel, settings), filename);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_add_picture_button_clicked_cb (CcBackgroundPanel *self)
|
||||
on_chooser_dialog_response (GtkDialog *dialog,
|
||||
int response_id,
|
||||
CcBackgroundPanel *panel)
|
||||
{
|
||||
cc_background_chooser_select_file (self->background_chooser);
|
||||
}
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) item = NULL;
|
||||
|
||||
static const char *
|
||||
cc_background_panel_get_help_uri (CcPanel *panel)
|
||||
{
|
||||
return "help:gnome-help/look-background";
|
||||
item = cc_background_chooser_dialog_get_item (CC_BACKGROUND_CHOOSER_DIALOG (dialog));
|
||||
if (item != NULL)
|
||||
set_background (panel, g_object_get_data (G_OBJECT (dialog), "settings"), item);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_constructed (GObject *object)
|
||||
launch_chooser (CcBackgroundPanel *panel,
|
||||
GSettings *settings)
|
||||
{
|
||||
CcBackgroundPanel *self;
|
||||
CcShell *shell;
|
||||
GtkWidget *dialog;
|
||||
|
||||
self = CC_BACKGROUND_PANEL (object);
|
||||
shell = cc_panel_get_shell (CC_PANEL (self));
|
||||
|
||||
cc_shell_embed_widget_in_header (shell, GTK_WIDGET (self->add_picture_button), GTK_POS_RIGHT);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->constructed (object);
|
||||
dialog = cc_background_chooser_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (WID ("background-panel"))));
|
||||
g_object_set_data (G_OBJECT (dialog), "settings", settings);
|
||||
gtk_widget_show (dialog);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (on_chooser_dialog_response), panel);
|
||||
panel->chooser = dialog;
|
||||
g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer *) &panel->chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_dispose (GObject *object)
|
||||
on_background_button_clicked (GtkButton *button,
|
||||
CcBackgroundPanel *panel)
|
||||
{
|
||||
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
|
||||
|
||||
g_clear_object (&panel->settings);
|
||||
g_clear_object (&panel->lock_settings);
|
||||
g_clear_object (&panel->thumb_factory);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
|
||||
launch_chooser (panel, panel->settings);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_finalize (GObject *object)
|
||||
on_lock_button_clicked (GtkButton *button,
|
||||
CcBackgroundPanel *panel)
|
||||
{
|
||||
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
|
||||
|
||||
g_clear_object (&panel->current_background);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->finalize (object);
|
||||
launch_chooser (panel, panel->lock_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_class_init (CcBackgroundPanelClass *klass)
|
||||
on_settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
CcBackgroundPanel *panel)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
g_type_ensure (CC_TYPE_BACKGROUND_CHOOSER);
|
||||
g_type_ensure (CC_TYPE_BACKGROUND_PREVIEW);
|
||||
|
||||
panel_class->get_help_uri = cc_background_panel_get_help_uri;
|
||||
|
||||
object_class->constructed = cc_background_panel_constructed;
|
||||
object_class->dispose = cc_background_panel_dispose;
|
||||
object_class->finalize = cc_background_panel_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, add_picture_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, background_chooser);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, desktop_preview);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_chooser_background_chosen_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_add_picture_button_clicked_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
on_settings_changed (CcBackgroundPanel *panel)
|
||||
{
|
||||
reload_current_bg (panel);
|
||||
update_preview (panel);
|
||||
reload_current_bg (panel, settings);
|
||||
update_preview (panel, settings, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_init (CcBackgroundPanel *panel)
|
||||
{
|
||||
g_resources_register (cc_background_get_resource ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (panel));
|
||||
gchar *objects[] = {"background-panel", NULL };
|
||||
g_autoptr(GError) err = NULL;
|
||||
GtkWidget *widget;
|
||||
|
||||
panel->connection = g_application_get_dbus_connection (g_application_get_default ());
|
||||
g_resources_register (cc_background_get_resource ());
|
||||
|
||||
panel->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
panel->builder = gtk_builder_new ();
|
||||
gtk_builder_add_objects_from_resource (panel->builder,
|
||||
"/org/gnome/control-center/background/background.ui",
|
||||
objects, &err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
g_warning ("Could not load ui: %s", err->message);
|
||||
return;
|
||||
}
|
||||
|
||||
panel->settings = g_settings_new (WP_PATH_ID);
|
||||
g_settings_delay (panel->settings);
|
||||
|
||||
|
||||
panel->lock_settings = g_settings_new (WP_LOCK_PATH_ID);
|
||||
g_settings_delay (panel->lock_settings);
|
||||
|
||||
/* Load the background */
|
||||
reload_current_bg (panel);
|
||||
update_preview (panel);
|
||||
/* add the top level widget */
|
||||
widget = WID ("background-panel");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (panel), widget);
|
||||
gtk_widget_show (GTK_WIDGET (panel));
|
||||
|
||||
/* setup preview area */
|
||||
widget = WID ("background-desktop-drawingarea");
|
||||
g_signal_connect (widget, "draw", G_CALLBACK (on_preview_draw), panel);
|
||||
widget = WID ("background-lock-drawingarea");
|
||||
g_signal_connect (widget, "draw", G_CALLBACK (on_lock_preview_draw), panel);
|
||||
|
||||
panel->copy_cancellable = g_cancellable_new ();
|
||||
|
||||
panel->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
|
||||
/* Load the backgrounds */
|
||||
reload_current_bg (panel, panel->settings);
|
||||
update_preview (panel, panel->settings, NULL);
|
||||
reload_current_bg (panel, panel->lock_settings);
|
||||
update_preview (panel, panel->lock_settings, NULL);
|
||||
|
||||
/* Background settings */
|
||||
g_signal_connect_object (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel);
|
||||
g_signal_connect (panel->lock_settings, "changed", G_CALLBACK (on_settings_changed), panel);
|
||||
|
||||
/* Background buttons */
|
||||
widget = WID ("background-set-button");
|
||||
g_signal_connect (widget, "clicked", G_CALLBACK (on_background_button_clicked), panel);
|
||||
widget = WID ("background-lock-set-button");
|
||||
g_signal_connect (widget, "clicked", G_CALLBACK (on_lock_button_clicked), panel);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _CC_BACKGROUND_PANEL_H
|
||||
#define _CC_BACKGROUND_PANEL_H
|
||||
|
||||
#include <shell/cc-panel.h>
|
||||
|
||||
@@ -28,3 +30,5 @@ G_BEGIN_DECLS
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundPanel, cc_background_panel, CC, BACKGROUND_PANEL, CcPanel)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _CC_BACKGROUND_PANEL_H */
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcBackgroundPanel" parent="CcPanel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="HdyClamp">
|
||||
<property name="visible">1</property>
|
||||
<property name="maximum_size">300</property>
|
||||
<property name="tightening_threshold">200</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">24</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="CcBackgroundPreview" id="desktop_preview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="CcBackgroundChooser" id="background_chooser">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="expand">True</property>
|
||||
<signal name="background-chosen" handler="on_chooser_background_chosen_cb" object="CcBackgroundPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
<!-- Header button -->
|
||||
<object class="GtkButton" id="add_picture_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Add Picture…</property>
|
||||
<signal name="clicked" handler="on_add_picture_button_clicked_cb" object="CcBackgroundPanel" swapped="yes" />
|
||||
</object>
|
||||
</interface>
|
||||
@@ -1,382 +0,0 @@
|
||||
/* cc-background-preview.c
|
||||
*
|
||||
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@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
|
||||
* 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 <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
#include "cc-background-preview.h"
|
||||
|
||||
struct _CcBackgroundPreview
|
||||
{
|
||||
GtkBox parent;
|
||||
|
||||
GtkImage *animated_background_icon;
|
||||
GtkLabel *desktop_clock_label;
|
||||
GtkFrame *desktop_frame;
|
||||
GtkDrawingArea *drawing_area;
|
||||
GtkFrame *lock_frame;
|
||||
GtkLabel *lock_screen_label;
|
||||
GtkStack *stack;
|
||||
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
|
||||
CcBackgroundItem *item;
|
||||
GSettings *desktop_settings;
|
||||
|
||||
guint lock_screen_time_timeout_id;
|
||||
gboolean is_lock_screen;
|
||||
GDateTime *previous_time;
|
||||
gboolean is_24h_format;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundPreview, cc_background_preview, GTK_TYPE_BOX)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_IS_LOCK_SCREEN,
|
||||
PROP_ITEM,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
/* Auxiliary methods */
|
||||
|
||||
static void
|
||||
update_lock_screen_label (CcBackgroundPreview *self,
|
||||
gboolean force)
|
||||
{
|
||||
g_autoptr(GDateTime) now = NULL;
|
||||
g_autofree gchar *label = NULL;
|
||||
|
||||
now = g_date_time_new_now_local ();
|
||||
|
||||
/* Don't update the label if the hour:minute pair did not change */
|
||||
if (!force && self->previous_time &&
|
||||
g_date_time_get_hour (now) == g_date_time_get_hour (self->previous_time) &&
|
||||
g_date_time_get_minute (now) == g_date_time_get_minute (self->previous_time))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->is_24h_format)
|
||||
label = g_date_time_format (now, "%R");
|
||||
else
|
||||
label = g_date_time_format (now, "%I:%M %p");
|
||||
|
||||
gtk_label_set_label (self->lock_screen_label, label);
|
||||
gtk_label_set_label (self->desktop_clock_label, label);
|
||||
|
||||
g_clear_pointer (&self->previous_time, g_date_time_unref);
|
||||
self->previous_time = g_steal_pointer (&now);
|
||||
}
|
||||
|
||||
static void
|
||||
update_clock_format (CcBackgroundPreview *self)
|
||||
{
|
||||
g_autofree gchar *clock_format = NULL;
|
||||
gboolean is_24h_format;
|
||||
|
||||
clock_format = g_settings_get_string (self->desktop_settings, "clock-format");
|
||||
is_24h_format = g_strcmp0 (clock_format, "24h") == 0;
|
||||
|
||||
if (is_24h_format != self->is_24h_format)
|
||||
{
|
||||
self->is_24h_format = is_24h_format;
|
||||
update_lock_screen_label (self, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
load_custom_css (CcBackgroundPreview *self)
|
||||
{
|
||||
g_autoptr(GtkCssProvider) provider = NULL;
|
||||
|
||||
/* use custom CSS */
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gnome/control-center/background/preview.css");
|
||||
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_clock_cb (gpointer data)
|
||||
{
|
||||
CcBackgroundPreview *self = data;
|
||||
|
||||
update_lock_screen_label (self, FALSE);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_monitor_time (CcBackgroundPreview *self)
|
||||
{
|
||||
if (self->lock_screen_time_timeout_id > 0)
|
||||
return;
|
||||
|
||||
self->lock_screen_time_timeout_id = g_timeout_add_seconds (1,
|
||||
update_clock_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_monitor_time (CcBackgroundPreview *self)
|
||||
{
|
||||
if (self->lock_screen_time_timeout_id > 0)
|
||||
{
|
||||
g_source_remove (self->lock_screen_time_timeout_id);
|
||||
self->lock_screen_time_timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static gboolean
|
||||
on_preview_draw_cb (CcBackgroundPreview *self,
|
||||
cairo_t *cr)
|
||||
{
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
GtkAllocation allocation;
|
||||
gint scale_factor;
|
||||
|
||||
if (!self->item)
|
||||
return FALSE;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self->drawing_area));
|
||||
gtk_widget_get_allocation (GTK_WIDGET (self->drawing_area), &allocation);
|
||||
pixbuf = cc_background_item_get_frame_thumbnail (self->item,
|
||||
self->thumbnail_factory,
|
||||
allocation.width,
|
||||
allocation.height,
|
||||
scale_factor,
|
||||
0,
|
||||
TRUE);
|
||||
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* GObject overrides */
|
||||
|
||||
static void
|
||||
cc_background_preview_finalize (GObject *object)
|
||||
{
|
||||
CcBackgroundPreview *self = (CcBackgroundPreview *)object;
|
||||
|
||||
g_clear_object (&self->desktop_settings);
|
||||
g_clear_object (&self->item);
|
||||
g_clear_object (&self->thumbnail_factory);
|
||||
|
||||
g_clear_pointer (&self->previous_time, g_date_time_unref);
|
||||
|
||||
stop_monitor_time (self);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_preview_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcBackgroundPreview *self = CC_BACKGROUND_PREVIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_IS_LOCK_SCREEN:
|
||||
g_value_set_boolean (value, self->is_lock_screen);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, self->item);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcBackgroundPreview *self = CC_BACKGROUND_PREVIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_IS_LOCK_SCREEN:
|
||||
self->is_lock_screen = g_value_get_boolean (value);
|
||||
gtk_stack_set_visible_child (self->stack,
|
||||
self->is_lock_screen ? GTK_WIDGET (self->lock_frame) : GTK_WIDGET (self->desktop_frame));
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
cc_background_preview_set_item (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
cc_background_preview_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static gfloat
|
||||
get_primary_monitor_aspect_ratio (void)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *primary_monitor;
|
||||
gfloat aspect_ratio;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
primary_monitor = gdk_display_get_primary_monitor (display);
|
||||
aspect_ratio = 16.0 / 9.0;
|
||||
|
||||
if (primary_monitor)
|
||||
{
|
||||
GdkRectangle monitor_layout;
|
||||
gdk_monitor_get_geometry (primary_monitor, &monitor_layout);
|
||||
aspect_ratio = monitor_layout.width / (gfloat) monitor_layout.height;
|
||||
}
|
||||
|
||||
return aspect_ratio;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gfloat aspect_ratio = get_primary_monitor_aspect_ratio ();
|
||||
|
||||
*minimum = *natural = MAX (2, width / aspect_ratio);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gfloat aspect_ratio = get_primary_monitor_aspect_ratio ();
|
||||
|
||||
*minimum = *natural = MAX (2, height * aspect_ratio);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_class_init (CcBackgroundPreviewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = cc_background_preview_finalize;
|
||||
object_class->get_property = cc_background_preview_get_property;
|
||||
object_class->set_property = cc_background_preview_set_property;
|
||||
|
||||
widget_class->get_request_mode = cc_background_preview_get_request_mode;
|
||||
widget_class->get_preferred_height_for_width = cc_background_preview_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_width_for_height = cc_background_preview_get_preferred_width_for_height;
|
||||
|
||||
properties[PROP_IS_LOCK_SCREEN] = g_param_spec_boolean ("is-lock-screen",
|
||||
"Lock screen",
|
||||
"Whether the preview is of the lock screen",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_ITEM] = g_param_spec_object ("item",
|
||||
"Item",
|
||||
"Background item",
|
||||
CC_TYPE_BACKGROUND_ITEM,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
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, animated_background_icon);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, desktop_clock_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, desktop_frame);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, drawing_area);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, lock_frame);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, lock_screen_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, stack);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_preview_draw_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_init (CcBackgroundPreview *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
self->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
|
||||
|
||||
g_signal_connect_object (self->desktop_settings,
|
||||
"changed::clock-format",
|
||||
G_CALLBACK (update_clock_format),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
update_clock_format (self);
|
||||
load_custom_css (self);
|
||||
start_monitor_time (self);
|
||||
}
|
||||
|
||||
CcBackgroundItem*
|
||||
cc_background_preview_get_item (CcBackgroundPreview *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_PREVIEW (self), NULL);
|
||||
|
||||
return self->item;
|
||||
}
|
||||
|
||||
void
|
||||
cc_background_preview_set_item (CcBackgroundPreview *self,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
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;
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->animated_background_icon),
|
||||
cc_background_item_changes_with_time (item));
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self->drawing_area));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* cc-background-preview.h
|
||||
*
|
||||
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@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
|
||||
* 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 <gtk/gtk.h>
|
||||
|
||||
#include "cc-background-item.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_BACKGROUND_PREVIEW (cc_background_preview_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundPreview, cc_background_preview, CC, BACKGROUND_PREVIEW, GtkBox)
|
||||
|
||||
CcBackgroundItem* cc_background_preview_get_item (CcBackgroundPreview *self);
|
||||
void cc_background_preview_set_item (CcBackgroundPreview *self,
|
||||
CcBackgroundItem *item);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcBackgroundPreview" parent="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">False</property>
|
||||
<style>
|
||||
<class name="frame" />
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkOverlay">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
|
||||
<!-- Wallpaper -->
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="drawing_area">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="expand">True</property>
|
||||
<signal name="draw" handler="on_preview_draw_cb" object="CcBackgroundPreview" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Desktop / Lock Screen widgets -->
|
||||
<child type="overlay">
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="expand">True</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkFrame" id="desktop_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="shadow-type">none</property>
|
||||
<property name="valign">start</property>
|
||||
<style>
|
||||
<class name="desktop-preview" />
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Activities</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="center">
|
||||
<object class="GtkLabel" id="desktop_clock_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="spacing">4</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">network-wireless-symbolic</property>
|
||||
<property name="pixel-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">audio-volume-high-symbolic</property>
|
||||
<property name="pixel-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">battery-low-symbolic</property>
|
||||
<property name="pixel-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
|
||||
<child>
|
||||
<object class="GtkFrame" id="lock_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="shadow-type">none</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lock_screen_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="lock-screen-preview" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Wallpaper -->
|
||||
<child type="overlay">
|
||||
<object class="GtkImage" id="animated_background_icon">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="margin-end">8</property>
|
||||
<property name="margin-bottom">8</property>
|
||||
<property name="pixel-size">16</property>
|
||||
<property name="icon-name">slideshow-emblem</property>
|
||||
<style>
|
||||
<class name="slideshow-icon" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <gio/gio.h>
|
||||
#include <string.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libgnome-desktop/gnome-bg.h>
|
||||
#include <gdesktop-enums.h>
|
||||
|
||||
#include "gdesktop-enums-types.h"
|
||||
@@ -199,10 +200,7 @@ cc_background_xml_load_xml_internal (CcBackgroundXml *xml,
|
||||
bg_uri = NULL;
|
||||
} else {
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autofree gchar *dirname = NULL;
|
||||
|
||||
dirname = g_path_get_dirname (filename);
|
||||
file = g_file_new_for_commandline_arg_and_cwd (content, dirname);
|
||||
file = g_file_new_for_commandline_arg (content);
|
||||
bg_uri = g_file_get_uri (file);
|
||||
}
|
||||
SET_FLAG(CC_BACKGROUND_ITEM_HAS_URI);
|
||||
@@ -271,7 +269,7 @@ cc_background_xml_load_xml_internal (CcBackgroundXml *xml,
|
||||
} else if (!strcmp ((gchar *)wpa->name, "text")) {
|
||||
/* Do nothing here, libxml2 is being weird */
|
||||
} else {
|
||||
g_debug ("Unknown Tag in %s: %s", filename, wpa->name);
|
||||
g_warning ("Unknown Tag in %s: %s", filename, wpa->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,8 +609,6 @@ cc_background_xml_finalize (GObject *object)
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _CC_BACKGROUND_XML_H_
|
||||
#define _CC_BACKGROUND_XML_H_
|
||||
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
@@ -44,3 +46,6 @@ gboolean cc_background_xml_load_list_finish (CcBackgroundXml *xml,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ enums_header = files(
|
||||
common_sources += gnome.mkenums(
|
||||
enums + '.h',
|
||||
sources: enums_header,
|
||||
fhead: '#pragma once\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n',
|
||||
fhead: '#ifndef __GDESKTOP_ENUMS_TYPES_H__\n#define __GDESKTOP_ENUMS_TYPES_H__\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'
|
||||
ftail: 'G_END_DECLS\n\n#endif /* __GDESKTOP_ENUMS_TYPES_H__ */'
|
||||
)
|
||||
|
||||
common_sources += gnome.mkenums(
|
||||
@@ -59,12 +59,7 @@ common_sources += gnome.mkenums(
|
||||
vtail: ' { 0, NULL, NULL }\n };\n etype = g_@type@_register_static ("@EnumName@", values);\n }\n return etype;\n}\n'
|
||||
)
|
||||
|
||||
resource_data = files(
|
||||
'cc-background-chooser.ui',
|
||||
'cc-background-panel.ui',
|
||||
'cc-background-preview.ui',
|
||||
'preview.css',
|
||||
)
|
||||
resource_data = files('background.ui')
|
||||
|
||||
common_sources += gnome.compile_resources(
|
||||
'cc-@0@-resources'.format(cappletname),
|
||||
@@ -76,31 +71,39 @@ common_sources += gnome.compile_resources(
|
||||
|
||||
sources = common_sources + files(
|
||||
'bg-colors-source.c',
|
||||
'bg-recent-source.c',
|
||||
'bg-pictures-source.c',
|
||||
'bg-source.c',
|
||||
'bg-wallpapers-source.c',
|
||||
'cc-background-chooser.c',
|
||||
'cc-background-chooser-dialog.c',
|
||||
'cc-background-grilo-miner.c',
|
||||
'cc-background-item.c',
|
||||
'cc-background-panel.c',
|
||||
'cc-background-preview.c',
|
||||
'cc-background-xml.c',
|
||||
'cc-background-xml.c'
|
||||
)
|
||||
|
||||
deps = common_deps + [
|
||||
gdk_pixbuf_dep,
|
||||
gnome_desktop_dep,
|
||||
goa_dep,
|
||||
libxml_dep,
|
||||
dependency('cairo-gobject'),
|
||||
dependency('grilo-0.3', version: '>= 0.3.0')
|
||||
]
|
||||
|
||||
cflags += [
|
||||
'-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir),
|
||||
'-DDATADIR="@0@"'.format(control_center_datadir),
|
||||
'-DGNOME_DESKTOP_USE_UNSTABLE_API'
|
||||
]
|
||||
|
||||
if gnome_desktop_dep.version().version_compare('>=3.35.4')
|
||||
cflags += '-DGNOME_DESKTOP_BG_API_BREAK'
|
||||
endif
|
||||
libbackground_chooser = static_library(
|
||||
cappletname + '-chooser',
|
||||
sources: sources,
|
||||
include_directories: top_inc,
|
||||
dependencies: deps,
|
||||
c_args: cflags
|
||||
)
|
||||
|
||||
sources = common_sources + files('cc-background-panel.c')
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
@@ -108,4 +111,16 @@ panels_libs += static_library(
|
||||
include_directories: top_inc,
|
||||
dependencies: deps,
|
||||
c_args: cflags,
|
||||
link_with: libbackground_chooser
|
||||
)
|
||||
|
||||
test_name = 'test-chooser-dialog'
|
||||
|
||||
executable(
|
||||
test_name,
|
||||
test_name + '.c',
|
||||
include_directories: top_inc,
|
||||
dependencies: deps,
|
||||
c_args: cflags,
|
||||
link_with: libbackground_chooser
|
||||
)
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
frame.desktop-preview {
|
||||
min-height: 10px;
|
||||
padding: 0 4px;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
frame.desktop-preview image {
|
||||
color: white;
|
||||
}
|
||||
|
||||
frame.desktop-preview label {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 6px;
|
||||
}
|
||||
|
||||
frame.lock-screen-preview {
|
||||
border: solid rgba(0, 0, 0, 0.33);
|
||||
border-width: 10px 0 0 0;
|
||||
}
|
||||
|
||||
frame.lock-screen-preview label {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
image.slideshow-icon {
|
||||
color: white;
|
||||
-gtk-icon-shadow: 0 1px 2px rgba(0, 0, 0, 0.33);
|
||||
}
|
||||
|
||||
button.remove-button {
|
||||
border-radius: 9999px;
|
||||
-gtk-outline-radius: 9999px;
|
||||
padding: 1px 0px; /* circles instead of ellipses */
|
||||
background-origin: padding-box, border-box;
|
||||
background-clip: padding-box, border-box;
|
||||
}
|
||||
37
panels/background/test-chooser-dialog.c
Normal file
37
panels/background/test-chooser-dialog.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "cc-background-chooser-dialog.h"
|
||||
|
||||
static void
|
||||
on_dialog_response (GtkDialog *dialog,
|
||||
int response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_debug ("response: %d", response_id);
|
||||
if (response_id == GTK_RESPONSE_OK) {
|
||||
g_autoptr(CcBackgroundItem) item = NULL;
|
||||
|
||||
item = cc_background_chooser_dialog_get_item (CC_BACKGROUND_CHOOSER_DIALOG (dialog));
|
||||
cc_background_item_dump (item);
|
||||
}
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
gtk_main_quit ();
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
dialog = cc_background_chooser_dialog_new (NULL);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), FALSE);
|
||||
g_signal_connect (G_OBJECT (dialog), "response",
|
||||
G_CALLBACK (on_dialog_response), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <shell/cc-shell.h>
|
||||
#include <shell/cc-object-storage.h>
|
||||
#include <bluetooth-settings-widget.h>
|
||||
@@ -29,19 +30,23 @@
|
||||
#include "cc-bluetooth-panel.h"
|
||||
#include "cc-bluetooth-resources.h"
|
||||
|
||||
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->builder, s))
|
||||
|
||||
struct _CcBluetoothPanel {
|
||||
CcPanel parent_instance;
|
||||
|
||||
GtkBox *airplane_box;
|
||||
GtkBuilder *builder;
|
||||
GtkBox *disabled_box;
|
||||
GtkSwitch *enable_switch;
|
||||
GtkBox *header_box;
|
||||
GtkBox *hw_airplane_box;
|
||||
GtkBox *no_devices_box;
|
||||
BluetoothSettingsWidget *settings_widget;
|
||||
GtkStack *stack;
|
||||
|
||||
GCancellable *cancellable;
|
||||
|
||||
/* Killswitch */
|
||||
GtkWidget *kill_switch_header;
|
||||
GDBusProxy *rfkill;
|
||||
GDBusProxy *properties;
|
||||
gboolean airplane_mode;
|
||||
@@ -65,8 +70,12 @@ cc_bluetooth_panel_finalize (GObject *object)
|
||||
|
||||
self = CC_BLUETOOTH_PANEL (object);
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
g_clear_object (&self->properties);
|
||||
g_clear_object (&self->rfkill);
|
||||
g_clear_object (&self->kill_switch_header);
|
||||
|
||||
G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -79,33 +88,18 @@ cc_bluetooth_panel_constructed (GObject *object)
|
||||
G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->constructed (object);
|
||||
|
||||
/* add kill switch widgets */
|
||||
self->kill_switch_header = g_object_ref (WID ("box_power"));
|
||||
cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (self)),
|
||||
GTK_WIDGET (self->header_box), GTK_POS_RIGHT);
|
||||
self->kill_switch_header);
|
||||
gtk_widget_show (self->kill_switch_header);
|
||||
}
|
||||
|
||||
static void
|
||||
airplane_mode_changed_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
power_callback (CcBluetoothPanel *self)
|
||||
{
|
||||
g_autoptr(GVariant) ret = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean state = GPOINTER_TO_UINT (user_data);
|
||||
gboolean state;
|
||||
|
||||
if (!g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
|
||||
res, &error)) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to change Bluetooth killswitch state to %s: %s",
|
||||
state ? "on" : "off", error->message);
|
||||
} else {
|
||||
g_debug ("Changed Bluetooth killswitch state to %s",
|
||||
state ? "on" : "off");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enable_switch_state_set_cb (CcBluetoothPanel *self, gboolean state)
|
||||
{
|
||||
state = gtk_switch_get_active (GTK_SWITCH (WID ("switch_bluetooth")));
|
||||
g_debug ("Power switched to %s", state ? "on" : "off");
|
||||
g_dbus_proxy_call (self->properties,
|
||||
"Set",
|
||||
@@ -113,20 +107,22 @@ enable_switch_state_set_cb (CcBluetoothPanel *self, gboolean state)
|
||||
g_variant_new_boolean (!state)),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
airplane_mode_changed_cb, self);
|
||||
self->cancellable,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
adapter_status_changed_cb (CcBluetoothPanel *self)
|
||||
cc_bluetooth_panel_update_power (CcBluetoothPanel *self)
|
||||
{
|
||||
GtkAlign valign;
|
||||
gboolean sensitive, powered;
|
||||
GObject *toggle;
|
||||
gboolean sensitive, powered, change_powered;
|
||||
GtkWidget *page;
|
||||
|
||||
g_debug ("Updating airplane mode: BluetoothHasAirplaneMode %d, BluetoothHardwareAirplaneMode %d, BluetoothAirplaneMode %d, AirplaneMode %d",
|
||||
self->has_airplane_mode, self->hardware_airplane_mode, self->bt_airplane_mode, self->airplane_mode);
|
||||
|
||||
change_powered = TRUE;
|
||||
valign = GTK_ALIGN_CENTER;
|
||||
|
||||
if (self->has_airplane_mode == FALSE) {
|
||||
@@ -146,9 +142,9 @@ adapter_status_changed_cb (CcBluetoothPanel *self)
|
||||
page = GTK_WIDGET (self->airplane_box);
|
||||
} else if (self->bt_airplane_mode ||
|
||||
!bluetooth_settings_widget_get_default_adapter_powered (self->settings_widget)) {
|
||||
g_debug ("Default adapter is unpowered");
|
||||
g_debug ("Default adapter is unpowered, but should be available");
|
||||
sensitive = TRUE;
|
||||
powered = FALSE;
|
||||
change_powered = FALSE;
|
||||
page = GTK_WIDGET (self->disabled_box);
|
||||
} else {
|
||||
g_debug ("Bluetooth is available and powered");
|
||||
@@ -159,10 +155,14 @@ adapter_status_changed_cb (CcBluetoothPanel *self)
|
||||
}
|
||||
|
||||
gtk_widget_set_valign (GTK_WIDGET (self->stack), valign);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->header_box), sensitive);
|
||||
g_signal_handlers_block_by_func (self->enable_switch, enable_switch_state_set_cb, self);
|
||||
gtk_switch_set_state (self->enable_switch, powered);
|
||||
g_signal_handlers_unblock_by_func (self->enable_switch, enable_switch_state_set_cb, self);
|
||||
gtk_widget_set_sensitive (WID ("box_power") , sensitive);
|
||||
|
||||
toggle = G_OBJECT (WID ("switch_bluetooth"));
|
||||
if (change_powered) {
|
||||
g_signal_handlers_block_by_func (toggle, power_callback, self);
|
||||
gtk_switch_set_active (GTK_SWITCH (toggle), powered);
|
||||
g_signal_handlers_unblock_by_func (toggle, power_callback, self);
|
||||
}
|
||||
|
||||
gtk_stack_set_visible_child (self->stack, page);
|
||||
}
|
||||
@@ -187,11 +187,11 @@ airplane_mode_changed (CcBluetoothPanel *self)
|
||||
bluetooth_has_airplane_mode = g_dbus_proxy_get_cached_property (self->rfkill, "BluetoothHasAirplaneMode");
|
||||
self->has_airplane_mode = g_variant_get_boolean (bluetooth_has_airplane_mode);
|
||||
|
||||
adapter_status_changed_cb (self);
|
||||
cc_bluetooth_panel_update_power (self);
|
||||
}
|
||||
|
||||
static void
|
||||
airplane_mode_off_button_clicked_cb (CcBluetoothPanel *self)
|
||||
on_airplane_mode_off_clicked (CcBluetoothPanel *self)
|
||||
{
|
||||
g_debug ("Airplane Mode Off clicked, disabling airplane mode");
|
||||
g_dbus_proxy_call (self->rfkill,
|
||||
@@ -201,13 +201,51 @@ airplane_mode_off_button_clicked_cb (CcBluetoothPanel *self)
|
||||
g_variant_new_boolean (FALSE)),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
self->cancellable,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static GtkBox *
|
||||
add_stack_page (CcBluetoothPanel *self,
|
||||
const char *icon_name,
|
||||
const char *message,
|
||||
const char *explanation)
|
||||
{
|
||||
GtkWidget *label, *image, *box;
|
||||
char *str;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_show (box);
|
||||
g_object_set (G_OBJECT (box), "margin-top", 64, "margin-bottom", 64, NULL);
|
||||
g_object_set (G_OBJECT (box), "margin-start", 12, "margin-end", 12, NULL);
|
||||
|
||||
image = gtk_image_new_from_icon_name (icon_name,
|
||||
GTK_ICON_SIZE_DIALOG);
|
||||
gtk_widget_show (image);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 192);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (image), "dim-label");
|
||||
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 24);
|
||||
|
||||
str = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>", message);
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_show (label);
|
||||
gtk_label_set_markup (GTK_LABEL (label), str);
|
||||
g_free (str);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (explanation);
|
||||
gtk_widget_show (label);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (self->stack), box);
|
||||
|
||||
return GTK_BOX (box);
|
||||
}
|
||||
|
||||
static void
|
||||
panel_changed_cb (CcBluetoothPanel *self,
|
||||
const char *panel)
|
||||
panel_changed (CcBluetoothPanel *self,
|
||||
const char *panel)
|
||||
{
|
||||
CcShell *shell;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@@ -221,38 +259,34 @@ static void
|
||||
cc_bluetooth_panel_class_init (CcBluetoothPanelClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
|
||||
object_class->constructed = cc_bluetooth_panel_constructed;
|
||||
object_class->finalize = cc_bluetooth_panel_finalize;
|
||||
|
||||
panel_class->get_help_uri = cc_bluetooth_panel_get_help_uri;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/bluetooth/cc-bluetooth-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, airplane_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, disabled_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, enable_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, header_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, no_devices_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, hw_airplane_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, settings_widget);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, stack);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, adapter_status_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, airplane_mode_off_button_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, enable_switch_state_set_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, panel_changed_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_bluetooth_panel_init (CcBluetoothPanel *self)
|
||||
{
|
||||
bluetooth_settings_widget_get_type ();
|
||||
GError *error = NULL;
|
||||
GtkWidget *button;
|
||||
|
||||
g_resources_register (cc_bluetooth_get_resource ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
self->builder = gtk_builder_new ();
|
||||
gtk_builder_set_translation_domain (self->builder, GETTEXT_PACKAGE);
|
||||
gtk_builder_add_from_resource (self->builder,
|
||||
"/org/gnome/control-center/bluetooth/cc-bluetooth-panel.ui",
|
||||
&error);
|
||||
if (error != NULL) {
|
||||
g_warning ("Could not load ui: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
/* RFKill */
|
||||
self->rfkill = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION,
|
||||
@@ -268,7 +302,48 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self)
|
||||
"org.freedesktop.DBus.Properties",
|
||||
NULL, NULL);
|
||||
|
||||
self->stack = GTK_STACK (gtk_stack_new ());
|
||||
gtk_stack_set_homogeneous (self->stack, TRUE);
|
||||
self->no_devices_box = add_stack_page (self,
|
||||
"bluetooth-active-symbolic",
|
||||
_("No Bluetooth Found"),
|
||||
_("Plug in a dongle to use Bluetooth."));
|
||||
self->disabled_box = add_stack_page (self,
|
||||
"bluetooth-active-symbolic",
|
||||
_("Bluetooth Turned Off"),
|
||||
_("Turn on to connect devices and receive file transfers."));
|
||||
self->airplane_box = add_stack_page (self,
|
||||
"airplane-mode-symbolic",
|
||||
_("Airplane Mode is on"),
|
||||
_("Bluetooth is disabled when airplane mode is on."));
|
||||
self->hw_airplane_box = add_stack_page (self,
|
||||
"airplane-mode-symbolic",
|
||||
_("Hardware Airplane Mode is on"),
|
||||
_("Turn off the Airplane mode switch to enable Bluetooth."));
|
||||
|
||||
button = gtk_button_new_with_label (_("Turn Off Airplane Mode"));
|
||||
gtk_widget_show (button);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||
g_signal_connect_swapped (G_OBJECT (button), "clicked",
|
||||
G_CALLBACK (on_airplane_mode_off_clicked), self);
|
||||
gtk_box_pack_start (self->airplane_box, button, FALSE, FALSE, 24);
|
||||
|
||||
self->settings_widget = BLUETOOTH_SETTINGS_WIDGET (bluetooth_settings_widget_new ());
|
||||
g_signal_connect_swapped (G_OBJECT (self->settings_widget), "panel-changed",
|
||||
G_CALLBACK (panel_changed), self);
|
||||
gtk_container_add (GTK_CONTAINER (self->stack), GTK_WIDGET (self->settings_widget));
|
||||
gtk_widget_show (GTK_WIDGET (self->settings_widget));
|
||||
gtk_widget_show (GTK_WIDGET (self->stack));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->stack));
|
||||
|
||||
airplane_mode_changed (self);
|
||||
g_signal_connect_object (self->rfkill, "g-properties-changed",
|
||||
G_CALLBACK (airplane_mode_changed), self, G_CONNECT_SWAPPED);
|
||||
G_CALLBACK (airplane_mode_changed), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (G_OBJECT (self->settings_widget), "adapter-status-changed",
|
||||
G_CALLBACK (cc_bluetooth_panel_update_power), self, G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_swapped (G_OBJECT (WID ("switch_bluetooth")), "notify::active",
|
||||
G_CALLBACK (power_callback), self);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _CC_BLUETOOTH_PANEL_H
|
||||
#define _CC_BLUETOOTH_PANEL_H
|
||||
|
||||
#include <shell/cc-shell.h>
|
||||
|
||||
@@ -32,3 +33,6 @@ G_BEGIN_DECLS
|
||||
G_DECLARE_FINAL_TYPE (CcBluetoothPanel, cc_bluetooth_panel, CC, BLUETOOTH_PANEL, CcPanel)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _CC_BLUETOOTH_PANEL_H */
|
||||
|
||||
|
||||
@@ -1,192 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.16.0 on Fri Nov 29 16:46:49 2013 -->
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcBluetoothPanel" parent="CcPanel">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="no_devices_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin_top">64</property>
|
||||
<property name="margin_bottom">64</property>
|
||||
<property name="margin_start">12</property>
|
||||
<property name="margin_end">12</property>
|
||||
<property name="spacing">24</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">bluetooth-active-symbolic</property>
|
||||
<property name="pixel_size">192</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">No Bluetooth Found</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="label" translatable="yes">Plug in a dongle to use Bluetooth.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="disabled_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin_top">64</property>
|
||||
<property name="margin_bottom">64</property>
|
||||
<property name="margin_start">12</property>
|
||||
<property name="margin_end">12</property>
|
||||
<property name="spacing">24</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">bluetooth-active-symbolic</property>
|
||||
<property name="pixel_size">192</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Bluetooth Turned Off</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="label" translatable="yes">Turn on to connect devices and receive file transfers.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="airplane_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin_top">64</property>
|
||||
<property name="margin_bottom">64</property>
|
||||
<property name="margin_start">12</property>
|
||||
<property name="margin_end">12</property>
|
||||
<property name="spacing">24</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">airplane-mode-symbolic</property>
|
||||
<property name="pixel_size">192</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Airplane Mode is on</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="label" translatable="yes">Bluetooth is disabled when airplane mode is on.</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Turn Off Airplane Mode</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="clicked" handler="airplane_mode_off_button_clicked_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hw_airplane_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin_top">64</property>
|
||||
<property name="margin_bottom">64</property>
|
||||
<property name="margin_start">12</property>
|
||||
<property name="margin_end">12</property>
|
||||
<property name="spacing">24</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">airplane-mode-symbolic</property>
|
||||
<property name="pixel_size">192</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hardware Airplane Mode is on</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="label" translatable="yes">Turn off the Airplane mode switch to enable Bluetooth.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="BluetoothSettingsWidget" id="settings_widget">
|
||||
<property name="visible">True</property>
|
||||
<signal name="panel-changed" handler="panel_changed_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
<signal name="adapter-status-changed" handler="adapter_status_changed_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="GtkBox" id="header_box">
|
||||
<object class="GtkBox" id="box_power">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="enable_switch">
|
||||
<object class="GtkSwitch" id="switch_bluetooth">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="state-set" handler="enable_switch_state_set_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
||||
@@ -31,6 +31,8 @@ sources += gnome.compile_resources(
|
||||
|
||||
deps = common_deps + [gnome_bluetooth_dep]
|
||||
|
||||
cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir)
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
sources: sources,
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/control-center/camera">
|
||||
<file preprocess="xml-stripblanks">cc-camera-panel.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -1,459 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2018 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 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: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "list-box-helper.h"
|
||||
#include "cc-camera-panel.h"
|
||||
#include "cc-camera-resources.h"
|
||||
#include "cc-util.h"
|
||||
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#define APP_PERMISSIONS_TABLE "devices"
|
||||
#define APP_PERMISSIONS_ID "camera"
|
||||
|
||||
struct _CcCameraPanel
|
||||
{
|
||||
CcPanel parent_instance;
|
||||
|
||||
GtkStack *stack;
|
||||
GtkListBox *camera_apps_list_box;
|
||||
|
||||
GSettings *privacy_settings;
|
||||
|
||||
GDBusProxy *perm_store;
|
||||
GVariant *camera_apps_perms;
|
||||
GVariant *camera_apps_data;
|
||||
GHashTable *camera_app_switches;
|
||||
|
||||
GtkSizeGroup *camera_icon_size_group;
|
||||
};
|
||||
|
||||
CC_PANEL_REGISTER (CcCameraPanel, cc_camera_panel)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CcCameraPanel *self;
|
||||
GtkWidget *widget;
|
||||
gchar *app_id;
|
||||
gboolean changing_state;
|
||||
gboolean pending_state;
|
||||
} CameraAppStateData;
|
||||
|
||||
static void
|
||||
camera_app_state_data_free (CameraAppStateData *data)
|
||||
{
|
||||
g_free (data->app_id);
|
||||
g_slice_free (CameraAppStateData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_perm_store_set_done (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GVariant) results = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
CameraAppStateData *data;
|
||||
|
||||
results = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
|
||||
res,
|
||||
&error);
|
||||
if (results == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to store permissions: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
data = (CameraAppStateData *) user_data;
|
||||
data->changing_state = FALSE;
|
||||
gtk_switch_set_state (GTK_SWITCH (data->widget), data->pending_state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_camera_app_state_set (GtkSwitch *widget,
|
||||
gboolean state,
|
||||
gpointer user_data)
|
||||
{
|
||||
CameraAppStateData *data = (CameraAppStateData *) user_data;
|
||||
GVariantBuilder builder;
|
||||
CcCameraPanel *self;
|
||||
GVariantIter iter;
|
||||
GVariant *params;
|
||||
const gchar *key;
|
||||
gchar **value;
|
||||
|
||||
self = data->self;
|
||||
|
||||
if (data->changing_state)
|
||||
return TRUE;
|
||||
|
||||
data->changing_state = TRUE;
|
||||
data->pending_state = state;
|
||||
|
||||
g_variant_iter_init (&iter, self->camera_apps_perms);
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
while (g_variant_iter_loop (&iter, "{&s^a&s}", &key, &value))
|
||||
{
|
||||
gchar *tmp = NULL;
|
||||
|
||||
/* It's OK to drop the entry if it's not in expected format */
|
||||
if (g_strv_length (value) != 1)
|
||||
continue;
|
||||
|
||||
if (g_strcmp0 (data->app_id, key) == 0)
|
||||
{
|
||||
tmp = value[0];
|
||||
value[0] = state ? "yes" : "no";
|
||||
}
|
||||
|
||||
g_variant_builder_add (&builder, "{s^as}", key, value);
|
||||
|
||||
if (tmp != NULL)
|
||||
value[0] = tmp;
|
||||
}
|
||||
|
||||
params = g_variant_new ("(sbsa{sas}v)",
|
||||
APP_PERMISSIONS_TABLE,
|
||||
TRUE,
|
||||
APP_PERMISSIONS_ID,
|
||||
&builder,
|
||||
self->camera_apps_data);
|
||||
|
||||
g_dbus_proxy_call (self->perm_store,
|
||||
"Set",
|
||||
params,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
on_perm_store_set_done,
|
||||
data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_camera_app (CcCameraPanel *self,
|
||||
const gchar *app_id,
|
||||
gboolean enabled)
|
||||
{
|
||||
g_autofree gchar *desktop_id = NULL;
|
||||
CameraAppStateData *data;
|
||||
GDesktopAppInfo *app_info;
|
||||
GtkWidget *box, *row, *w;
|
||||
GIcon *icon;
|
||||
|
||||
w = g_hash_table_lookup (self->camera_app_switches, app_id);
|
||||
if (w != NULL)
|
||||
{
|
||||
gtk_switch_set_active (GTK_SWITCH (w), enabled);
|
||||
return;
|
||||
}
|
||||
|
||||
desktop_id = g_strdup_printf ("%s.desktop", app_id);
|
||||
app_info = g_desktop_app_info_new (desktop_id);
|
||||
if (!app_info)
|
||||
return;
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
gtk_widget_show (row);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_show (box);
|
||||
gtk_widget_set_margin_start (box, 12);
|
||||
gtk_widget_set_margin_end (box, 6);
|
||||
gtk_widget_set_margin_top (box, 12);
|
||||
gtk_widget_set_margin_bottom (box, 12);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_widget_set_hexpand (box, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (self->camera_apps_list_box), row);
|
||||
|
||||
icon = g_app_info_get_icon (G_APP_INFO (app_info));
|
||||
w = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||
gtk_widget_show (w);
|
||||
gtk_widget_set_halign (w, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
|
||||
gtk_size_group_add_widget (self->camera_icon_size_group, w);
|
||||
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
|
||||
|
||||
w = gtk_label_new (g_app_info_get_name (G_APP_INFO (app_info)));
|
||||
gtk_widget_show (w);
|
||||
gtk_widget_set_margin_start (w, 12);
|
||||
gtk_widget_set_margin_end (w, 12);
|
||||
gtk_widget_set_halign (w, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
|
||||
gtk_label_set_xalign (GTK_LABEL (w), 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
|
||||
|
||||
w = gtk_switch_new ();
|
||||
gtk_widget_show (w);
|
||||
gtk_switch_set_active (GTK_SWITCH (w), enabled);
|
||||
gtk_widget_set_halign (w, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
|
||||
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
|
||||
g_settings_bind (self->privacy_settings,
|
||||
"disable-camera",
|
||||
w,
|
||||
"sensitive",
|
||||
G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||||
g_hash_table_insert (self->camera_app_switches,
|
||||
g_strdup (app_id),
|
||||
g_object_ref (w));
|
||||
|
||||
data = g_slice_new (CameraAppStateData);
|
||||
data->self = self;
|
||||
data->app_id = g_strdup (app_id);
|
||||
data->widget = w;
|
||||
data->changing_state = FALSE;
|
||||
g_signal_connect_data (G_OBJECT (w),
|
||||
"state-set",
|
||||
G_CALLBACK (on_camera_app_state_set),
|
||||
data,
|
||||
(GClosureNotify) camera_app_state_data_free,
|
||||
0);
|
||||
}
|
||||
|
||||
/* Steals permissions and permissions_data references */
|
||||
|
||||
static gboolean
|
||||
to_child_name (GBinding *binding,
|
||||
const GValue *from,
|
||||
GValue *to,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (g_value_get_boolean (from))
|
||||
g_value_set_string (to, "content");
|
||||
else
|
||||
g_value_set_string (to, "empty");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_perm_store (CcCameraPanel *self,
|
||||
GVariant *permissions,
|
||||
GVariant *permissions_data)
|
||||
{
|
||||
GVariantIter iter;
|
||||
const gchar *key;
|
||||
gchar **value;
|
||||
|
||||
g_clear_pointer (&self->camera_apps_perms, g_variant_unref);
|
||||
self->camera_apps_perms = permissions;
|
||||
g_clear_pointer (&self->camera_apps_data, g_variant_unref);
|
||||
self->camera_apps_data = permissions_data;
|
||||
|
||||
g_variant_iter_init (&iter, permissions);
|
||||
while (g_variant_iter_loop (&iter, "{&s^a&s}", &key, &value))
|
||||
{
|
||||
gboolean enabled;
|
||||
|
||||
if (g_strv_length (value) != 1)
|
||||
{
|
||||
g_debug ("Permissions for %s in incorrect format, ignoring..", key);
|
||||
continue;
|
||||
}
|
||||
|
||||
enabled = (g_strcmp0 (value[0], "no") != 0);
|
||||
|
||||
add_camera_app (self, key, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_perm_store_signal (GDBusProxy *proxy,
|
||||
gchar *sender_name,
|
||||
gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
GVariant *permissions, *permissions_data;
|
||||
|
||||
if (g_strcmp0 (signal_name, "Changed") != 0)
|
||||
return;
|
||||
|
||||
permissions = g_variant_get_child_value (parameters, 4);
|
||||
permissions_data = g_variant_get_child_value (parameters, 3);
|
||||
update_perm_store (user_data, permissions, permissions_data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_perm_store_lookup_done (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcCameraPanel *self = user_data;
|
||||
GVariant *ret, *permissions, *permissions_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
|
||||
res,
|
||||
&error);
|
||||
if (ret == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed fetch permissions from flatpak permission store: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
permissions = g_variant_get_child_value (ret, 0);
|
||||
permissions_data = g_variant_get_child_value (ret, 1);
|
||||
update_perm_store (user_data, permissions, permissions_data);
|
||||
|
||||
g_signal_connect_object (source_object,
|
||||
"g-signal",
|
||||
G_CALLBACK (on_perm_store_signal),
|
||||
self,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_perm_store_ready (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcCameraPanel *self;
|
||||
g_autoptr(GVariant) params = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
if (proxy == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to connect to flatpak permission store: %s", error->message);
|
||||
return;
|
||||
}
|
||||
self = user_data;
|
||||
self->perm_store = proxy;
|
||||
|
||||
params = g_variant_new ("(ss)",
|
||||
APP_PERMISSIONS_TABLE,
|
||||
APP_PERMISSIONS_ID);
|
||||
g_dbus_proxy_call (self->perm_store,
|
||||
"Lookup",
|
||||
params,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
on_perm_store_lookup_done,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_camera_panel_finalize (GObject *object)
|
||||
{
|
||||
CcCameraPanel *self = CC_CAMERA_PANEL (object);
|
||||
|
||||
g_clear_object (&self->privacy_settings);
|
||||
g_clear_object (&self->perm_store);
|
||||
g_clear_object (&self->camera_icon_size_group);
|
||||
g_clear_pointer (&self->camera_apps_perms, g_variant_unref);
|
||||
g_clear_pointer (&self->camera_apps_data, g_variant_unref);
|
||||
g_clear_pointer (&self->camera_app_switches, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (cc_camera_panel_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static const char *
|
||||
cc_camera_panel_get_help_uri (CcPanel *panel)
|
||||
{
|
||||
return "help:gnome-help/camera";
|
||||
}
|
||||
|
||||
static void
|
||||
cc_camera_panel_constructed (GObject *object)
|
||||
{
|
||||
CcCameraPanel *self = CC_CAMERA_PANEL (object);
|
||||
GtkWidget *box, *widget;
|
||||
|
||||
G_OBJECT_CLASS (cc_camera_panel_parent_class)->constructed (object);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_widget_show (box);
|
||||
|
||||
widget = gtk_switch_new ();
|
||||
gtk_widget_show (widget);
|
||||
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
|
||||
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 4);
|
||||
|
||||
g_settings_bind (self->privacy_settings, "disable-camera",
|
||||
widget, "active",
|
||||
G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||||
g_object_bind_property_full (widget, "active",
|
||||
self->stack, "visible-child-name",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
to_child_name,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
|
||||
cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (self)),
|
||||
box,
|
||||
GTK_POS_RIGHT);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_camera_panel_class_init (CcCameraPanelClass *klass)
|
||||
{
|
||||
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
panel_class->get_help_uri = cc_camera_panel_get_help_uri;
|
||||
|
||||
object_class->finalize = cc_camera_panel_finalize;
|
||||
object_class->constructed = cc_camera_panel_constructed;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/camera/cc-camera-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, camera_apps_list_box);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_camera_panel_init (CcCameraPanel *self)
|
||||
{
|
||||
g_resources_register (cc_camera_get_resource ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_list_box_set_header_func (self->camera_apps_list_box,
|
||||
cc_list_box_update_header_func,
|
||||
NULL,
|
||||
NULL);
|
||||
self->camera_icon_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
|
||||
|
||||
self->privacy_settings = g_settings_new ("org.gnome.desktop.privacy");
|
||||
|
||||
|
||||
self->camera_app_switches = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
g_object_unref);
|
||||
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
"org.freedesktop.impl.portal.PermissionStore",
|
||||
"/org/freedesktop/impl/portal/PermissionStore",
|
||||
"org.freedesktop.impl.portal.PermissionStore",
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
on_perm_store_ready,
|
||||
self);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2018 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 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: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shell/cc-panel.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_CAMERA_PANEL (cc_camera_panel_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcCameraPanel, cc_camera_panel, CC, CAMERA_PANEL, CcPanel)
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.14"/>
|
||||
<template class="CcCameraPanel" parent="CcPanel">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">true</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">true</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="pixel-size">96</property>
|
||||
<property name="icon-name">camera-disabled-symbolic</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="fill">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">true</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">15</property>
|
||||
<property name="label" translatable="yes">Camera is turned off</property>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">true</property>
|
||||
<property name="label" translatable="yes">No applications can capture photos or video.</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">empty</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="HdyClamp">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin_top">32</property>
|
||||
<property name="margin_bottom">32</property>
|
||||
<property name="margin_start">12</property>
|
||||
<property name="margin_end">12</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">true</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">true</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="label" translatable="yes">Use of the camera allows applications to capture photos and video. Disabling the camera may cause some applications to not function properly.</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">true</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="label" translatable="yes">Allow the applications below to use your camera.</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="camera_apps_list_box">
|
||||
<property name="visible">true</property>
|
||||
<property name="can-focus">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
|
||||
<child type="placeholder">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">true</property>
|
||||
<property name="margin">18</property>
|
||||
<property name="label" translatable="yes">No Applications Have Asked for Camera Access</property>
|
||||
<property name="wrap">true</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<style>
|
||||
<class name="dim-label" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">content</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,40 +0,0 @@
|
||||
panels_list += cappletname
|
||||
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
|
||||
|
||||
desktop_in = configure_file(
|
||||
input: desktop + '.in.in',
|
||||
output: desktop + '.in',
|
||||
configuration: desktop_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
desktop,
|
||||
type: 'desktop',
|
||||
input: desktop_in,
|
||||
output: desktop,
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
install_dir: control_center_desktopdir
|
||||
)
|
||||
|
||||
sources = files('cc-camera-panel.c')
|
||||
|
||||
resource_data = files('cc-camera-panel.ui')
|
||||
|
||||
sources += gnome.compile_resources(
|
||||
'cc-' + cappletname + '-resources',
|
||||
cappletname + '.gresource.xml',
|
||||
c_name: 'cc_' + cappletname,
|
||||
dependencies: resource_data,
|
||||
export: true
|
||||
)
|
||||
|
||||
cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir)
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
sources: sources,
|
||||
include_directories: [top_inc, common_inc],
|
||||
dependencies: common_deps,
|
||||
c_args: cflags
|
||||
)
|
||||
@@ -279,9 +279,10 @@ cc_color_calibrate_calib_set_output_gamma (CcColorCalibrate *calibrate,
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_property_changed_cb (CcColorCalibrate *calibrate,
|
||||
cc_color_calibrate_property_changed_cb (GDBusProxy *proxy,
|
||||
GVariant *changed_properties,
|
||||
GStrv invalidated_properties)
|
||||
GStrv invalidated_properties,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
gboolean ret;
|
||||
GtkWidget *widget;
|
||||
@@ -391,7 +392,7 @@ cc_color_calibrate_get_error_translation (CdSessionError code)
|
||||
case CD_SESSION_ERROR_FAILED_TO_FIND_SENSOR:
|
||||
case CD_SESSION_ERROR_INTERNAL:
|
||||
case CD_SESSION_ERROR_INVALID_VALUE:
|
||||
/* TRANSLATORS: We suck, the calibration failed and we have no
|
||||
/* TRANSLATORS: We suck, the calibation failed and we have no
|
||||
* good idea why or any suggestions */
|
||||
str = _("An internal error occurred that could not be recovered.");
|
||||
break;
|
||||
@@ -472,10 +473,11 @@ cc_color_calibrate_finished (CcColorCalibrate *calibrate,
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_signal_cb (CcColorCalibrate *calibrate,
|
||||
cc_color_calibrate_signal_cb (GDBusProxy *proxy,
|
||||
const gchar *sender_name,
|
||||
const gchar *signal_name,
|
||||
GVariant *parameters)
|
||||
GVariant *parameters,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
CdColorRGB color;
|
||||
CdColorRGB *color_tmp;
|
||||
@@ -654,27 +656,22 @@ out:
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_window_realize_cb (CcColorCalibrate *self)
|
||||
cc_color_calibrate_window_realize_cb (GtkWidget *widget,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (self->builder,
|
||||
"dialog_calibrate"));
|
||||
gtk_window_fullscreen (GTK_WINDOW (widget));
|
||||
gtk_window_maximize (GTK_WINDOW (widget));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_window_state_cb (CcColorCalibrate *calibrate,
|
||||
GdkEvent *event)
|
||||
cc_color_calibrate_window_state_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GdkEventWindowState *event_state = (GdkEventWindowState *) event;
|
||||
GtkWindow *window;
|
||||
|
||||
window = GTK_WINDOW (gtk_builder_get_object (calibrate->builder,
|
||||
"dialog_calibrate"));
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
|
||||
/* check event */
|
||||
if (event->type != GDK_WINDOW_STATE)
|
||||
@@ -692,15 +689,16 @@ cc_color_calibrate_window_state_cb (CcColorCalibrate *calibrate,
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_button_done_cb (CcColorCalibrate *calibrate)
|
||||
cc_color_calibrate_button_done_cb (GtkWidget *widget,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
g_main_loop_quit (calibrate->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_button_start_cb (CcColorCalibrate *calibrate)
|
||||
cc_color_calibrate_button_start_cb (GtkWidget *widget,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GVariant) retval = NULL;
|
||||
|
||||
@@ -725,19 +723,15 @@ cc_color_calibrate_button_start_cb (CcColorCalibrate *calibrate)
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_button_cancel_cb (CcColorCalibrate *calibrate)
|
||||
cc_color_calibrate_button_cancel_cb (GtkWidget *widget,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
cc_color_calibrate_cancel (calibrate);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_alpha_window_draw (CcColorCalibrate *calibrate, cairo_t *cr)
|
||||
cc_color_calibrate_alpha_window_draw (GtkWidget *widget, cairo_t *cr)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (calibrate->builder,
|
||||
"dialog_calibrate"));
|
||||
|
||||
if (gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)) &&
|
||||
gdk_screen_is_composited (gtk_widget_get_screen (widget)))
|
||||
{
|
||||
@@ -755,16 +749,12 @@ cc_color_calibrate_alpha_window_draw (CcColorCalibrate *calibrate, cairo_t *cr)
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_alpha_screen_changed_cb (CcColorCalibrate *calibrate)
|
||||
cc_color_calibrate_alpha_screen_changed_cb (GtkWindow *window,
|
||||
GdkScreen *old_screen,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GdkScreen *screen;
|
||||
GdkVisual *visual;
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (calibrate->builder,
|
||||
"dialog_calibrate"));
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (window));
|
||||
visual = gdk_screen_get_rgba_visual (screen);
|
||||
GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
|
||||
GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
|
||||
if (visual == NULL)
|
||||
visual = gdk_screen_get_system_visual (screen);
|
||||
gtk_widget_set_visual (GTK_WIDGET (window), visual);
|
||||
@@ -881,11 +871,11 @@ cc_color_calibrate_setup (CcColorCalibrate *calibrate,
|
||||
g_signal_connect_object (calibrate->proxy_helper,
|
||||
"g-properties-changed",
|
||||
G_CALLBACK (cc_color_calibrate_property_changed_cb),
|
||||
calibrate, G_CONNECT_SWAPPED);
|
||||
calibrate, 0);
|
||||
g_signal_connect_object (calibrate->proxy_helper,
|
||||
"g-signal",
|
||||
G_CALLBACK (cc_color_calibrate_signal_cb),
|
||||
calibrate, G_CONNECT_SWAPPED);
|
||||
calibrate, 0);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -986,7 +976,9 @@ cc_color_calibrate_start (CcColorCalibrate *calibrate,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_delete_event_cb (CcColorCalibrate *calibrate)
|
||||
cc_color_calibrate_delete_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
CcColorCalibrate *calibrate)
|
||||
{
|
||||
/* do not destroy the window */
|
||||
cc_color_calibrate_cancel (calibrate);
|
||||
@@ -1034,7 +1026,7 @@ cc_color_calibrate_init (CcColorCalibrate *calibrate)
|
||||
/* load UI */
|
||||
calibrate->builder = gtk_builder_new ();
|
||||
retval = gtk_builder_add_from_resource (calibrate->builder,
|
||||
"/org/gnome/control-center/color/cc-color-calibrate.ui",
|
||||
"/org/gnome/control-center/color/color-calibrate.ui",
|
||||
&error);
|
||||
if (retval == 0)
|
||||
g_warning ("Could not load interface: %s", error->message);
|
||||
@@ -1057,38 +1049,38 @@ cc_color_calibrate_init (CcColorCalibrate *calibrate)
|
||||
/* connect to buttons */
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (calibrate->builder,
|
||||
"button_start"));
|
||||
g_signal_connect_object (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_start_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_start_cb), calibrate);
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (calibrate->builder,
|
||||
"button_resume"));
|
||||
g_signal_connect_object (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_start_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_start_cb), calibrate);
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (calibrate->builder,
|
||||
"button_done"));
|
||||
g_signal_connect_object (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_done_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_done_cb), calibrate);
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (calibrate->builder,
|
||||
"button_cancel"));
|
||||
g_signal_connect_object (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_cancel_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (widget, "clicked",
|
||||
G_CALLBACK (cc_color_calibrate_button_cancel_cb), calibrate);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
/* setup the specialist calibration window */
|
||||
window = GTK_WINDOW (gtk_builder_get_object (calibrate->builder,
|
||||
"dialog_calibrate"));
|
||||
g_signal_connect_object (window, "draw",
|
||||
G_CALLBACK (cc_color_calibrate_alpha_window_draw), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (window, "realize",
|
||||
G_CALLBACK (cc_color_calibrate_window_realize_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (window, "window-state-event",
|
||||
G_CALLBACK (cc_color_calibrate_window_state_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (window, "delete-event",
|
||||
G_CALLBACK (cc_color_calibrate_delete_event_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (window, "draw",
|
||||
G_CALLBACK (cc_color_calibrate_alpha_window_draw), calibrate);
|
||||
g_signal_connect (window, "realize",
|
||||
G_CALLBACK (cc_color_calibrate_window_realize_cb), calibrate);
|
||||
g_signal_connect (window, "window-state-event",
|
||||
G_CALLBACK (cc_color_calibrate_window_state_cb), calibrate);
|
||||
g_signal_connect (window, "delete-event",
|
||||
G_CALLBACK (cc_color_calibrate_delete_event_cb), calibrate);
|
||||
gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
|
||||
gtk_window_set_keep_above (window, TRUE);
|
||||
cc_color_calibrate_alpha_screen_changed_cb (calibrate);
|
||||
g_signal_connect_object (window, "screen-changed",
|
||||
G_CALLBACK (cc_color_calibrate_alpha_screen_changed_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
cc_color_calibrate_alpha_screen_changed_cb (GTK_WINDOW (window), NULL, calibrate);
|
||||
g_signal_connect (window, "screen-changed",
|
||||
G_CALLBACK (cc_color_calibrate_alpha_screen_changed_cb), calibrate);
|
||||
calibrate->window = window;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ struct _CcColorDevice
|
||||
GtkWidget *widget_switch;
|
||||
GtkWidget *widget_arrow;
|
||||
GtkWidget *widget_nocalib;
|
||||
guint device_changed_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcColorDevice, cc_color_device, GTK_TYPE_LIST_BOX_ROW)
|
||||
@@ -147,6 +148,9 @@ cc_color_device_finalize (GObject *object)
|
||||
{
|
||||
CcColorDevice *color_device = CC_COLOR_DEVICE (object);
|
||||
|
||||
if (color_device->device_changed_id > 0)
|
||||
g_signal_handler_disconnect (color_device->device, color_device->device_changed_id);
|
||||
|
||||
g_free (color_device->sortable);
|
||||
g_object_unref (color_device->device);
|
||||
|
||||
@@ -170,13 +174,16 @@ cc_color_device_set_expanded (CcColorDevice *color_device,
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_device_notify_enable_device_cb (CcColorDevice *color_device)
|
||||
cc_color_device_notify_enable_device_cb (GtkSwitch *sw,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcColorDevice *color_device = CC_COLOR_DEVICE (user_data);
|
||||
gboolean enable;
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
enable = gtk_switch_get_active (GTK_SWITCH (color_device->widget_switch));
|
||||
enable = gtk_switch_get_active (sw);
|
||||
g_debug ("Set %s to %i", cd_device_get_id (color_device->device), enable);
|
||||
ret = cd_device_set_enabled_sync (color_device->device,
|
||||
enable, NULL, &error);
|
||||
@@ -189,7 +196,8 @@ cc_color_device_notify_enable_device_cb (CcColorDevice *color_device)
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_device_changed_cb (CcColorDevice *color_device)
|
||||
cc_color_device_changed_cb (CdDevice *device,
|
||||
CcColorDevice *color_device)
|
||||
{
|
||||
cc_color_device_refresh (color_device);
|
||||
}
|
||||
@@ -201,8 +209,9 @@ cc_color_device_constructed (GObject *object)
|
||||
g_autofree gchar *sortable_tmp = NULL;
|
||||
|
||||
/* watch the device for changes */
|
||||
g_signal_connect_object (color_device->device, "changed",
|
||||
G_CALLBACK (cc_color_device_changed_cb), color_device, G_CONNECT_SWAPPED);
|
||||
color_device->device_changed_id =
|
||||
g_signal_connect (color_device->device, "changed",
|
||||
G_CALLBACK (cc_color_device_changed_cb), color_device);
|
||||
|
||||
/* calculate sortable -- FIXME: we have to hack this as EggListBox
|
||||
* does not let us specify a GtkSortType:
|
||||
@@ -213,9 +222,9 @@ cc_color_device_constructed (GObject *object)
|
||||
cc_color_device_refresh (color_device);
|
||||
|
||||
/* watch to see if the user flicked the switch */
|
||||
g_signal_connect_object (color_device->widget_switch, "notify::active",
|
||||
G_CALLBACK (cc_color_device_notify_enable_device_cb),
|
||||
color_device, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (color_device->widget_switch, "notify::active",
|
||||
G_CALLBACK (cc_color_device_notify_enable_device_cb),
|
||||
color_device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -242,8 +251,10 @@ cc_color_device_class_init (CcColorDeviceClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_device_clicked_expander_cb (CcColorDevice *color_device)
|
||||
cc_color_device_clicked_expander_cb (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcColorDevice *color_device = CC_COLOR_DEVICE (user_data);
|
||||
color_device->expanded = !color_device->expanded;
|
||||
cc_color_device_refresh (color_device);
|
||||
g_signal_emit (color_device, signals[SIGNAL_EXPANDED_CHANGED], 0,
|
||||
@@ -276,9 +287,9 @@ cc_color_device_init (CcColorDevice *color_device)
|
||||
color_device->widget_arrow = gtk_image_new_from_icon_name ("pan-end-symbolic",
|
||||
GTK_ICON_SIZE_BUTTON);
|
||||
color_device->widget_button = gtk_button_new ();
|
||||
g_signal_connect_object (color_device->widget_button, "clicked",
|
||||
G_CALLBACK (cc_color_device_clicked_expander_cb),
|
||||
color_device, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (color_device->widget_button, "clicked",
|
||||
G_CALLBACK (cc_color_device_clicked_expander_cb),
|
||||
color_device);
|
||||
gtk_widget_set_valign (color_device->widget_button, GTK_ALIGN_CENTER);
|
||||
gtk_button_set_relief (GTK_BUTTON (color_device->widget_button), GTK_RELIEF_NONE);
|
||||
gtk_container_add (GTK_CONTAINER (color_device->widget_button), color_device->widget_arrow);
|
||||
|
||||
@@ -43,6 +43,7 @@ struct _CcColorPanel
|
||||
CdDevice *current_device;
|
||||
GPtrArray *devices;
|
||||
GPtrArray *sensors;
|
||||
GCancellable *cancellable;
|
||||
GDBusProxy *proxy;
|
||||
GSettings *settings;
|
||||
GSettings *settings_colord;
|
||||
@@ -86,6 +87,8 @@ struct _CcColorPanel
|
||||
CcColorCalibrate *calibrate;
|
||||
GtkListBox *list_box;
|
||||
gchar *list_box_filter;
|
||||
guint list_box_selected_id;
|
||||
guint list_box_activated_id;
|
||||
GtkSizeGroup *list_box_size;
|
||||
gboolean is_live_cd;
|
||||
gboolean model_is_changing;
|
||||
@@ -202,7 +205,7 @@ gcm_prefs_combobox_add_profile (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_default_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_default_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
g_autoptr(CdProfile) profile = NULL;
|
||||
gboolean ret;
|
||||
@@ -215,7 +218,7 @@ gcm_prefs_default_cb (CcColorPanel *prefs)
|
||||
|
||||
/* install somewhere out of $HOME */
|
||||
ret = cd_profile_install_system_wide_sync (profile,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (!ret)
|
||||
g_warning ("failed to set profile system-wide: %s",
|
||||
@@ -269,7 +272,7 @@ gcm_prefs_file_chooser_get_icc_profile (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_cancel_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_calib_cancel_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
gtk_widget_hide (prefs->assistant_calib);
|
||||
}
|
||||
@@ -286,8 +289,9 @@ gcm_prefs_calib_delayed_complete_cb (gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_prepare_cb (CcColorPanel *panel,
|
||||
GtkWidget *page)
|
||||
gcm_prefs_calib_prepare_cb (GtkAssistant *assistant,
|
||||
GtkWidget *page,
|
||||
CcColorPanel *panel)
|
||||
{
|
||||
/* give the user the indication they should actually manually set the
|
||||
* desired brightness rather than clicking blindly by delaying the
|
||||
@@ -300,11 +304,11 @@ gcm_prefs_calib_prepare_cb (CcColorPanel *panel,
|
||||
|
||||
/* disable the brightness page as we don't want to show a 'Finished'
|
||||
* button if the user goes back at any point */
|
||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (panel->assistant_calib), panel->box_calib_brightness, FALSE);
|
||||
gtk_assistant_set_page_complete (assistant, panel->box_calib_brightness, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_apply_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_calib_apply_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@@ -339,16 +343,18 @@ gcm_prefs_calib_apply_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcm_prefs_calib_delete_event_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_calib_delete_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
/* do not destroy the window */
|
||||
gcm_prefs_calib_cancel_cb (prefs);
|
||||
gcm_prefs_calib_cancel_cb (widget, prefs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_temp_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
GtkTreeSelection *selection)
|
||||
gcm_prefs_calib_temp_treeview_clicked_cb (GtkTreeSelection *selection,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
gboolean ret;
|
||||
GtkTreeIter iter;
|
||||
@@ -370,8 +376,8 @@ gcm_prefs_calib_temp_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_kind_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
GtkTreeSelection *selection)
|
||||
gcm_prefs_calib_kind_treeview_clicked_cb (GtkTreeSelection *selection,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
CdSensorCap device_kind;
|
||||
gboolean ret;
|
||||
@@ -394,8 +400,8 @@ gcm_prefs_calib_kind_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_quality_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
GtkTreeSelection *selection)
|
||||
gcm_prefs_calib_quality_treeview_clicked_cb (GtkTreeSelection *selection,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
CdProfileQuality quality;
|
||||
gboolean ret;
|
||||
@@ -485,8 +491,8 @@ gcm_prefs_calib_set_sensor (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_sensor_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
GtkTreeSelection *selection)
|
||||
gcm_prefs_calib_sensor_treeview_clicked_cb (GtkTreeSelection *selection,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
gboolean ret;
|
||||
GtkTreeIter iter;
|
||||
@@ -560,7 +566,9 @@ gcm_prefs_calibrate_display (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_title_entry_changed_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_title_entry_changed_cb (GtkWidget *widget,
|
||||
GParamSpec *param_spec,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
GtkAssistant *assistant;
|
||||
const gchar *value;
|
||||
@@ -572,7 +580,7 @@ gcm_prefs_title_entry_changed_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calibrate_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_calibrate_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@@ -591,13 +599,13 @@ gcm_prefs_calibrate_cb (CcColorPanel *prefs)
|
||||
|
||||
/* run with modal set */
|
||||
argv = g_ptr_array_new_with_free_func (g_free);
|
||||
g_ptr_array_add (argv, g_strdup ("gcm-calibrate"));
|
||||
g_ptr_array_add (argv, g_build_filename (BINDIR, "gcm-calibrate", NULL));
|
||||
g_ptr_array_add (argv, g_strdup ("--device"));
|
||||
g_ptr_array_add (argv, g_strdup (cd_device_get_id (prefs->current_device)));
|
||||
g_ptr_array_add (argv, g_strdup ("--parent-window"));
|
||||
g_ptr_array_add (argv, g_strdup_printf ("%i", xid));
|
||||
g_ptr_array_add (argv, NULL);
|
||||
ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, G_SPAWN_SEARCH_PATH,
|
||||
ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, 0,
|
||||
NULL, NULL, NULL, &error);
|
||||
if (!ret)
|
||||
g_warning ("failed to run calibrate: %s", error->message);
|
||||
@@ -725,7 +733,7 @@ gcm_prefs_add_profiles_suitable_for_devices (CcColorPanel *prefs,
|
||||
|
||||
/* get profiles */
|
||||
profile_array = cd_client_get_profiles_sync (prefs->client,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (profile_array == NULL)
|
||||
{
|
||||
@@ -741,7 +749,7 @@ gcm_prefs_add_profiles_suitable_for_devices (CcColorPanel *prefs,
|
||||
|
||||
/* get properties */
|
||||
ret = cd_profile_connect_sync (profile_tmp,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (!ret)
|
||||
{
|
||||
@@ -776,7 +784,7 @@ gcm_prefs_add_profiles_suitable_for_devices (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_upload_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_calib_upload_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
const gchar *uri;
|
||||
@@ -861,7 +869,7 @@ gcm_prefs_calib_upload_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_export_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_calib_export_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
gboolean ret;
|
||||
@@ -910,8 +918,9 @@ gcm_prefs_calib_export_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_export_link_cb (CcColorPanel *prefs,
|
||||
const gchar *url)
|
||||
gcm_prefs_calib_export_link_cb (GtkLabel *widget,
|
||||
const gchar *url,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
gtk_show_uri_on_window (GTK_WINDOW (prefs->main_window),
|
||||
"help:gnome-help/color-howtoimport",
|
||||
@@ -920,7 +929,7 @@ gcm_prefs_calib_export_link_cb (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_profile_add_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_profile_add_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
g_autoptr(GPtrArray) profiles = NULL;
|
||||
|
||||
@@ -928,7 +937,7 @@ gcm_prefs_profile_add_cb (CcColorPanel *prefs)
|
||||
profiles = cd_device_get_profiles (prefs->current_device);
|
||||
gcm_prefs_add_profiles_suitable_for_devices (prefs, profiles);
|
||||
|
||||
/* make insensitive until we have a selection */
|
||||
/* make insensitve until we have a selection */
|
||||
gtk_widget_set_sensitive (prefs->button_assign_ok, FALSE);
|
||||
|
||||
/* show the dialog */
|
||||
@@ -937,7 +946,7 @@ gcm_prefs_profile_add_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_profile_remove_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_profile_remove_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
gboolean ret = FALSE;
|
||||
@@ -958,7 +967,7 @@ gcm_prefs_profile_remove_cb (CcColorPanel *prefs)
|
||||
/* just remove it, the list store will get ::changed */
|
||||
ret = cd_device_remove_profile_sync (prefs->current_device,
|
||||
profile,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (!ret)
|
||||
g_warning ("failed to remove profile: %s", error->message);
|
||||
@@ -989,7 +998,7 @@ gcm_prefs_make_profile_default_cb (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_device_profile_enable_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_device_profile_enable_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
GtkListBoxRow *row;
|
||||
@@ -1011,7 +1020,7 @@ gcm_prefs_device_profile_enable_cb (CcColorPanel *prefs)
|
||||
cd_device_get_id (prefs->current_device));
|
||||
cd_device_make_profile_default (prefs->current_device,
|
||||
profile,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
(GAsyncReadyCallback) gcm_prefs_make_profile_default_cb,
|
||||
prefs);
|
||||
}
|
||||
@@ -1029,21 +1038,22 @@ gcm_prefs_profile_view (CcColorPanel *prefs, CdProfile *profile)
|
||||
|
||||
/* open up gcm-viewer as a info pane */
|
||||
argv = g_ptr_array_new_with_free_func (g_free);
|
||||
g_ptr_array_add (argv, g_strdup ("gcm-viewer"));
|
||||
g_ptr_array_add (argv, g_build_filename (BINDIR, "gcm-viewer", NULL));
|
||||
g_ptr_array_add (argv, g_strdup ("--profile"));
|
||||
g_ptr_array_add (argv, g_strdup (cd_profile_get_id (profile)));
|
||||
g_ptr_array_add (argv, g_strdup ("--parent-window"));
|
||||
g_ptr_array_add (argv, g_strdup_printf ("%i", xid));
|
||||
g_ptr_array_add (argv, NULL);
|
||||
ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, G_SPAWN_SEARCH_PATH,
|
||||
ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, 0,
|
||||
NULL, NULL, NULL, &error);
|
||||
if (!ret)
|
||||
g_warning ("failed to run calibrate: %s", error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_profile_assign_link_activate_cb (CcColorPanel *prefs,
|
||||
const gchar *uri)
|
||||
gcm_prefs_profile_assign_link_activate_cb (GtkLabel *label,
|
||||
const gchar *uri,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
GtkListBoxRow *row;
|
||||
@@ -1064,7 +1074,7 @@ gcm_prefs_profile_assign_link_activate_cb (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_profile_view_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_profile_view_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
GtkListBoxRow *row;
|
||||
@@ -1085,13 +1095,13 @@ gcm_prefs_profile_view_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_button_assign_cancel_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_button_assign_cancel_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
gtk_widget_hide (prefs->dialog_assign);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_button_assign_ok_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
@@ -1101,7 +1111,8 @@ gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
/* hide window */
|
||||
gtk_widget_hide (GTK_WIDGET (prefs->dialog_assign));
|
||||
widget = GTK_WIDGET (prefs->dialog_assign);
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
/* get the selected profile */
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview_assign));
|
||||
@@ -1122,7 +1133,7 @@ gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
{
|
||||
ret = cd_device_set_enabled_sync (prefs->current_device,
|
||||
TRUE,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (!ret)
|
||||
{
|
||||
@@ -1135,7 +1146,7 @@ gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
ret = cd_device_add_profile_sync (prefs->current_device,
|
||||
CD_DEVICE_RELATION_HARD,
|
||||
profile,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (!ret)
|
||||
{
|
||||
@@ -1146,15 +1157,17 @@ gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
/* make it default */
|
||||
cd_device_make_profile_default (prefs->current_device,
|
||||
profile,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
(GAsyncReadyCallback) gcm_prefs_make_profile_default_cb,
|
||||
prefs);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcm_prefs_profile_delete_event_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_profile_delete_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
gcm_prefs_button_assign_cancel_cb (prefs);
|
||||
gcm_prefs_button_assign_cancel_cb (widget, prefs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1290,8 +1303,8 @@ gcm_prefs_profile_clicked (CcColorPanel *prefs, CdProfile *profile, CdDevice *de
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_profiles_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
GtkTreeSelection *selection)
|
||||
gcm_prefs_profiles_treeview_clicked_cb (GtkTreeSelection *selection,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
@@ -1320,21 +1333,24 @@ gcm_prefs_profiles_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_profiles_row_activated_cb (CcColorPanel *prefs,
|
||||
GtkTreePath *path)
|
||||
gcm_prefs_profiles_row_activated_cb (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean ret;
|
||||
|
||||
ret = gtk_tree_model_get_iter (gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->treeview_assign)), &iter, path);
|
||||
ret = gtk_tree_model_get_iter (gtk_tree_view_get_model (tree_view), &iter, path);
|
||||
if (!ret)
|
||||
return;
|
||||
gcm_prefs_button_assign_ok_cb (prefs);
|
||||
gcm_prefs_button_assign_ok_cb (NULL, prefs);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gcm_prefs_button_assign_import_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_button_assign_import_cb (GtkWidget *widget,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@@ -1344,14 +1360,15 @@ gcm_prefs_button_assign_import_cb (CcColorPanel *prefs)
|
||||
if (file == NULL)
|
||||
{
|
||||
g_warning ("failed to get ICC file");
|
||||
gtk_widget_hide (GTK_WIDGET (prefs->dialog_assign));
|
||||
widget = GTK_WIDGET (prefs->dialog_assign);
|
||||
gtk_widget_hide (widget);
|
||||
return;
|
||||
}
|
||||
|
||||
#if CD_CHECK_VERSION(0,1,12)
|
||||
profile = cd_client_import_profile_sync (prefs->client,
|
||||
file,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (profile == NULL)
|
||||
{
|
||||
@@ -1361,7 +1378,7 @@ gcm_prefs_button_assign_import_cb (CcColorPanel *prefs)
|
||||
#endif
|
||||
|
||||
/* add to list view */
|
||||
gcm_prefs_profile_add_cb (prefs);
|
||||
gcm_prefs_profile_add_cb (NULL, prefs);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1423,7 +1440,7 @@ gcm_prefs_add_device_profile (CcColorPanel *prefs,
|
||||
|
||||
/* get properties */
|
||||
ret = cd_profile_connect_sync (profile,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
&error);
|
||||
if (!ret)
|
||||
{
|
||||
@@ -1525,7 +1542,7 @@ gcm_prefs_find_widget_by_object_path (GList *list,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_device_changed_cb (CcColorPanel *prefs, CdDevice *device)
|
||||
gcm_prefs_device_changed_cb (CdDevice *device, CcColorPanel *prefs)
|
||||
{
|
||||
CdDevice *device_tmp;
|
||||
CdProfile *profile_tmp;
|
||||
@@ -1576,9 +1593,9 @@ gcm_prefs_device_changed_cb (CcColorPanel *prefs, CdDevice *device)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_device_expanded_changed_cb (CcColorPanel *prefs,
|
||||
gcm_prefs_device_expanded_changed_cb (CcColorDevice *widget,
|
||||
gboolean is_expanded,
|
||||
CcColorDevice *widget)
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
/* ignore internal changes */
|
||||
if (prefs->model_is_changing)
|
||||
@@ -1619,7 +1636,7 @@ gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *device)
|
||||
GtkWidget *widget;
|
||||
|
||||
/* get device properties */
|
||||
ret = cd_device_connect_sync (device, cc_panel_get_cancellable (CC_PANEL (prefs)), &error);
|
||||
ret = cd_device_connect_sync (device, prefs->cancellable, &error);
|
||||
if (!ret)
|
||||
{
|
||||
g_warning ("failed to connect to the device: %s", error->message);
|
||||
@@ -1628,8 +1645,8 @@ gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *device)
|
||||
|
||||
/* add device */
|
||||
widget = cc_color_device_new (device);
|
||||
g_signal_connect_object (widget, "expanded-changed",
|
||||
G_CALLBACK (gcm_prefs_device_expanded_changed_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (widget, "expanded-changed",
|
||||
G_CALLBACK (gcm_prefs_device_expanded_changed_cb), prefs);
|
||||
gtk_widget_show (widget);
|
||||
gtk_container_add (GTK_CONTAINER (prefs->list_box), widget);
|
||||
gtk_size_group_add_widget (prefs->list_box_size, widget);
|
||||
@@ -1639,8 +1656,8 @@ gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *device)
|
||||
|
||||
/* watch for changes */
|
||||
g_ptr_array_add (prefs->devices, g_object_ref (device));
|
||||
g_signal_connect_object (device, "changed",
|
||||
G_CALLBACK (gcm_prefs_device_changed_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (device, "changed",
|
||||
G_CALLBACK (gcm_prefs_device_changed_cb), prefs);
|
||||
gtk_list_box_invalidate_sort (prefs->list_box);
|
||||
}
|
||||
|
||||
@@ -1742,8 +1759,9 @@ gcm_prefs_get_devices_cb (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_list_box_row_selected_cb (CcColorPanel *panel,
|
||||
GtkListBoxRow *row)
|
||||
gcm_prefs_list_box_row_selected_cb (GtkListBox *list_box,
|
||||
GtkListBoxRow *row,
|
||||
CcColorPanel *panel)
|
||||
{
|
||||
gcm_prefs_refresh_toolbar_buttons (panel);
|
||||
}
|
||||
@@ -1795,12 +1813,13 @@ gcm_prefs_refresh_toolbar_buttons (CcColorPanel *panel)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_list_box_row_activated_cb (CcColorPanel *prefs,
|
||||
GtkListBoxRow *row)
|
||||
gcm_prefs_list_box_row_activated_cb (GtkListBox *list_box,
|
||||
GtkListBoxRow *row,
|
||||
CcColorPanel *prefs)
|
||||
{
|
||||
if (CC_IS_COLOR_PROFILE (row))
|
||||
{
|
||||
gcm_prefs_device_profile_enable_cb (prefs);
|
||||
gcm_prefs_device_profile_enable_cb (NULL, prefs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1833,7 +1852,7 @@ gcm_prefs_connect_cb (GObject *object,
|
||||
|
||||
/* get devices */
|
||||
cd_client_get_devices (prefs->client,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
gcm_prefs_get_devices_cb,
|
||||
prefs);
|
||||
}
|
||||
@@ -1866,9 +1885,9 @@ gcm_prefs_is_livecd (void)
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_window_realize_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_window_realize_cb (GtkWidget *widget, CcColorPanel *prefs)
|
||||
{
|
||||
prefs->main_window = gtk_widget_get_toplevel (GTK_WIDGET (prefs));
|
||||
prefs->main_window = gtk_widget_get_toplevel (widget);
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -1907,12 +1926,41 @@ static void
|
||||
cc_color_panel_dispose (GObject *object)
|
||||
{
|
||||
CcColorPanel *prefs = CC_COLOR_PANEL (object);
|
||||
CdDevice *device;
|
||||
guint i;
|
||||
|
||||
/* stop the EggListView from firing when it gets disposed */
|
||||
if (prefs->list_box_selected_id != 0)
|
||||
{
|
||||
g_signal_handler_disconnect (prefs->list_box,
|
||||
prefs->list_box_selected_id);
|
||||
prefs->list_box_selected_id = 0;
|
||||
|
||||
/* row-activated event should be connected at this point */
|
||||
g_signal_handler_disconnect (prefs->list_box,
|
||||
prefs->list_box_activated_id);
|
||||
prefs->list_box_activated_id = 0;
|
||||
}
|
||||
|
||||
/* stop the devices from emitting after the ListBox has been disposed */
|
||||
if (prefs->devices != NULL)
|
||||
{
|
||||
for (i = 0; i < prefs->devices->len; i++)
|
||||
{
|
||||
device = g_ptr_array_index (prefs->devices, i);
|
||||
g_signal_handlers_disconnect_by_func (device,
|
||||
G_CALLBACK (gcm_prefs_device_changed_cb),
|
||||
CC_COLOR_PANEL (object));
|
||||
}
|
||||
g_clear_pointer (&prefs->devices, g_ptr_array_unref);
|
||||
}
|
||||
|
||||
g_cancellable_cancel (prefs->cancellable);
|
||||
g_clear_object (&prefs->settings);
|
||||
g_clear_object (&prefs->settings_colord);
|
||||
g_clear_object (&prefs->cancellable);
|
||||
g_clear_object (&prefs->client);
|
||||
g_clear_object (&prefs->current_device);
|
||||
g_clear_pointer (&prefs->devices, g_ptr_array_unref);
|
||||
g_clear_object (&prefs->calibrate);
|
||||
g_clear_object (&prefs->list_box_size);
|
||||
g_clear_pointer (&prefs->sensors, g_ptr_array_unref);
|
||||
@@ -2049,6 +2097,7 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (prefs));
|
||||
|
||||
prefs->cancellable = g_cancellable_new ();
|
||||
prefs->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
|
||||
/* can do native display calibration using colord-session */
|
||||
@@ -2060,67 +2109,67 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
prefs->settings_colord = g_settings_new (COLORD_SETTINGS_SCHEMA);
|
||||
|
||||
/* assign buttons */
|
||||
g_signal_connect_object (prefs->toolbutton_profile_add, "clicked",
|
||||
G_CALLBACK (gcm_prefs_profile_add_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->toolbutton_profile_remove, "clicked",
|
||||
G_CALLBACK (gcm_prefs_profile_remove_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->toolbutton_profile_view, "clicked",
|
||||
G_CALLBACK (gcm_prefs_profile_view_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->toolbutton_profile_add, "clicked",
|
||||
G_CALLBACK (gcm_prefs_profile_add_cb), prefs);
|
||||
g_signal_connect (prefs->toolbutton_profile_remove, "clicked",
|
||||
G_CALLBACK (gcm_prefs_profile_remove_cb), prefs);
|
||||
g_signal_connect (prefs->toolbutton_profile_view, "clicked",
|
||||
G_CALLBACK (gcm_prefs_profile_view_cb), prefs);
|
||||
|
||||
/* href */
|
||||
g_signal_connect_object (prefs->label_assign_warning, "activate-link",
|
||||
G_CALLBACK (gcm_prefs_profile_assign_link_activate_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->label_assign_warning, "activate-link",
|
||||
G_CALLBACK (gcm_prefs_profile_assign_link_activate_cb), prefs);
|
||||
|
||||
/* add columns to profile tree view */
|
||||
gcm_prefs_add_profiles_columns (prefs, GTK_TREE_VIEW (prefs->treeview_assign));
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview_assign));
|
||||
g_signal_connect_object (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_profiles_treeview_clicked_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->treeview_assign, "row-activated",
|
||||
G_CALLBACK (gcm_prefs_profiles_row_activated_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_profiles_treeview_clicked_cb),
|
||||
prefs);
|
||||
g_signal_connect (GTK_TREE_VIEW (prefs->treeview_assign), "row-activated",
|
||||
G_CALLBACK (gcm_prefs_profiles_row_activated_cb),
|
||||
prefs);
|
||||
|
||||
g_signal_connect_object (prefs->toolbutton_device_default, "clicked",
|
||||
G_CALLBACK (gcm_prefs_default_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->toolbutton_device_enable, "clicked",
|
||||
G_CALLBACK (gcm_prefs_device_profile_enable_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->toolbutton_device_calibrate, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calibrate_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->toolbutton_device_default, "clicked",
|
||||
G_CALLBACK (gcm_prefs_default_cb), prefs);
|
||||
g_signal_connect (prefs->toolbutton_device_enable, "clicked",
|
||||
G_CALLBACK (gcm_prefs_device_profile_enable_cb), prefs);
|
||||
g_signal_connect (prefs->toolbutton_device_calibrate, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calibrate_cb), prefs);
|
||||
|
||||
context = gtk_widget_get_style_context (prefs->toolbar_devices);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
|
||||
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
|
||||
|
||||
/* set up assign dialog */
|
||||
g_signal_connect_object (prefs->dialog_assign, "delete-event",
|
||||
G_CALLBACK (gcm_prefs_profile_delete_event_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->dialog_assign, "delete-event",
|
||||
G_CALLBACK (gcm_prefs_profile_delete_event_cb), prefs);
|
||||
|
||||
g_signal_connect_object (prefs->button_assign_cancel, "clicked",
|
||||
G_CALLBACK (gcm_prefs_button_assign_cancel_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->button_assign_ok, "clicked",
|
||||
G_CALLBACK (gcm_prefs_button_assign_ok_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->button_assign_cancel, "clicked",
|
||||
G_CALLBACK (gcm_prefs_button_assign_cancel_cb), prefs);
|
||||
g_signal_connect (prefs->button_assign_ok, "clicked",
|
||||
G_CALLBACK (gcm_prefs_button_assign_ok_cb), prefs);
|
||||
|
||||
/* setup icc profiles list */
|
||||
g_signal_connect_object (prefs->button_assign_import, "clicked",
|
||||
G_CALLBACK (gcm_prefs_button_assign_import_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->button_assign_import, "clicked",
|
||||
G_CALLBACK (gcm_prefs_button_assign_import_cb), prefs);
|
||||
|
||||
/* setup the calibration helper */
|
||||
g_signal_connect_object (prefs->assistant_calib, "delete-event",
|
||||
G_CALLBACK (gcm_prefs_calib_delete_event_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->assistant_calib, "apply",
|
||||
G_CALLBACK (gcm_prefs_calib_apply_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->assistant_calib, "cancel",
|
||||
G_CALLBACK (gcm_prefs_calib_cancel_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->assistant_calib, "close",
|
||||
G_CALLBACK (gcm_prefs_calib_cancel_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->assistant_calib, "prepare",
|
||||
G_CALLBACK (gcm_prefs_calib_prepare_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->assistant_calib, "delete-event",
|
||||
G_CALLBACK (gcm_prefs_calib_delete_event_cb),
|
||||
prefs);
|
||||
g_signal_connect (prefs->assistant_calib, "apply",
|
||||
G_CALLBACK (gcm_prefs_calib_apply_cb),
|
||||
prefs);
|
||||
g_signal_connect (prefs->assistant_calib, "cancel",
|
||||
G_CALLBACK (gcm_prefs_calib_cancel_cb),
|
||||
prefs);
|
||||
g_signal_connect (prefs->assistant_calib, "close",
|
||||
G_CALLBACK (gcm_prefs_calib_cancel_cb),
|
||||
prefs);
|
||||
g_signal_connect (prefs->assistant_calib, "prepare",
|
||||
G_CALLBACK (gcm_prefs_calib_prepare_cb),
|
||||
prefs);
|
||||
|
||||
/* setup the calibration helper ::TreeView */
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview_calib_quality));
|
||||
@@ -2128,9 +2177,9 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
gtk_tree_model_foreach (model,
|
||||
cc_color_panel_treeview_quality_default_cb,
|
||||
selection);
|
||||
g_signal_connect_object (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_quality_treeview_clicked_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_quality_treeview_clicked_cb),
|
||||
prefs);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set (renderer,
|
||||
@@ -2158,9 +2207,9 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview_calib_sensor));
|
||||
g_signal_connect_object (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_sensor_treeview_clicked_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_sensor_treeview_clicked_cb),
|
||||
prefs);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set (renderer,
|
||||
@@ -2175,9 +2224,9 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview_calib_kind));
|
||||
g_signal_connect_object (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_kind_treeview_clicked_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_kind_treeview_clicked_cb),
|
||||
prefs);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set (renderer,
|
||||
@@ -2198,9 +2247,9 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview_calib_temp));
|
||||
g_signal_connect_object (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_temp_treeview_clicked_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (gcm_prefs_calib_temp_treeview_clicked_cb),
|
||||
prefs);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set (renderer,
|
||||
@@ -2213,8 +2262,8 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
gtk_tree_view_column_set_expand (column, TRUE);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (prefs->treeview_calib_temp),
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
g_signal_connect_object (prefs->entry_calib_title, "notify::text",
|
||||
G_CALLBACK (gcm_prefs_title_entry_changed_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->entry_calib_title, "notify::text",
|
||||
G_CALLBACK (gcm_prefs_title_entry_changed_cb), prefs);
|
||||
|
||||
/* use a device client array */
|
||||
prefs->client = cd_client_new ();
|
||||
@@ -2239,12 +2288,14 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
gtk_list_box_set_selection_mode (prefs->list_box,
|
||||
GTK_SELECTION_SINGLE);
|
||||
gtk_list_box_set_activate_on_single_click (prefs->list_box, FALSE);
|
||||
g_signal_connect_object (prefs->list_box, "row-selected",
|
||||
G_CALLBACK (gcm_prefs_list_box_row_selected_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->list_box, "row-activated",
|
||||
G_CALLBACK (gcm_prefs_list_box_row_activated_cb),
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
prefs->list_box_selected_id =
|
||||
g_signal_connect (prefs->list_box, "row-selected",
|
||||
G_CALLBACK (gcm_prefs_list_box_row_selected_cb),
|
||||
prefs);
|
||||
prefs->list_box_activated_id =
|
||||
g_signal_connect (prefs->list_box, "row-activated",
|
||||
G_CALLBACK (gcm_prefs_list_box_row_activated_cb),
|
||||
prefs);
|
||||
prefs->list_box_size = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (prefs->frame_devices), GTK_WIDGET (prefs->list_box));
|
||||
@@ -2252,7 +2303,7 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
|
||||
/* connect to colord */
|
||||
cd_client_connect (prefs->client,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
prefs->cancellable,
|
||||
gcm_prefs_connect_cb,
|
||||
prefs);
|
||||
|
||||
@@ -2270,14 +2321,14 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
/* show the confirmation export page if we are running from a LiveCD */
|
||||
prefs->is_live_cd = gcm_prefs_is_livecd ();
|
||||
gtk_widget_set_visible (prefs->box_calib_summary, prefs->is_live_cd);
|
||||
g_signal_connect_object (prefs->button_calib_export, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calib_export_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->button_calib_upload, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calib_upload_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (prefs->label_calib_summary_message, "activate-link",
|
||||
G_CALLBACK (gcm_prefs_calib_export_link_cb), prefs, G_CONNECT_SWAPPED);
|
||||
g_signal_connect (prefs->button_calib_export, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calib_export_cb), prefs);
|
||||
g_signal_connect (prefs->button_calib_upload, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calib_upload_cb), prefs);
|
||||
g_signal_connect (prefs->label_calib_summary_message, "activate-link",
|
||||
G_CALLBACK (gcm_prefs_calib_export_link_cb), prefs);
|
||||
|
||||
g_signal_connect (prefs, "realize",
|
||||
G_CALLBACK (gcm_prefs_window_realize_cb),
|
||||
NULL);
|
||||
prefs);
|
||||
}
|
||||
|
||||
@@ -762,8 +762,10 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="HdyClamp">
|
||||
<object class="HdyColumn">
|
||||
<property name="visible">True</property>
|
||||
<property name="maximum_width">600</property>
|
||||
<property name="linear_growth_width">400</property>
|
||||
<property name="margin_top">32</property>
|
||||
<property name="margin_bottom">32</property>
|
||||
<property name="margin_start">12</property>
|
||||
|
||||
@@ -40,6 +40,8 @@ struct _CcColorProfile
|
||||
GtkWidget *widget_image;
|
||||
GtkWidget *widget_info;
|
||||
GSettings *settings;
|
||||
guint device_changed_id;
|
||||
guint profile_changed_id;
|
||||
};
|
||||
|
||||
#define GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD "recalibrate-printer-threshold"
|
||||
@@ -330,6 +332,11 @@ cc_color_profile_finalize (GObject *object)
|
||||
{
|
||||
CcColorProfile *color_profile = CC_COLOR_PROFILE (object);
|
||||
|
||||
if (color_profile->device_changed_id > 0)
|
||||
g_signal_handler_disconnect (color_profile->device, color_profile->device_changed_id);
|
||||
if (color_profile->profile_changed_id > 0)
|
||||
g_signal_handler_disconnect (color_profile->profile, color_profile->profile_changed_id);
|
||||
|
||||
g_free (color_profile->sortable);
|
||||
g_object_unref (color_profile->device);
|
||||
g_object_unref (color_profile->profile);
|
||||
@@ -339,12 +346,13 @@ cc_color_profile_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_profile_changed_cb (CcColorProfile *color_profile)
|
||||
cc_color_profile_changed_cb (CdDevice *device,
|
||||
CcColorProfile *color_profile)
|
||||
{
|
||||
g_autoptr(CdProfile) profile = NULL;
|
||||
|
||||
/* check to see if the default has changed */
|
||||
profile = cd_device_get_default_profile (color_profile->device);
|
||||
profile = cd_device_get_default_profile (device);
|
||||
if (profile != NULL)
|
||||
color_profile->is_default = g_strcmp0 (cd_profile_get_object_path (profile),
|
||||
cd_profile_get_object_path (color_profile->profile)) == 0;
|
||||
@@ -376,13 +384,15 @@ cc_color_profile_constructed (GObject *object)
|
||||
g_autofree gchar *title = NULL;
|
||||
|
||||
/* watch to see if the default changes */
|
||||
g_signal_connect_object (color_profile->device, "changed",
|
||||
G_CALLBACK (cc_color_profile_changed_cb), color_profile, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (color_profile->profile, "changed",
|
||||
G_CALLBACK (cc_color_profile_changed_cb), color_profile, G_CONNECT_SWAPPED);
|
||||
color_profile->device_changed_id =
|
||||
g_signal_connect (color_profile->device, "changed",
|
||||
G_CALLBACK (cc_color_profile_changed_cb), color_profile);
|
||||
color_profile->profile_changed_id =
|
||||
g_signal_connect (color_profile->profile, "changed",
|
||||
G_CALLBACK (cc_color_profile_changed_cb), color_profile);
|
||||
|
||||
/* sort the profiles in the list by:
|
||||
* 1. their device (required)
|
||||
* 1. thier device (required)
|
||||
* 2. the data source (so calibration profiles are listed before autogenerated ones)
|
||||
* 3. the date the profiles were created (newest first)
|
||||
* 4. the alpha sorting of the filename
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/control-center/color">
|
||||
<file preprocess="xml-stripblanks">cc-color-calibrate.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-color-panel.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gnome/control-center/color">
|
||||
<file preprocess="xml-stripblanks">color-calibrate.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -27,8 +27,8 @@ sources = files(
|
||||
)
|
||||
|
||||
resource_data = files(
|
||||
'cc-color-calibrate.ui',
|
||||
'cc-color-panel.ui',
|
||||
'color-calibrate.ui',
|
||||
)
|
||||
|
||||
sources += gnome.compile_resources(
|
||||
@@ -47,6 +47,11 @@ deps = common_deps + [
|
||||
dependency('libsoup-2.4')
|
||||
]
|
||||
|
||||
cflags += [
|
||||
'-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir),
|
||||
'-DBINDIR="@0@"'.format(control_center_bindir)
|
||||
]
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
sources: sources,
|
||||
|
||||
@@ -233,7 +233,7 @@ cc_hostname_entry_constructed (GObject *object)
|
||||
else
|
||||
gtk_entry_set_text (GTK_ENTRY (self), "");
|
||||
|
||||
g_signal_connect (self, "changed", G_CALLBACK (text_changed_cb), NULL);
|
||||
g_signal_connect (G_OBJECT (self), "changed", G_CALLBACK (text_changed_cb), self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <config.h>
|
||||
#include "cc-language-chooser.h"
|
||||
#include "cc-language-row.h"
|
||||
#include "cc-common-resources.h"
|
||||
|
||||
#include <locale.h>
|
||||
@@ -40,12 +39,12 @@
|
||||
struct _CcLanguageChooser {
|
||||
GtkDialog parent_instance;
|
||||
|
||||
GtkSearchEntry *language_filter_entry;
|
||||
GtkListBox *language_listbox;
|
||||
GtkListBoxRow *more_row;
|
||||
GtkSearchBar *search_bar;
|
||||
GtkButton *select_button;
|
||||
|
||||
GtkWidget *select_button;
|
||||
GtkWidget *no_results;
|
||||
GtkListBoxRow *more_item;
|
||||
GtkWidget *search_bar;
|
||||
GtkWidget *language_filter_entry;
|
||||
GtkWidget *language_listbox;
|
||||
gboolean showing_extra;
|
||||
gchar *language;
|
||||
gchar **filter_words;
|
||||
@@ -53,27 +52,134 @@ struct _CcLanguageChooser {
|
||||
|
||||
G_DEFINE_TYPE (CcLanguageChooser, cc_language_chooser, GTK_TYPE_DIALOG)
|
||||
|
||||
static void
|
||||
add_all_languages (CcLanguageChooser *self)
|
||||
static GtkWidget *
|
||||
language_widget_new (const gchar *locale_id,
|
||||
gboolean is_extra)
|
||||
{
|
||||
g_auto(GStrv) locale_ids = NULL;
|
||||
g_autoptr(GHashTable) initial = NULL;
|
||||
g_autofree gchar *language_code = NULL;
|
||||
g_autofree gchar *country_code = NULL;
|
||||
g_autofree gchar *language = NULL;
|
||||
g_autofree gchar *country = NULL;
|
||||
g_autofree gchar *language_local = NULL;
|
||||
g_autofree gchar *country_local = NULL;
|
||||
GtkWidget *row;
|
||||
GtkWidget *box;
|
||||
GtkWidget *language_label;
|
||||
GtkWidget *check;
|
||||
GtkWidget *country_label;
|
||||
|
||||
gnome_parse_locale (locale_id, &language_code, &country_code, NULL, NULL);
|
||||
language = gnome_get_language_from_code (language_code, locale_id);
|
||||
country = gnome_get_country_from_code (country_code, locale_id);
|
||||
language_local = gnome_get_language_from_code (language_code, NULL);
|
||||
country_local = gnome_get_country_from_code (country_code, NULL);
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
gtk_widget_show (box);
|
||||
gtk_widget_set_margin_top (box, 12);
|
||||
gtk_widget_set_margin_bottom (box, 12);
|
||||
gtk_widget_set_margin_start (box, 18);
|
||||
gtk_widget_set_margin_end (box, 18);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
|
||||
language_label = gtk_label_new (language);
|
||||
gtk_widget_show (language_label);
|
||||
gtk_label_set_xalign (GTK_LABEL (language_label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), language_label, FALSE, TRUE, 0);
|
||||
|
||||
check = gtk_image_new ();
|
||||
gtk_widget_hide (check);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (check), "object-select-symbolic", GTK_ICON_SIZE_MENU);
|
||||
g_object_set (check, "icon-size", GTK_ICON_SIZE_MENU, NULL);
|
||||
gtk_box_pack_start (GTK_BOX (box), check, FALSE, FALSE, 0);
|
||||
|
||||
country_label = gtk_label_new (country);
|
||||
gtk_widget_show (country_label);
|
||||
gtk_label_set_xalign (GTK_LABEL (country_label), 1.0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (country_label), "dim-label");
|
||||
gtk_box_pack_start (GTK_BOX (box), country_label, TRUE, TRUE, 0);
|
||||
|
||||
g_object_set_data (G_OBJECT (row), "check", check);
|
||||
g_object_set_data_full (G_OBJECT (row), "locale-id", g_strdup (locale_id), g_free);
|
||||
g_object_set_data_full (G_OBJECT (row), "language", g_steal_pointer (&language), g_free);
|
||||
g_object_set_data_full (G_OBJECT (row), "country", g_steal_pointer (&country), g_free);
|
||||
g_object_set_data_full (G_OBJECT (row), "language-local", g_steal_pointer (&language_local), g_free);
|
||||
g_object_set_data_full (G_OBJECT (row), "country-local", g_steal_pointer (&country_local), g_free);
|
||||
g_object_set_data (G_OBJECT (row), "is-extra", GUINT_TO_POINTER (is_extra));
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
static GtkListBoxRow *
|
||||
more_widget_new (void)
|
||||
{
|
||||
GtkWidget *box, *row;
|
||||
GtkWidget *arrow;
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_widget_show (box);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_widget_set_tooltip_text (box, _("More…"));
|
||||
|
||||
arrow = gtk_image_new_from_icon_name ("view-more-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_show (arrow);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (arrow), "dim-label");
|
||||
gtk_widget_set_margin_top (box, 10);
|
||||
gtk_widget_set_margin_bottom (box, 10);
|
||||
gtk_box_pack_start (GTK_BOX (box), arrow, TRUE, TRUE, 0);
|
||||
|
||||
return GTK_LIST_BOX_ROW (row);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
no_results_widget_new (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_label_new (_("No languages found"));
|
||||
gtk_widget_set_sensitive (widget, FALSE);
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
add_languages (CcLanguageChooser *chooser,
|
||||
gchar **locale_ids,
|
||||
GHashTable *initial)
|
||||
{
|
||||
while (*locale_ids) {
|
||||
gchar *locale_id;
|
||||
gboolean is_initial;
|
||||
GtkWidget *widget;
|
||||
|
||||
locale_id = *locale_ids;
|
||||
locale_ids ++;
|
||||
|
||||
if (!cc_common_language_has_font (locale_id))
|
||||
continue;
|
||||
|
||||
is_initial = (g_hash_table_lookup (initial, locale_id) != NULL);
|
||||
widget = language_widget_new (locale_id, !is_initial);
|
||||
gtk_widget_show (widget);
|
||||
gtk_container_add (GTK_CONTAINER (chooser->language_listbox), widget);
|
||||
}
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (chooser->language_listbox), GTK_WIDGET (chooser->more_item));
|
||||
}
|
||||
|
||||
static void
|
||||
add_all_languages (CcLanguageChooser *chooser)
|
||||
{
|
||||
gchar **locale_ids;
|
||||
GHashTable *initial;
|
||||
|
||||
locale_ids = gnome_get_all_locales ();
|
||||
initial = cc_common_language_get_initial_languages ();
|
||||
for (int i = 0; locale_ids[i] != NULL; i++) {
|
||||
CcLanguageRow *row;
|
||||
gboolean is_initial;
|
||||
|
||||
if (!cc_common_language_has_font (locale_ids[i]))
|
||||
continue;
|
||||
|
||||
row = cc_language_row_new (locale_ids[i]);
|
||||
gtk_widget_show (GTK_WIDGET (row));
|
||||
is_initial = (g_hash_table_lookup (initial, locale_ids[i]) != NULL);
|
||||
cc_language_row_set_is_extra (row, !is_initial);
|
||||
gtk_list_box_prepend (self->language_listbox, GTK_WIDGET (row));
|
||||
}
|
||||
add_languages (chooser, locale_ids, initial);
|
||||
g_hash_table_destroy (initial);
|
||||
g_strfreev (locale_ids);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -96,46 +202,46 @@ static gboolean
|
||||
language_visible (GtkListBoxRow *row,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcLanguageChooser *self = user_data;
|
||||
CcLanguageChooser *chooser = user_data;
|
||||
g_autofree gchar *language = NULL;
|
||||
g_autofree gchar *country = NULL;
|
||||
g_autofree gchar *language_local = NULL;
|
||||
g_autofree gchar *country_local = NULL;
|
||||
gboolean is_extra;
|
||||
gboolean visible;
|
||||
|
||||
if (row == self->more_row)
|
||||
return !self->showing_extra;
|
||||
if (row == chooser->more_item)
|
||||
return !chooser->showing_extra;
|
||||
|
||||
if (!CC_IS_LANGUAGE_ROW (row))
|
||||
return TRUE;
|
||||
is_extra = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (row), "is-extra"));
|
||||
|
||||
if (!self->showing_extra && cc_language_row_get_is_extra (CC_LANGUAGE_ROW (row)))
|
||||
if (!chooser->showing_extra && is_extra)
|
||||
return FALSE;
|
||||
|
||||
if (!self->filter_words)
|
||||
if (!chooser->filter_words)
|
||||
return TRUE;
|
||||
|
||||
language =
|
||||
cc_util_normalize_casefold_and_unaccent (cc_language_row_get_language (CC_LANGUAGE_ROW (row)));
|
||||
visible = match_all (self->filter_words, language);
|
||||
cc_util_normalize_casefold_and_unaccent (g_object_get_data (G_OBJECT (row), "language"));
|
||||
visible = match_all (chooser->filter_words, language);
|
||||
if (visible)
|
||||
return TRUE;
|
||||
|
||||
country =
|
||||
cc_util_normalize_casefold_and_unaccent (cc_language_row_get_country (CC_LANGUAGE_ROW (row)));
|
||||
visible = match_all (self->filter_words, country);
|
||||
cc_util_normalize_casefold_and_unaccent (g_object_get_data (G_OBJECT (row), "country"));
|
||||
visible = match_all (chooser->filter_words, country);
|
||||
if (visible)
|
||||
return TRUE;
|
||||
|
||||
language_local =
|
||||
cc_util_normalize_casefold_and_unaccent (cc_language_row_get_language_local (CC_LANGUAGE_ROW (row)));
|
||||
visible = match_all (self->filter_words, language_local);
|
||||
cc_util_normalize_casefold_and_unaccent (g_object_get_data (G_OBJECT (row), "language-local"));
|
||||
visible = match_all (chooser->filter_words, language_local);
|
||||
if (visible)
|
||||
return TRUE;
|
||||
|
||||
country_local =
|
||||
cc_util_normalize_casefold_and_unaccent (cc_language_row_get_country_local (CC_LANGUAGE_ROW (row)));
|
||||
return match_all (self->filter_words, country_local);
|
||||
cc_util_normalize_casefold_and_unaccent (g_object_get_data (G_OBJECT (row), "country-local"));
|
||||
return match_all (chooser->filter_words, country_local);
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -143,153 +249,184 @@ sort_languages (GtkListBoxRow *a,
|
||||
GtkListBoxRow *b,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *la, *lb, *ca, *cb;
|
||||
int d;
|
||||
|
||||
if (!CC_IS_LANGUAGE_ROW (a))
|
||||
if (g_object_get_data (G_OBJECT (a), "locale-id") == NULL)
|
||||
return 1;
|
||||
if (!CC_IS_LANGUAGE_ROW (b))
|
||||
if (g_object_get_data (G_OBJECT (b), "locale-id") == NULL)
|
||||
return -1;
|
||||
|
||||
d = g_strcmp0 (cc_language_row_get_language (CC_LANGUAGE_ROW (a)), cc_language_row_get_language (CC_LANGUAGE_ROW (b)));
|
||||
la = g_object_get_data (G_OBJECT (a), "language");
|
||||
lb = g_object_get_data (G_OBJECT (b), "language");
|
||||
d = g_strcmp0 (la, lb);
|
||||
if (d != 0)
|
||||
return d;
|
||||
|
||||
return g_strcmp0 (cc_language_row_get_country (CC_LANGUAGE_ROW (a)), cc_language_row_get_country (CC_LANGUAGE_ROW (b)));
|
||||
ca = g_object_get_data (G_OBJECT (a), "country");
|
||||
cb = g_object_get_data (G_OBJECT (b), "country");
|
||||
return g_strcmp0 (ca, cb);
|
||||
}
|
||||
|
||||
static void
|
||||
language_filter_entry_search_changed_cb (CcLanguageChooser *self)
|
||||
filter_changed (CcLanguageChooser *chooser)
|
||||
{
|
||||
g_autofree gchar *filter_contents = NULL;
|
||||
|
||||
g_clear_pointer (&self->filter_words, g_strfreev);
|
||||
g_clear_pointer (&chooser->filter_words, g_strfreev);
|
||||
|
||||
filter_contents =
|
||||
cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (self->language_filter_entry)));
|
||||
cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (chooser->language_filter_entry)));
|
||||
if (!filter_contents) {
|
||||
gtk_list_box_invalidate_filter (self->language_listbox);
|
||||
gtk_list_box_invalidate_filter (GTK_LIST_BOX (chooser->language_listbox));
|
||||
gtk_list_box_set_placeholder (GTK_LIST_BOX (chooser->language_listbox), NULL);
|
||||
return;
|
||||
}
|
||||
self->filter_words = g_strsplit_set (g_strstrip (filter_contents), " ", 0);
|
||||
gtk_list_box_invalidate_filter (self->language_listbox);
|
||||
chooser->filter_words = g_strsplit_set (g_strstrip (filter_contents), " ", 0);
|
||||
gtk_list_box_set_placeholder (GTK_LIST_BOX (chooser->language_listbox), chooser->no_results);
|
||||
gtk_list_box_invalidate_filter (GTK_LIST_BOX (chooser->language_listbox));
|
||||
}
|
||||
|
||||
static void
|
||||
show_more (CcLanguageChooser *self, gboolean visible)
|
||||
show_more (CcLanguageChooser *chooser, gboolean visible)
|
||||
{
|
||||
gint width, height;
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (self), &width, &height);
|
||||
gtk_widget_set_size_request (GTK_WIDGET (self), width, height);
|
||||
gtk_window_get_size (GTK_WINDOW (chooser), &width, &height);
|
||||
gtk_widget_set_size_request (GTK_WIDGET (chooser), width, height);
|
||||
|
||||
gtk_search_bar_set_search_mode (self->search_bar, visible);
|
||||
gtk_widget_grab_focus (visible ? GTK_WIDGET (self->language_filter_entry) : GTK_WIDGET (self->language_listbox));
|
||||
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (chooser->search_bar), visible);
|
||||
gtk_widget_grab_focus (visible ? chooser->language_filter_entry : chooser->language_listbox);
|
||||
|
||||
self->showing_extra = visible;
|
||||
chooser->showing_extra = visible;
|
||||
|
||||
gtk_list_box_invalidate_filter (self->language_listbox);
|
||||
gtk_list_box_invalidate_filter (GTK_LIST_BOX (chooser->language_listbox));
|
||||
}
|
||||
|
||||
static void
|
||||
set_locale_id (CcLanguageChooser *self,
|
||||
set_locale_id (CcLanguageChooser *chooser,
|
||||
const gchar *locale_id)
|
||||
{
|
||||
g_autoptr(GList) children = NULL;
|
||||
GList *l;
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->select_button), FALSE);
|
||||
gtk_widget_set_sensitive (chooser->select_button, FALSE);
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (self->language_listbox));
|
||||
children = gtk_container_get_children (GTK_CONTAINER (chooser->language_listbox));
|
||||
for (l = children; l; l = l->next) {
|
||||
GtkListBoxRow *row = l->data;
|
||||
|
||||
if (!CC_IS_LANGUAGE_ROW (row))
|
||||
GtkWidget *row = l->data;
|
||||
GtkWidget *check = g_object_get_data (G_OBJECT (row), "check");
|
||||
const gchar *language = g_object_get_data (G_OBJECT (row), "locale-id");
|
||||
if (check == NULL || language == NULL)
|
||||
continue;
|
||||
|
||||
if (g_strcmp0 (locale_id, cc_language_row_get_locale_id (CC_LANGUAGE_ROW (row))) == 0) {
|
||||
cc_language_row_set_checked (CC_LANGUAGE_ROW (row), TRUE);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->select_button), TRUE);
|
||||
if (g_strcmp0 (locale_id, language) == 0) {
|
||||
gboolean is_extra;
|
||||
|
||||
gtk_widget_show (check);
|
||||
gtk_widget_set_sensitive (chooser->select_button, TRUE);
|
||||
|
||||
/* make sure the selected language is shown */
|
||||
if (!self->showing_extra && cc_language_row_get_is_extra (CC_LANGUAGE_ROW (row))) {
|
||||
cc_language_row_set_is_extra (CC_LANGUAGE_ROW (row), FALSE);
|
||||
gtk_list_box_invalidate_filter (self->language_listbox);
|
||||
is_extra = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (row), "is-extra"));
|
||||
if (!chooser->showing_extra && is_extra) {
|
||||
g_object_set_data (G_OBJECT (row), "is-extra", GINT_TO_POINTER (FALSE));
|
||||
gtk_list_box_invalidate_filter (GTK_LIST_BOX (chooser->language_listbox));
|
||||
}
|
||||
} else {
|
||||
cc_language_row_set_checked (CC_LANGUAGE_ROW (row), FALSE);
|
||||
gtk_widget_hide (check);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (self->language);
|
||||
self->language = g_strdup (locale_id);
|
||||
g_free (chooser->language);
|
||||
chooser->language = g_strdup (locale_id);
|
||||
}
|
||||
|
||||
static void
|
||||
language_listbox_row_activated_cb (CcLanguageChooser *self, GtkListBoxRow *row)
|
||||
row_activated (GtkListBox *box,
|
||||
GtkListBoxRow *row,
|
||||
CcLanguageChooser *chooser)
|
||||
{
|
||||
const gchar *new_locale_id;
|
||||
gchar *new_locale_id;
|
||||
|
||||
if (row == self->more_row) {
|
||||
show_more (self, TRUE);
|
||||
if (row == NULL)
|
||||
return;
|
||||
|
||||
if (row == chooser->more_item) {
|
||||
show_more (chooser, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CC_IS_LANGUAGE_ROW (row))
|
||||
return;
|
||||
|
||||
new_locale_id = cc_language_row_get_locale_id (CC_LANGUAGE_ROW (row));
|
||||
if (g_strcmp0 (new_locale_id, self->language) == 0) {
|
||||
gtk_dialog_response (GTK_DIALOG (self),
|
||||
gtk_dialog_get_response_for_widget (GTK_DIALOG (self),
|
||||
GTK_WIDGET (self->select_button)));
|
||||
new_locale_id = g_object_get_data (G_OBJECT (row), "locale-id");
|
||||
if (g_strcmp0 (new_locale_id, chooser->language) == 0) {
|
||||
gtk_dialog_response (GTK_DIALOG (chooser),
|
||||
gtk_dialog_get_response_for_widget (GTK_DIALOG (chooser),
|
||||
chooser->select_button));
|
||||
} else {
|
||||
set_locale_id (self, new_locale_id);
|
||||
set_locale_id (chooser, new_locale_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate_default_cb (CcLanguageChooser *self)
|
||||
activate_default (GtkWindow *window,
|
||||
CcLanguageChooser *chooser)
|
||||
{
|
||||
GtkWidget *focus;
|
||||
gchar *locale_id;
|
||||
|
||||
focus = gtk_window_get_focus (GTK_WINDOW (self));
|
||||
if (!focus || !CC_IS_LANGUAGE_ROW (focus))
|
||||
focus = gtk_window_get_focus (window);
|
||||
if (!focus)
|
||||
return;
|
||||
|
||||
if (g_strcmp0 (cc_language_row_get_locale_id (CC_LANGUAGE_ROW (focus)), self->language) == 0)
|
||||
locale_id = g_object_get_data (G_OBJECT (focus), "locale-id");
|
||||
if (g_strcmp0 (locale_id, chooser->language) == 0)
|
||||
return;
|
||||
|
||||
g_signal_stop_emission_by_name (GTK_WINDOW (self), "activate-default");
|
||||
g_signal_stop_emission_by_name (window, "activate-default");
|
||||
gtk_widget_activate (focus);
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_chooser_init (CcLanguageChooser *self)
|
||||
cc_language_chooser_init (CcLanguageChooser *chooser)
|
||||
{
|
||||
g_resources_register (cc_common_get_resource ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
gtk_widget_init_template (GTK_WIDGET (chooser));
|
||||
|
||||
gtk_list_box_set_sort_func (self->language_listbox,
|
||||
sort_languages, self, NULL);
|
||||
gtk_list_box_set_filter_func (self->language_listbox,
|
||||
language_visible, self, NULL);
|
||||
gtk_list_box_set_selection_mode (self->language_listbox,
|
||||
chooser->more_item = more_widget_new ();
|
||||
gtk_widget_show (GTK_WIDGET (chooser->more_item));
|
||||
/* We ref-sink here so we can reuse this widget multiple times */
|
||||
chooser->no_results = g_object_ref_sink (no_results_widget_new ());
|
||||
gtk_widget_show (chooser->no_results);
|
||||
|
||||
gtk_list_box_set_sort_func (GTK_LIST_BOX (chooser->language_listbox),
|
||||
sort_languages, chooser, NULL);
|
||||
gtk_list_box_set_filter_func (GTK_LIST_BOX (chooser->language_listbox),
|
||||
language_visible, chooser, NULL);
|
||||
gtk_list_box_set_selection_mode (GTK_LIST_BOX (chooser->language_listbox),
|
||||
GTK_SELECTION_NONE);
|
||||
gtk_list_box_set_header_func (self->language_listbox,
|
||||
gtk_list_box_set_header_func (GTK_LIST_BOX (chooser->language_listbox),
|
||||
cc_list_box_update_header_func, NULL, NULL);
|
||||
add_all_languages (self);
|
||||
add_all_languages (chooser);
|
||||
|
||||
gtk_list_box_invalidate_filter (self->language_listbox);
|
||||
g_signal_connect_swapped (chooser->language_filter_entry, "search-changed",
|
||||
G_CALLBACK (filter_changed), chooser);
|
||||
|
||||
g_signal_connect (chooser->language_listbox, "row-activated",
|
||||
G_CALLBACK (row_activated), chooser);
|
||||
|
||||
gtk_list_box_invalidate_filter (GTK_LIST_BOX (chooser->language_listbox));
|
||||
|
||||
g_signal_connect (chooser, "activate-default",
|
||||
G_CALLBACK (activate_default), chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_language_chooser_dispose (GObject *object)
|
||||
{
|
||||
CcLanguageChooser *self = CC_LANGUAGE_CHOOSER (object);
|
||||
CcLanguageChooser *chooser = CC_LANGUAGE_CHOOSER (object);
|
||||
|
||||
g_clear_pointer (&self->filter_words, g_strfreev);
|
||||
g_clear_pointer (&self->language, g_free);
|
||||
g_clear_object (&chooser->no_results);
|
||||
g_clear_pointer (&chooser->filter_words, g_strfreev);
|
||||
g_clear_pointer (&chooser->language, g_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_language_chooser_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -304,15 +441,10 @@ cc_language_chooser_class_init (CcLanguageChooserClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/common/cc-language-chooser.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, select_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, search_bar);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, language_filter_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, language_listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, more_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, search_bar);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageChooser, select_button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, activate_default_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, language_filter_entry_search_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, language_listbox_row_activated_cb);
|
||||
}
|
||||
|
||||
CcLanguageChooser *
|
||||
@@ -324,24 +456,24 @@ cc_language_chooser_new (void)
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_chooser_clear_filter (CcLanguageChooser *self)
|
||||
cc_language_chooser_clear_filter (CcLanguageChooser *chooser)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LANGUAGE_CHOOSER (self));
|
||||
gtk_entry_set_text (GTK_ENTRY (self->language_filter_entry), "");
|
||||
show_more (self, FALSE);
|
||||
g_return_if_fail (CC_IS_LANGUAGE_CHOOSER (chooser));
|
||||
gtk_entry_set_text (GTK_ENTRY (chooser->language_filter_entry), "");
|
||||
show_more (chooser, FALSE);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_language_chooser_get_language (CcLanguageChooser *self)
|
||||
cc_language_chooser_get_language (CcLanguageChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_CHOOSER (self), NULL);
|
||||
return self->language;
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_CHOOSER (chooser), NULL);
|
||||
return chooser->language;
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_chooser_set_language (CcLanguageChooser *self,
|
||||
cc_language_chooser_set_language (CcLanguageChooser *chooser,
|
||||
const gchar *language)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LANGUAGE_CHOOSER (self));
|
||||
set_locale_id (self, language);
|
||||
g_return_if_fail (CC_IS_LANGUAGE_CHOOSER (chooser));
|
||||
set_locale_id (chooser, language);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
<property name="title" translatable="yes">Select Language</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="default_width">340</property>
|
||||
<property name="default_height">475</property>
|
||||
<signal name="activate-default" handler="activate_default_cb"/>
|
||||
<property name="default_width">400</property>
|
||||
<property name="default_height">350</property>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="select_button">
|
||||
<property name="label" translatable="yes">_Select</property>
|
||||
@@ -43,7 +42,6 @@
|
||||
<object class="GtkSearchEntry" id="language_filter_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="width_chars">30</property>
|
||||
<signal name="search-changed" handler="language_filter_entry_search_changed_cb" object="CcLanguageChooser" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -62,43 +60,6 @@
|
||||
<property name="vexpand">True</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="valign">fill</property>
|
||||
<signal name="row-activated" handler="language_listbox_row_activated_cb" object="CcLanguageChooser" swapped="yes"/>
|
||||
<child type="placeholder">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">No languages found</property>
|
||||
<property name="sensitive">False</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- "More" row -->
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="more_row">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">10</property>
|
||||
<property name="tooltip_markup" translatable="yes">More…</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="icon-name">view-more-symbolic</property>
|
||||
<property name="icon-size">1</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2020 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 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/>.
|
||||
*/
|
||||
|
||||
#include "cc-language-row.h"
|
||||
#include "cc-common-resources.h"
|
||||
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnome-desktop/gnome-languages.h>
|
||||
|
||||
struct _CcLanguageRow {
|
||||
GtkListBoxRow parent_instance;
|
||||
|
||||
GtkImage *check_image;
|
||||
GtkLabel *country_label;
|
||||
GtkLabel *language_label;
|
||||
|
||||
gchar *locale_id;
|
||||
gchar *language;
|
||||
gchar *language_local;
|
||||
gchar *country;
|
||||
gchar *country_local;
|
||||
|
||||
gboolean is_extra;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcLanguageRow, cc_language_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
static gchar *
|
||||
get_language_label (const gchar *language_code,
|
||||
const gchar *modifier,
|
||||
const gchar *locale_id)
|
||||
{
|
||||
g_autofree gchar *language = NULL;
|
||||
|
||||
language = gnome_get_language_from_code (language_code, locale_id);
|
||||
|
||||
if (modifier == NULL)
|
||||
return g_steal_pointer (&language);
|
||||
else
|
||||
{
|
||||
g_autofree gchar *t_mod = gnome_get_translated_modifier (modifier, locale_id);
|
||||
return g_strdup_printf ("%s — %s", language, t_mod);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_language_row_dispose (GObject *object)
|
||||
{
|
||||
CcLanguageRow *self = CC_LANGUAGE_ROW (object);
|
||||
|
||||
g_clear_pointer (&self->locale_id, g_free);
|
||||
g_clear_pointer (&self->country, g_free);
|
||||
g_clear_pointer (&self->country_local, g_free);
|
||||
g_clear_pointer (&self->language, g_free);
|
||||
g_clear_pointer (&self->language_local, g_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_language_row_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_row_class_init (CcLanguageRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = cc_language_row_dispose;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/common/cc-language-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageRow, check_image);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageRow, country_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcLanguageRow, language_label);
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_row_init (CcLanguageRow *self)
|
||||
{
|
||||
g_resources_register (cc_common_get_resource ());
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
CcLanguageRow *
|
||||
cc_language_row_new (const gchar *locale_id)
|
||||
{
|
||||
CcLanguageRow *self;
|
||||
g_autofree gchar *language_code = NULL;
|
||||
g_autofree gchar *country_code = NULL;
|
||||
g_autofree gchar *modifier = NULL;
|
||||
|
||||
self = CC_LANGUAGE_ROW (g_object_new (CC_TYPE_LANGUAGE_ROW, NULL));
|
||||
self->locale_id = g_strdup (locale_id);
|
||||
|
||||
gnome_parse_locale (locale_id, &language_code, &country_code, NULL, &modifier);
|
||||
|
||||
self->language = get_language_label (language_code, modifier, locale_id);
|
||||
self->language_local = get_language_label (language_code, modifier, NULL);
|
||||
gtk_label_set_label (self->language_label, self->language);
|
||||
|
||||
self->country = gnome_get_country_from_code (country_code, locale_id);
|
||||
self->country_local = gnome_get_country_from_code (country_code, NULL);
|
||||
gtk_label_set_label (self->country_label, self->country);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_language_row_get_locale_id (CcLanguageRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_ROW (self), NULL);
|
||||
return self->locale_id;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_language_row_get_language (CcLanguageRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_ROW (self), NULL);
|
||||
return self->language;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_language_row_get_language_local (CcLanguageRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_ROW (self), NULL);
|
||||
return self->language_local;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_language_row_get_country (CcLanguageRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_ROW (self), NULL);
|
||||
return self->country;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_language_row_get_country_local (CcLanguageRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_ROW (self), NULL);
|
||||
return self->country_local;
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_row_set_checked (CcLanguageRow *self, gboolean checked)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LANGUAGE_ROW (self));
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->check_image), checked);
|
||||
}
|
||||
|
||||
void
|
||||
cc_language_row_set_is_extra (CcLanguageRow *self, gboolean is_extra)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LANGUAGE_ROW (self));
|
||||
self->is_extra = is_extra;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_language_row_get_is_extra (CcLanguageRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LANGUAGE_ROW (self), FALSE);
|
||||
return self->is_extra;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2020 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 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_LANGUAGE_ROW (cc_language_row_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcLanguageRow, cc_language_row, CC, LANGUAGE_ROW, GtkListBoxRow)
|
||||
|
||||
CcLanguageRow *cc_language_row_new (const gchar *locale_id);
|
||||
|
||||
const gchar *cc_language_row_get_locale_id (CcLanguageRow *row);
|
||||
|
||||
const gchar *cc_language_row_get_language (CcLanguageRow *row);
|
||||
|
||||
const gchar *cc_language_row_get_language_local (CcLanguageRow *row);
|
||||
|
||||
const gchar *cc_language_row_get_country (CcLanguageRow *row);
|
||||
|
||||
const gchar *cc_language_row_get_country_local (CcLanguageRow *row);
|
||||
|
||||
void cc_language_row_set_checked (CcLanguageRow *row, gboolean checked);
|
||||
|
||||
void cc_language_row_set_is_extra (CcLanguageRow *row, gboolean is_extra);
|
||||
|
||||
gboolean cc_language_row_get_is_extra (CcLanguageRow *row);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcLanguageRow" parent="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="language_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="check_image">
|
||||
<property name="visible">False</property>
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="country_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="hexpand">True</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,399 +0,0 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* cc-list-row.c
|
||||
*
|
||||
* Copyright 2019 Purism SPC
|
||||
*
|
||||
* 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):
|
||||
* Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "cc-list-row"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "cc-list-row.h"
|
||||
|
||||
struct _CcListRow
|
||||
{
|
||||
GtkListBoxRow parent_instance;
|
||||
|
||||
GtkBox *box;
|
||||
GtkLabel *title;
|
||||
GtkLabel *subtitle;
|
||||
GtkLabel *secondary_label;
|
||||
GtkImage *icon;
|
||||
|
||||
GtkSwitch *enable_switch;
|
||||
gboolean show_switch;
|
||||
|
||||
gboolean switch_active;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcListRow, cc_list_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_SUBTITLE,
|
||||
PROP_SECONDARY_LABEL,
|
||||
PROP_ICON_NAME,
|
||||
PROP_SHOW_SWITCH,
|
||||
PROP_ACTIVE,
|
||||
PROP_BOLD,
|
||||
PROP_USE_UNDERLINE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
static void
|
||||
cc_list_row_activated_cb (CcListRow *self,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
g_assert (CC_IS_LIST_ROW (self));
|
||||
|
||||
if (!self->show_switch || row != GTK_LIST_BOX_ROW (self))
|
||||
return;
|
||||
|
||||
cc_list_row_activate (self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_parent_changed_cb (CcListRow *self)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
|
||||
g_assert (CC_IS_LIST_ROW (self));
|
||||
|
||||
parent = gtk_widget_get_parent (GTK_WIDGET (self));
|
||||
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
g_return_if_fail (GTK_IS_LIST_BOX (parent));
|
||||
g_signal_connect_object (parent, "row-activated",
|
||||
G_CALLBACK (cc_list_row_activated_cb),
|
||||
self, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_switch_active_cb (CcListRow *self)
|
||||
{
|
||||
gboolean switch_active;
|
||||
|
||||
g_assert (CC_IS_LIST_ROW (self));
|
||||
g_assert (self->show_switch);
|
||||
|
||||
switch_active = gtk_switch_get_active (self->enable_switch);
|
||||
|
||||
if (switch_active == self->switch_active)
|
||||
return;
|
||||
|
||||
self->switch_active = switch_active;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIVE]);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcListRow *self = (CcListRow *)object;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SECONDARY_LABEL:
|
||||
g_value_set_string (value, gtk_label_get_label (self->secondary_label));
|
||||
break;
|
||||
|
||||
case PROP_ACTIVE:
|
||||
g_value_set_boolean (value, self->switch_active);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcListRow *self = (CcListRow *)object;
|
||||
PangoAttrList *attributes;
|
||||
PangoAttribute *attribute;
|
||||
gint margin;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
gtk_label_set_label (self->title, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SUBTITLE:
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->subtitle),
|
||||
g_value_get_string (value) != NULL);
|
||||
gtk_label_set_label (self->subtitle, g_value_get_string (value));
|
||||
if (g_value_get_string (value) != NULL)
|
||||
margin = 6;
|
||||
else
|
||||
margin = 12;
|
||||
g_object_set (self->box,
|
||||
"margin-top", margin,
|
||||
"margin-bottom", margin,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case PROP_SECONDARY_LABEL:
|
||||
gtk_label_set_label (self->secondary_label, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_ICON_NAME:
|
||||
cc_list_row_set_icon_name (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SHOW_SWITCH:
|
||||
cc_list_row_set_show_switch (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_USE_UNDERLINE:
|
||||
gtk_label_set_use_underline (self->title, g_value_get_boolean (value));
|
||||
gtk_label_set_use_underline (self->subtitle, g_value_get_boolean (value));
|
||||
gtk_label_set_mnemonic_widget (self->title, GTK_WIDGET (self));
|
||||
gtk_label_set_mnemonic_widget (self->subtitle, GTK_WIDGET (self));
|
||||
break;
|
||||
|
||||
case PROP_ACTIVE:
|
||||
g_signal_handlers_block_by_func (self->enable_switch,
|
||||
cc_list_row_switch_active_cb, self);
|
||||
gtk_switch_set_active (self->enable_switch,
|
||||
g_value_get_boolean (value));
|
||||
self->switch_active = g_value_get_boolean (value);
|
||||
g_signal_handlers_unblock_by_func (self->enable_switch,
|
||||
cc_list_row_switch_active_cb, self);
|
||||
break;
|
||||
|
||||
case PROP_BOLD:
|
||||
if (g_value_get_boolean (value))
|
||||
attribute = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
else
|
||||
attribute = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);
|
||||
|
||||
attributes = gtk_label_get_attributes (self->title);
|
||||
|
||||
if (!attributes)
|
||||
attributes = pango_attr_list_new ();
|
||||
else
|
||||
pango_attr_list_ref (attributes);
|
||||
|
||||
pango_attr_list_change (attributes, attribute);
|
||||
gtk_label_set_attributes (self->title, attributes);
|
||||
pango_attr_list_unref (attributes);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_class_init (CcListRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->get_property = cc_list_row_get_property;
|
||||
object_class->set_property = cc_list_row_set_property;
|
||||
|
||||
properties[PROP_TITLE] =
|
||||
g_param_spec_string ("title",
|
||||
"Title",
|
||||
"List row primary title",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SUBTITLE] =
|
||||
g_param_spec_string ("subtitle",
|
||||
"Subtitle",
|
||||
"List row primary subtitle",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SECONDARY_LABEL] =
|
||||
g_param_spec_string ("secondary-label",
|
||||
"Secondary Label",
|
||||
"Set Secondary Label",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_ICON_NAME] =
|
||||
g_param_spec_string ("icon-name",
|
||||
"Icon Name",
|
||||
"Secondary Icon name",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SHOW_SWITCH] =
|
||||
g_param_spec_boolean ("show-switch",
|
||||
"Show Switch",
|
||||
"Whether to show a switch at the end of row",
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_ACTIVE] =
|
||||
g_param_spec_boolean ("active",
|
||||
"Active",
|
||||
"The active state of the switch",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_BOLD] =
|
||||
g_param_spec_boolean ("bold",
|
||||
"Bold",
|
||||
"Whether title is bold or not",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_USE_UNDERLINE] =
|
||||
g_param_spec_boolean ("use-underline",
|
||||
"Use underline",
|
||||
"If set, text prefixed with underline shall be used as mnemonic",
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gnome/control-center/"
|
||||
"common/cc-list-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcListRow, box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcListRow, title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcListRow, subtitle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcListRow, secondary_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcListRow, icon);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcListRow, enable_switch);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, cc_list_row_switch_active_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_init (CcListRow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
g_signal_connect_object (self, "notify::parent",
|
||||
G_CALLBACK (cc_list_row_parent_changed_cb),
|
||||
self, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
void
|
||||
cc_list_row_set_icon_name (CcListRow *self,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LIST_ROW (self));
|
||||
g_return_if_fail (!self->show_switch);
|
||||
|
||||
if (icon_name)
|
||||
g_object_set (self->icon, "icon-name", icon_name, NULL);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->icon), icon_name != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cc_list_row_set_show_switch (CcListRow *self,
|
||||
gboolean show_switch)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LIST_ROW (self));
|
||||
|
||||
self->show_switch = !!show_switch;
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->enable_switch), self->show_switch);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->icon), !self->show_switch);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->secondary_label), !self->show_switch);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_list_row_get_active (CcListRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_LIST_ROW (self), FALSE);
|
||||
g_return_val_if_fail (self->show_switch, FALSE);
|
||||
|
||||
return self->switch_active;
|
||||
}
|
||||
|
||||
void
|
||||
cc_list_row_activate (CcListRow *self)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LIST_ROW (self));
|
||||
g_return_if_fail (self->show_switch);
|
||||
|
||||
self->switch_active = !self->switch_active;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIVE]);
|
||||
|
||||
gtk_widget_activate (GTK_WIDGET (self->enable_switch));
|
||||
}
|
||||
|
||||
void
|
||||
cc_list_row_set_secondary_label (CcListRow *self,
|
||||
const gchar *label)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LIST_ROW (self));
|
||||
g_return_if_fail (!self->show_switch);
|
||||
|
||||
if (!label)
|
||||
label = "";
|
||||
|
||||
if (g_str_equal (label, gtk_label_get_label (self->secondary_label)))
|
||||
return;
|
||||
|
||||
gtk_label_set_text (self->secondary_label, label);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SECONDARY_LABEL]);
|
||||
}
|
||||
|
||||
void
|
||||
cc_list_row_set_secondary_markup (CcListRow *self,
|
||||
const gchar *markup)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LIST_ROW (self));
|
||||
g_return_if_fail (!self->show_switch);
|
||||
|
||||
if (!markup)
|
||||
markup = "";
|
||||
|
||||
if (g_str_equal (markup, gtk_label_get_label (self->secondary_label)))
|
||||
return;
|
||||
|
||||
gtk_label_set_markup (self->secondary_label, markup);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SECONDARY_LABEL]);
|
||||
}
|
||||
|
||||
void
|
||||
cc_list_row_set_switch_sensitive (CcListRow *self,
|
||||
gboolean sensitive)
|
||||
{
|
||||
g_return_if_fail (CC_IS_LIST_ROW (self));
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->enable_switch), sensitive);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* cc-list-row.h
|
||||
*
|
||||
* Copyright 2019 Purism SPC
|
||||
*
|
||||
* 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):
|
||||
* Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_LIST_ROW (cc_list_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcListRow, cc_list_row, CC, LIST_ROW, GtkListBoxRow)
|
||||
|
||||
void cc_list_row_set_icon_name (CcListRow *self,
|
||||
const gchar *icon_name);
|
||||
void cc_list_row_set_show_switch (CcListRow *self,
|
||||
gboolean show_switch);
|
||||
gboolean cc_list_row_get_active (CcListRow *self);
|
||||
void cc_list_row_activate (CcListRow *self);
|
||||
void cc_list_row_set_secondary_label (CcListRow *self,
|
||||
const gchar *label);
|
||||
void cc_list_row_set_secondary_markup (CcListRow *self,
|
||||
const gchar *markup);
|
||||
void cc_list_row_set_switch_sensitive (CcListRow *self,
|
||||
gboolean sensitive);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcListRow" parent="GtkListBoxRow">
|
||||
<property name="visible">1</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box">
|
||||
<property name="visible">1</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<!-- Title -->
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="visible">1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Subtitle -->
|
||||
<child>
|
||||
<object class="GtkLabel" id="subtitle">
|
||||
<property name="visible">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="max-width-chars">42</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<attributes>
|
||||
<attribute name="scale" value="0.83"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Secondary Label -->
|
||||
<child>
|
||||
<object class="GtkLabel" id="secondary_label">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="selectable" bind-source="CcListRow" bind-property="activatable" bind-flags="sync-create|invert-boolean" />
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Icon -->
|
||||
<child>
|
||||
<object class="GtkImage" id="icon">
|
||||
<property name="visible">0</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Switch -->
|
||||
<child>
|
||||
<object class="GtkSwitch" id="enable_switch">
|
||||
<property name="visible">0</property>
|
||||
<property name="can-focus">0</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::active" handler="cc_list_row_switch_active_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,110 +0,0 @@
|
||||
/* cc-permission-infobar.c
|
||||
*
|
||||
* Copyright (C) 2020 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>
|
||||
*
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "cc-permission-infobar"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "cc-permission-infobar.h"
|
||||
|
||||
struct _CcPermissionInfobar
|
||||
{
|
||||
GtkRevealer parent_instance;
|
||||
|
||||
GtkLabel *title;
|
||||
GtkLockButton *lock_button;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcPermissionInfobar, cc_permission_infobar, GTK_TYPE_REVEALER)
|
||||
|
||||
static void
|
||||
on_permission_changed (CcPermissionInfobar *self)
|
||||
{
|
||||
GPermission *permission;
|
||||
gboolean is_authorized;
|
||||
|
||||
permission = gtk_lock_button_get_permission (self->lock_button);
|
||||
is_authorized = g_permission_get_allowed (permission);
|
||||
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self), !is_authorized);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_permission_infobar_class_init (CcPermissionInfobarClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gnome/control-center/"
|
||||
"common/cc-permission-infobar.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcPermissionInfobar, title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcPermissionInfobar, lock_button);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_permission_infobar_init (CcPermissionInfobar *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
/* Set the default title. */
|
||||
cc_permission_infobar_set_title (self, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cc_permission_infobar_set_permission (CcPermissionInfobar *self,
|
||||
GPermission *permission)
|
||||
{
|
||||
g_return_if_fail (CC_IS_PERMISSION_INFOBAR (self));
|
||||
|
||||
gtk_lock_button_set_permission (self->lock_button, permission);
|
||||
|
||||
g_signal_connect_object (permission, "notify",
|
||||
G_CALLBACK (on_permission_changed),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
on_permission_changed (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* cc_permission_infobar_set_title:
|
||||
* @self: a #CcPermissionInfobar
|
||||
* @title: (nullable): title to display in the infobar, or %NULL for the default
|
||||
*
|
||||
* Set the title text to display in the infobar.
|
||||
*/
|
||||
void
|
||||
cc_permission_infobar_set_title (CcPermissionInfobar *self,
|
||||
const gchar *title)
|
||||
{
|
||||
g_return_if_fail (CC_IS_PERMISSION_INFOBAR (self));
|
||||
|
||||
if (title == NULL)
|
||||
title = _("Unlock to Change Settings");
|
||||
|
||||
gtk_label_set_text (self->title, title);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user