Compare commits

..

30 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
b3a3c544b3 3.32.2 2019-05-24 15:48:24 -03:00
Jakub Steiner
afb6b2a713 Applications: use larger icons
- the new application icon style strongly advises to use
  sizes above 32px. Lower the whitespace to fit more items
- make fullcolor icons not semi-opaque
2019-05-24 15:42:09 -03:00
Charles Monzat
a28ac69531 Update French translation 2019-05-24 07:37:23 +00:00
Benjamin Berg
eaa4dd4aa3 sound: Clean up labels of devices without origin
Sound devices may not have an origin, in that case we ended up with a
trailing " - " in the label which should not be there. Add a check that
the origin is non-null and not an empty string and only show the devices
description otherwise.

(cherry picked from commit 6872c767bb)
2019-05-23 15:41:27 +02:00
Tim Sabsch
d0c76cff43 Update German translation 2019-05-12 10:29:48 +00:00
Dz Chen
055ab69378 Update Chinese (China) translation 2019-05-08 09:29:16 +00:00
Daniel Rusek
196477e60c Update Czech translation 2019-05-02 21:28:45 +00:00
Ethan Hsieh
9a67cd0884 power: correct the value of 90 minutes to 5400 2019-05-02 20:09:51 +12:00
Benjamin Berg
4d64299561 display: Fix crash if a monitor has no preferred mode
When a monitor has no current mode set and also no preferred mode we ran
into a crash. Simply select the first mode we can find as a further
fallback.

(cherry picked from commit f75c3a8471)
2019-04-30 16:56:18 +02:00
Fabio Tomat
49deb7796f Update Friulian translation 2019-04-26 14:06:39 +00:00
Balázs Meskó
3489e88acd Update Hungarian translation 2019-04-26 05:58:11 +00:00
Jiri Grönroos
1d4d5527b3 Update Finnish translation 2019-04-25 12:09:15 +00:00
Daniel Mustieles
7461501c5b Updated Spanish translation 2019-04-24 09:53:51 +02:00
Stas Solovey
077a7c4a64 Update Russian translation 2019-04-22 18:18:27 +00:00
Марко Костић
040c895208 Update Serbian translation 2019-04-18 22:10:09 +00:00
Daniel Șerbănescu
09356dbdc7 Update Romanian translation 2019-04-14 17:14:22 +00:00
Rafael Fontenelle
91130064e9 Update Brazilian Portuguese translation 2019-04-12 15:01:29 +00:00
Mario Blättermann
3c97de2121 Update German translation 2019-04-12 10:30:55 +00:00
Milo Casagrande
fb81c922c8 Update Italian translation 2019-04-12 10:06:18 +00:00
Kukuh Syafaat
2e363141eb Update Indonesian translation 2019-04-12 09:30:13 +00:00
Anders Jonsson
86c60f47b0 Update Swedish translation 2019-04-11 20:28:31 +00:00
Aurimas Černius
e6c0c0e1c1 Updated Lithuanian translation 2019-04-11 22:51:48 +03:00
Piotr Drąg
738dbfb6ea Update Polish translation 2019-04-11 18:17:58 +02:00
Sebastien Bacher
809fac82df night-light: set screen temperature strings as translatable
Fixes #437
2019-04-11 14:09:38 +00:00
Robert Ancell
5fac79b089 region: Fix input source options not being applied.
This was broken in a86cf1eca2 (3.32) when the input options dialog was converted
into a GtkPopover. Previously two GSettings objects were used, with one set to
'delay-apply' mode. The input source option didn't apply the changes.

The 'delay-apply' mode is from the original commit d3852fc831, however code was
simplified in b3199dd to only set one setting. This meant that the delay is no
longer necessary.

Fixes #440
2019-04-09 14:15:11 +12:00
Jordi Mas
725a921028 Update Catalan translation 2019-04-07 21:58:24 +02:00
Felipe Borges
8e78f8438a mouse: Reinstate keyboard navigation in the panel
Fixes #246


(cherry picked from commit 6046d562cf)
2019-04-01 12:41:48 +00:00
Carmen Bianca BAKKER
419d2f99d4 Update Esperanto translation 2019-04-01 06:02:06 +00:00
Dušan Kazik
5c1dedbebd Update Slovak translation 2019-03-30 07:06:03 +00:00
Dušan Kazik
901bb6b366 Update Slovak translation 2019-03-29 16:08:57 +00:00
782 changed files with 248550 additions and 312847 deletions

View File

@@ -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"

View File

@@ -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.

View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -1,4 +1,4 @@
[![Build Status](https://gitlab.gnome.org/GNOME/gnome-control-center/badges/master/pipeline.svg)](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
[![Build Status](https://gitlab.gnome.org/GNOME/gnome-control-center/badges/master/build.svg)](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
[![Coverage report](https://gitlab.gnome.org/GNOME/gnome-control-center/badges/master/coverage.svg)](https://gnome.pages.gitlab.gnome.org/gnome-control-center/)
[![License](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](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

View 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"]

View 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"]

View 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"]

View File

@@ -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

View File

@@ -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"
]
}
]

View File

@@ -1,4 +0,0 @@
#!/bin/sh
gtkdocize --flavour no-tmpl
autoreconf -if

View File

@@ -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

View File

@@ -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)

View 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@"

View 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

View 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@"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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>

View File

@@ -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

View File

@@ -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)

View File

@@ -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')

View File

@@ -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>

View File

@@ -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

View File

@@ -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 &lt;a href=&quot;privacy&quot;&gt;Privacy&lt;/a&gt; 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>

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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
)

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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>

View 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>

View File

@@ -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);
}

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View 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 */

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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 */

View 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;
}

View 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__ */

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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>

View 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);
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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>

View File

@@ -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]);
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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
)

View File

@@ -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;
}

View 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;
}

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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>

View File

@@ -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,

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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
)

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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,

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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