Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
735980860b | ||
|
|
6a9742986f | ||
|
|
c95b557f3f | ||
|
|
3d23aa2d13 | ||
|
|
740959f161 | ||
|
|
aadf89b442 | ||
|
|
90cf8afd25 | ||
|
|
aa721dc9ac | ||
|
|
3c06c2e199 | ||
|
|
47fed006d7 | ||
|
|
3ba0e1253b | ||
|
|
d3929cf3ed | ||
|
|
825a5b485b | ||
|
|
d95957068b | ||
|
|
32d3bb2d18 | ||
|
|
b771b2dad8 | ||
|
|
7f2ffcca2f | ||
|
|
a35e4aa214 | ||
|
|
5a985d85a8 | ||
|
|
9ced38ea65 | ||
|
|
d9ea855408 | ||
|
|
022934bfb3 | ||
|
|
ef683cafc0 | ||
|
|
6a61f969ac | ||
|
|
fa3afbf370 | ||
|
|
e480efa58e | ||
|
|
d8caedd80e | ||
|
|
daabfb5a8c | ||
|
|
c30358bea1 | ||
|
|
cc75d32c62 | ||
|
|
f2e1dfd161 | ||
|
|
3bfc5f71d0 | ||
|
|
83f774f9ea | ||
|
|
37bd61ccd6 | ||
|
|
db7c2b2cc5 | ||
|
|
ac3839d0c9 | ||
|
|
5650a5f5c7 | ||
|
|
dfbeace734 | ||
|
|
7c6e4d4174 | ||
|
|
753ba80b3b | ||
|
|
3e9d08287c | ||
|
|
815ed9169d | ||
|
|
c4a91dc613 | ||
|
|
7c04266599 | ||
|
|
cdd1118add | ||
|
|
bd23f743d3 | ||
|
|
0da2ef8b0b | ||
|
|
b5f191894c | ||
|
|
4c52d5b646 | ||
|
|
44ee3e5fa2 |
@@ -1,5 +1,5 @@
|
||||
include:
|
||||
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/fedora.yml'
|
||||
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/5888c7388134cbe4661600222fe9befb10441f6e/templates/fedora.yml'
|
||||
|
||||
variables:
|
||||
FDO_UPSTREAM_REPO: gnome/gnome-control-center
|
||||
@@ -40,11 +40,6 @@ stages:
|
||||
meson test -C _build --verbose --no-stdsplit
|
||||
|
||||
.fedora.container.common:
|
||||
# As of 2022-03-07 runners not tagged with "crun" have broken seccomp rules
|
||||
# affecting the close_range syscall and breaking g_spawn
|
||||
# Note that "asan" tests are disabled for the same reason, see below.
|
||||
# https://gitlab.gnome.org/Infrastructure/GitLab/-/issues/545
|
||||
tags: [ crun ]
|
||||
variables:
|
||||
# When branching a stable release, change 'main'
|
||||
# to the release number/branch to ensure that
|
||||
@@ -52,8 +47,8 @@ stages:
|
||||
# stable branch.
|
||||
# Could probably also switch away from rawhide,
|
||||
# to stable fedora branch as well.
|
||||
FDO_DISTRIBUTION_TAG: '2022-03-29.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: rawhide
|
||||
FDO_DISTRIBUTION_TAG: '2021-07-22.0-gnome-40'
|
||||
FDO_DISTRIBUTION_VERSION: '34'
|
||||
|
||||
#############################################
|
||||
# Create CI Docker Images #
|
||||
@@ -92,18 +87,16 @@ build.container.fedora@x86_64:
|
||||
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
|
||||
gtk4-devel
|
||||
intltool
|
||||
libadwaita-devel
|
||||
libcanberra-devel
|
||||
libgtop2-devel
|
||||
libgudev-devel
|
||||
libnma-devel
|
||||
libnotify-devel
|
||||
libpwquality-devel
|
||||
libsmbclient-devel
|
||||
libsoup-devel
|
||||
@@ -122,56 +115,12 @@ build.container.fedora@x86_64:
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
libsecret-devel
|
||||
geocode-glib-devel
|
||||
libgweather-devel
|
||||
lcms2-devel
|
||||
geoclue2-devel
|
||||
libnotify-devel
|
||||
alsa-lib-devel
|
||||
nss-devel
|
||||
gcr-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 .. && \
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-desktop.git && \
|
||||
cd gnome-desktop && \
|
||||
meson . _build --prefix=/usr -Ddesktop_docs=false && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-bluetooth.git && \
|
||||
cd gnome-bluetooth && \
|
||||
meson . _build --prefix=/usr -Dsendto=false && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
git clone https://gitlab.gnome.org/GNOME/libnma.git && \
|
||||
cd libnma && \
|
||||
meson . _build --prefix=/usr -Dlibnma_gtk4=true -Dmobile_broadband_provider_info=false -Dgcr=false -Dgtk_doc=false && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
git clone https://github.com/hughsie/colord-gtk.git && \
|
||||
cd colord-gtk && \
|
||||
meson . _build --prefix=/usr -Dgtk4=true -Ddocs=false -Dtests=false -Dman=false && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
git clone https://gitlab.gnome.org/GNOME/libgweather.git && \
|
||||
cd libgweather && \
|
||||
meson . _build --prefix=/usr -Denable_vala=false -Dgtk_doc=false -Dintrospection=false && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd .. && \
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-settings-daemon.git && \
|
||||
cd gnome-settings-daemon && \
|
||||
meson . _build --prefix=/usr && \
|
||||
ninja -C _build && \
|
||||
ninja -C _build install && \
|
||||
cd ..
|
||||
|
||||
##
|
||||
@@ -222,7 +171,6 @@ test:
|
||||
- build
|
||||
|
||||
script:
|
||||
- dnf -y install setxkbmap
|
||||
- *environment_information
|
||||
- *run_tests
|
||||
|
||||
@@ -248,7 +196,7 @@ coverage:
|
||||
BUILD_OPTS: "-Db_coverage=true"
|
||||
coverage: '/^Lines:.\d+.\d+.(\d+\.\d+\%)/'
|
||||
only:
|
||||
- main@GNOME/gnome-control-center
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
script:
|
||||
- *environment_information
|
||||
@@ -288,7 +236,7 @@ pages:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- main@GNOME/gnome-control-center
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
except:
|
||||
variables:
|
||||
@@ -302,7 +250,7 @@ pages:
|
||||
##
|
||||
flatpak:
|
||||
stage: manual
|
||||
image: quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
artifacts:
|
||||
name: package
|
||||
paths:
|
||||
@@ -354,7 +302,7 @@ flatpak:
|
||||
except:
|
||||
- tags
|
||||
- gnome-3-.*
|
||||
- main@GNOME/gnome-control-center
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
|
||||
# Runs the sanitizers [address, thread, undefined, and memory].
|
||||
@@ -375,19 +323,18 @@ flatpak:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
- $CI_COMMIT_TITLE =~ /^Update.*translation$/
|
||||
|
||||
# Disabled because we currently need "crun" tagged runners, see above
|
||||
#asan:
|
||||
# extends:
|
||||
# - '.fdo.distribution-image@fedora'
|
||||
# - '.fedora.container.common'
|
||||
# <<: *sanitizer
|
||||
# # ASAN requires debugging capabilities
|
||||
# tags: [ asan ]
|
||||
# stage: manual
|
||||
# when: manual
|
||||
# variables:
|
||||
# BUILD_OPTS: "-Db_sanitize=address"
|
||||
# LSAN_OPTIONS: "suppressions=${CI_PROJECT_DIR}/build-aux/ci/lsan.supp"
|
||||
asan:
|
||||
extends:
|
||||
- '.fdo.distribution-image@fedora'
|
||||
- '.fedora.container.common'
|
||||
<<: *sanitizer
|
||||
# ASAN requires debugging capabilities
|
||||
tags: [ asan ]
|
||||
stage: manual
|
||||
when: manual
|
||||
variables:
|
||||
BUILD_OPTS: "-Db_sanitize=address"
|
||||
LSAN_OPTIONS: "suppressions=${CI_PROJECT_DIR}/build-aux/ci/lsan.supp"
|
||||
|
||||
tsan:
|
||||
extends:
|
||||
|
||||
@@ -4,7 +4,7 @@ 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/main/docs/CONTRIBUTING.md#communication-guideline
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guideline
|
||||
|
||||
-->
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ 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/main/docs/CONTRIBUTING.md#communication-guideline
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guideline
|
||||
|
||||
-->
|
||||
|
||||
|
||||
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "subprojects/gvc"]
|
||||
path = subprojects/gvc
|
||||
url = https://gitlab.gnome.org/GNOME/libgnome-volume-control.git
|
||||
[submodule "subprojects/libhandy"]
|
||||
path = subprojects/libhandy
|
||||
url = https://gitlab.gnome.org/GNOME/libhandy.git
|
||||
|
||||
222
NEWS
@@ -1,239 +1,47 @@
|
||||
================
|
||||
Version 43.0
|
||||
Version 40.9
|
||||
================
|
||||
|
||||
- Drop unused argument for i18n.merge_file() in Meson rules
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 43.rc
|
||||
================
|
||||
|
||||
- Fix initial AM/PM label value
|
||||
- Remove no longer used icon
|
||||
- Select panel only if non-folded when search is canceled
|
||||
- Updated translations
|
||||
|
||||
Appearance
|
||||
- Allow backgrounds to use any image format
|
||||
|
||||
Device Security
|
||||
- Several UI improvements
|
||||
|
||||
Display
|
||||
- Fix primary monitor selection
|
||||
|
||||
Info
|
||||
- Improve dark theme support
|
||||
|
||||
Keyboard
|
||||
- Fix activation of input source toggle button
|
||||
- Improve handling of Shift shortcuts
|
||||
|
||||
Power
|
||||
- Fix blank screen and power button behavior settings
|
||||
|
||||
Printers
|
||||
- Show empty state after removing last printer
|
||||
|
||||
Search
|
||||
- Fix Move Up and Move Down actions
|
||||
- Do not invert order when constructing modes
|
||||
|
||||
Sound
|
||||
- Fix sound alert selection
|
||||
|
||||
Wacom
|
||||
- Better support Wacom Express Key Remote
|
||||
- Update the volume-slider after getting a valid stream
|
||||
- Clear level bar when stream is empty
|
||||
|
||||
================
|
||||
Version 43.beta
|
||||
Version 40.7
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Cellular
|
||||
- Add WWAN 5G connection support
|
||||
|
||||
Device Security
|
||||
- Polish failure messages
|
||||
- Various style updates
|
||||
|
||||
Display
|
||||
- Support privacy screens
|
||||
|
||||
Info
|
||||
- Show build id in a separate row
|
||||
|
||||
Network
|
||||
- Fix VPN empty state
|
||||
|
||||
Sound
|
||||
- Update default sounds
|
||||
|
||||
User Accounts
|
||||
- Fix back button not appearing sometimes
|
||||
|
||||
================
|
||||
Version 43.alpha
|
||||
================
|
||||
|
||||
- Improved accessibility in various panels
|
||||
- New Device Security panel
|
||||
- Updated translations
|
||||
|
||||
Date & Time
|
||||
- Update visual style of the timezone map
|
||||
|
||||
Display
|
||||
- Various visual improvements
|
||||
|
||||
Sound
|
||||
- Remove dog barking sounds
|
||||
|
||||
================
|
||||
Version 42.1
|
||||
Version 40.6
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Display
|
||||
- Various small behavior improvements
|
||||
- Fix monitor labels
|
||||
|
||||
Network
|
||||
- Improve handling of VPN connections
|
||||
|
||||
Online Accounts
|
||||
- Fix behavior of helper application on X11
|
||||
- Fix changes to online accounts services not applying correctly
|
||||
|
||||
User Accounts
|
||||
- Various small polishments
|
||||
|
||||
Wacom
|
||||
- Properly translate various strings
|
||||
|
||||
================
|
||||
Version 42.0
|
||||
Version 40.1
|
||||
================
|
||||
|
||||
- Updated AppData screenshots
|
||||
- Re-enable tests
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 42.rc
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Keyboard
|
||||
- Restore _GNOME_WM_KEYBINDINGS support
|
||||
|
||||
User Accounts
|
||||
- Bring back Fingerprint dialog
|
||||
- Fix avatar loading
|
||||
|
||||
Wacom
|
||||
- Bring back empty state
|
||||
|
||||
================
|
||||
Version 42.beta
|
||||
================
|
||||
|
||||
- Port to GTK4
|
||||
- Various UI polish changes
|
||||
- New symbolic icons for panels
|
||||
- Updated translations
|
||||
|
||||
Application
|
||||
- Implement new design
|
||||
|
||||
Background
|
||||
- Introduce dark & light mode selector
|
||||
- Rename to Appearance
|
||||
|
||||
Display
|
||||
- Implement new design
|
||||
|
||||
Region & Language
|
||||
- Implement new design
|
||||
|
||||
User Accounts
|
||||
- New design for the User Accounts panel
|
||||
|
||||
Wacom
|
||||
- Implement new design
|
||||
|
||||
================
|
||||
Version 41.0
|
||||
================
|
||||
|
||||
- Cleanup the development Flatpak manifest
|
||||
- Updated translations
|
||||
|
||||
User Accounts
|
||||
- Add parental controls keywords
|
||||
|
||||
================
|
||||
Version 41.rc1
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Cellular
|
||||
- Various translation fixes
|
||||
|
||||
User Accounts
|
||||
- Improve parental controls behavior
|
||||
|
||||
================
|
||||
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
|
||||
- Don't show GNOME micro version
|
||||
|
||||
Location
|
||||
- Fix permission store id (again)
|
||||
- Fix permission store table and id
|
||||
|
||||
Network
|
||||
- Show all IPv6 addresses for an interface
|
||||
- Display IPv6 gateway
|
||||
|
||||
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
|
||||
- Fix D-Bus proxy leak
|
||||
|
||||
================
|
||||
Version 40
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
|
||||
[](https://gnome.pages.gitlab.gnome.org/gnome-control-center/)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/COPYING)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
|
||||
[](https://gnome.pages.gitlab.gnome.org/gnome-control-center/)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/COPYING)
|
||||
|
||||
GNOME Settings
|
||||
====================
|
||||
@@ -60,4 +60,4 @@ 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/main/docs/CONTRIBUTING.md#communication-guidelines
|
||||
[communication-guidelines]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guidelines
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gnome-control-center",
|
||||
"rename-desktop-file" : "gnome-control-center.desktop",
|
||||
"tags" : [
|
||||
"devel"
|
||||
],
|
||||
@@ -12,6 +13,7 @@
|
||||
"--device=dri",
|
||||
"--env=DCONF_USER_CONFIG_DIR=.config/dconf",
|
||||
"--filesystem=host",
|
||||
"--own-name=org.gnome.ControlCenter",
|
||||
"--own-name=org.gnome.SessionManager",
|
||||
"--share=ipc",
|
||||
"--share=network",
|
||||
@@ -134,7 +136,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/libusb/libusb.git"
|
||||
"url" : "git://github.com/libusb/libusb.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -149,8 +151,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/hughsie/libgusb.git",
|
||||
"branch" : "main"
|
||||
"url" : "git://github.com/hughsie/libgusb.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -182,7 +183,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/gentoo/eudev.git"
|
||||
"url" : "git://github.com/gentoo/eudev.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -217,8 +218,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch" : "main",
|
||||
"url" : "https://github.com/hughsie/colord.git"
|
||||
"url" : "git://github.com/hughsie/colord.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -231,8 +231,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch" : "main",
|
||||
"url" : "https://github.com/hughsie/colord-gtk.git"
|
||||
"url" : "git://github.com/hughsie/colord-gtk.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -301,19 +300,19 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libgweather.git",
|
||||
"branch" : "main"
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libgweather.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "upower",
|
||||
"buildsystem" : "meson",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"-Dsystemdsystemunitdir=/app/lib/systemd/system",
|
||||
"-Dgtk-doc=false",
|
||||
"-Dman=false",
|
||||
"-Dintrospection=disabled"
|
||||
"--prefix=/app",
|
||||
"--with-systemdsystemunitdir=/app/lib/systemd/system",
|
||||
"--disable-gtk-doc",
|
||||
"--disable-man-pages",
|
||||
"--disable-tests"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -324,11 +323,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "libwacom",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Ddocumentation=disabled",
|
||||
"-Dtests=disabled"
|
||||
],
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
@@ -381,7 +376,6 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch": "main",
|
||||
"url" : "https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git"
|
||||
}
|
||||
]
|
||||
@@ -392,7 +386,6 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch": "main",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git"
|
||||
}
|
||||
]
|
||||
@@ -401,7 +394,6 @@
|
||||
"name" : "libnma",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dlibnma_gtk4=true",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dvapi=false"
|
||||
@@ -409,8 +401,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libnma.git",
|
||||
"branch" : "main"
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libnma.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -429,31 +420,25 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/network-manager-applet.git",
|
||||
"branch" : "main"
|
||||
"url" : "https://gitlab.gnome.org/GNOME/network-manager-applet.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "ModemManager",
|
||||
"buildsystem" : "meson",
|
||||
"buildsystem" : "autotools",
|
||||
"config-opts" : [
|
||||
"-Dintrospection=false",
|
||||
"-Dbash_completion=false",
|
||||
"-Dudevdir=/app/lib",
|
||||
"-Dsystemdsystemunitdir=/app/lib/systemd/system",
|
||||
"-Dmbim=false",
|
||||
"-Dplugin_dell=disabled",
|
||||
"-Dplugin_foxconn=disabled",
|
||||
"-Dplugin_fibocom=disabled",
|
||||
"-Dqmi=false",
|
||||
"-Dqrtr=false"
|
||||
"--disable-introspection",
|
||||
"--disable-vala",
|
||||
"--with-udev-base-dir=/app/lib",
|
||||
"--with-systemdsystemunitdir=/app/lib/systemd/system",
|
||||
"--without-mbim",
|
||||
"--without-qmi"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "git://anongit.freedesktop.org/ModemManager/ModemManager",
|
||||
"branch" : "main"
|
||||
"url" : "git://anongit.freedesktop.org/ModemManager/ModemManager"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -487,16 +472,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gsound",
|
||||
"buildsystem" : "meson",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gsound.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gnome-bluetooth",
|
||||
"buildsystem" : "meson",
|
||||
@@ -510,6 +485,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",
|
||||
@@ -518,9 +510,9 @@
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.6.1.tgz",
|
||||
"sha256": "9d576ea6962d7db8a2e2808574e8c257c15aef55f403a1fb5a0faf35de70e6f3"
|
||||
"type" : "archive",
|
||||
"url" : "https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.4.46.tgz",
|
||||
"sha256" : "9a90dcb86b99ae790ccab93b7585a31fbcbeec8c94bf0f7ab0ca0a87ea0c4b2d"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -560,28 +552,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -590,17 +560,11 @@
|
||||
"--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.11.0.tar.gz",
|
||||
"sha256" : "6adf1c74afff1f3f7e14060cc5a36111a6721d644ea51ed1b22da46051e48e9c"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -617,13 +581,207 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "cheese",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dintrospection=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dman=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/cheese.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libhandy",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dexamples=false",
|
||||
"-Dglade_catalog=disabled",
|
||||
"-Dintrospection=disabled",
|
||||
"-Dtests=false",
|
||||
"-Dvapi=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libhandy.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gsound",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gsound.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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" : "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"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/storaged-project/libblockdev.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"--enable-daemon=no",
|
||||
"--with-systemdsystemunitdir=/app/lib/systemd/system",
|
||||
"--with-tmpfilesdir=/app/lib/tmpfiles.d"
|
||||
],
|
||||
@@ -640,7 +798,6 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch": "main",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gnome-backgrounds.git"
|
||||
}
|
||||
]
|
||||
|
||||
1
build-aux/meson.build
Normal file
@@ -0,0 +1 @@
|
||||
meson.add_install_script('meson/meson_post_install.py', control_center_datadir)
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
def usage():
|
||||
print('Usage:')
|
||||
print('find_xdg_file.py FILENAME')
|
||||
print('')
|
||||
print('Looks for FILENAME in the XDG data directories and returns if path if found')
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
||||
data_home = os.getenv('XDG_DATA_HOME')
|
||||
if not data_home or data_home == '':
|
||||
data_home = os.path.join(os.path.expanduser("~"), "local", "share")
|
||||
|
||||
data_dirs_str = os.getenv('XDG_DATA_DIRS')
|
||||
if not data_dirs_str or data_dirs_str == '':
|
||||
data_dirs_str = '/usr/local/share/:/usr/share/'
|
||||
|
||||
dirs = []
|
||||
dirs += [ data_home ]
|
||||
for _dir in data_dirs_str.split(':'):
|
||||
dirs += [ _dir ]
|
||||
|
||||
for _dir in dirs:
|
||||
full_path = os.path.join(_dir, filename)
|
||||
if os.path.exists(full_path):
|
||||
print(full_path)
|
||||
sys.exit(0)
|
||||
|
||||
print(f"'{filename}' not found in XDG data directories")
|
||||
sys.exit(1)
|
||||
15
build-aux/meson/meson_post_install.py
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
gsettingsschemadir = os.path.join(sys.argv[1], 'glib-2.0', 'schemas')
|
||||
icondir = os.path.join(sys.argv[1], 'icons', 'hicolor')
|
||||
|
||||
if not os.environ.get('DESTDIR'):
|
||||
print('Compiling gsettings schemas...')
|
||||
subprocess.call(['glib-compile-schemas', gsettingsschemadir])
|
||||
|
||||
print('Update icon cache...')
|
||||
subprocess.call(['gtk-update-icon-cache', '-f', '-t', icondir])
|
||||
@@ -1,5 +1,13 @@
|
||||
<?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"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 4.1 KiB |
@@ -209,4 +209,4 @@ available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
[maintainers]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/docs/MAINTAINERS.md
|
||||
[maintainers]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/MAINTAINERS.md
|
||||
|
||||
@@ -50,7 +50,7 @@ by being explicit. Suggested acceptance phrase:
|
||||
Urgency commits should never happen, but in case they're needed, they are defined by the following
|
||||
criteria:
|
||||
|
||||
* On stable branches (or `main` right after a stable release)
|
||||
* On stable branches (or master right after a stable release)
|
||||
* Symptoms:
|
||||
* Always OR often reproducible; AND
|
||||
* Crash; OR
|
||||
@@ -59,4 +59,4 @@ criteria:
|
||||
* Quickly followed by an emergency release (at most 2 days after the commit)
|
||||
|
||||
|
||||
[doap]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/gnome-control-center.doap
|
||||
[doap]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/gnome-control-center.doap
|
||||
|
||||
@@ -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>
|
||||
|
||||
89
meson.build
@@ -1,8 +1,8 @@
|
||||
project(
|
||||
'gnome-control-center', 'c',
|
||||
version : '43.0',
|
||||
version : '40.9',
|
||||
license : 'GPL2+',
|
||||
meson_version : '>= 0.57.0'
|
||||
meson_version : '>= 0.53.0'
|
||||
)
|
||||
|
||||
control_center_prefix = get_option('prefix')
|
||||
@@ -50,17 +50,6 @@ foreach define: set_defines
|
||||
config_h.set_quoted(define[0], define[1])
|
||||
endforeach
|
||||
|
||||
distributor_logo = get_option('distributor_logo')
|
||||
if (distributor_logo != '')
|
||||
config_h.set_quoted('DISTRIBUTOR_LOGO', distributor_logo,
|
||||
description: 'Define to absolute path of distributor logo')
|
||||
dark_mode_distributor_logo = get_option('dark_mode_distributor_logo')
|
||||
if (dark_mode_distributor_logo != '')
|
||||
config_h.set_quoted('DARK_MODE_DISTRIBUTOR_LOGO', dark_mode_distributor_logo,
|
||||
description: 'Define to absolute path of distributor logo for use in dark mode')
|
||||
endif
|
||||
endif
|
||||
|
||||
# meson does not support octal values, so it must be handled as a
|
||||
# string. See: https://github.com/mesonbuild/meson/issues/2047
|
||||
config_h.set('USER_DIR_MODE', '0700',
|
||||
@@ -110,28 +99,35 @@ libgvc = subproject(
|
||||
)
|
||||
libgvc_dep = libgvc.get_variable('libgvc_dep')
|
||||
|
||||
libhandy_dep = dependency('libhandy-1', version: '>= 1.0.0', required: false)
|
||||
if not libhandy_dep.found()
|
||||
libhandy = subproject(
|
||||
'libhandy',
|
||||
default_options: [
|
||||
'examples=false',
|
||||
'glade_catalog=disabled',
|
||||
'introspection=disabled',
|
||||
'tests=false',
|
||||
'vapi=false',
|
||||
]
|
||||
)
|
||||
libhandy_dep = libhandy.get_variable('libhandy_dep')
|
||||
endif
|
||||
|
||||
goa_req_version = '>= 3.25.3'
|
||||
pulse_req_version = '>= 2.0'
|
||||
|
||||
libadwaita_dep = dependency(
|
||||
'libadwaita-1',
|
||||
version: '>= 1.2.alpha',
|
||||
fallback: ['libadwaita', 'libadwaita_dep'],
|
||||
default_options: ['examples=false', 'introspection=disabled', 'tests=false', 'vapi=false'],
|
||||
)
|
||||
|
||||
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.70.0')
|
||||
gnome_desktop_dep = dependency('gnome-desktop-4')
|
||||
gnome_bg_dep = dependency('gnome-bg-4')
|
||||
gnome_rr_dep = dependency('gnome-rr-4')
|
||||
gnome_settings_dep = dependency('gnome-settings-daemon', version: '>= 41.0')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.56.0')
|
||||
gnome_desktop_dep = dependency('gnome-desktop-3.0', version: '>= 3.33.4')
|
||||
gnome_settings_dep = dependency('gnome-settings-daemon', version: '>= 3.27.90')
|
||||
goa_dep = dependency('goa-1.0', version: goa_req_version)
|
||||
gsettings_desktop_dep = dependency('gsettings-desktop-schemas', version: '>= 42.alpha')
|
||||
gsettings_desktop_dep = dependency('gsettings-desktop-schemas', version: '>= 40.alpha')
|
||||
libxml_dep = dependency('libxml-2.0')
|
||||
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.114')
|
||||
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')
|
||||
@@ -139,8 +135,6 @@ gudev_dep = dependency('gudev-1.0', version: '>= 232')
|
||||
x11_dep = dependency('x11')
|
||||
xi_dep = dependency('xi', version: '>= 1.2')
|
||||
epoxy_dep = dependency('epoxy')
|
||||
gcr_dep = dependency('gcr-base-3')
|
||||
pwquality_dep = dependency('pwquality', version: '>= 1.2.2')
|
||||
|
||||
m_dep = cc.find_library('m')
|
||||
|
||||
@@ -148,21 +142,12 @@ common_deps = [
|
||||
gio_dep,
|
||||
glib_dep,
|
||||
gsettings_desktop_dep,
|
||||
libadwaita_dep,
|
||||
libhandy_dep,
|
||||
dependency('gio-unix-2.0'),
|
||||
dependency('gthread-2.0'),
|
||||
dependency('gtk4', version: '>= 4.4'),
|
||||
dependency('gtk+-3.0', version: '>= 3.22.20')
|
||||
]
|
||||
|
||||
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.103')
|
||||
# Also verify that polkit ITS files exist:
|
||||
# https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/491
|
||||
polkit_files = [ 'gettext/its/polkit.its', 'gettext/its/polkit.loc' ]
|
||||
foreach polkit_file: polkit_files
|
||||
r = run_command('build-aux/meson/find_xdg_file.py', polkit_file, check: true)
|
||||
assert(r.returncode() == 0, 'ITS support missing from polkit, please upgrade or contact your distribution')
|
||||
endforeach
|
||||
|
||||
# Check for CUPS 1.4 or newer
|
||||
cups_dep = dependency('cups', version : '>= 1.4', required: false)
|
||||
assert(cups_dep.found(), 'CUPS 1.4 or newer not found')
|
||||
@@ -187,6 +172,17 @@ 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
|
||||
cheese_deps = [
|
||||
dependency('cheese', version: '>= 3.28.0'),
|
||||
dependency('cheese-gtk', version: '>= 3.5.91')
|
||||
]
|
||||
endif
|
||||
config_h.set('HAVE_CHEESE', enable_cheese,
|
||||
description: 'Define to 1 to enable cheese webcam support')
|
||||
|
||||
# IBus support
|
||||
enable_ibus = get_option('ibus')
|
||||
if enable_ibus
|
||||
@@ -224,7 +220,7 @@ if host_is_linux
|
||||
# network manager
|
||||
network_manager_deps = [
|
||||
dependency('libnm', version: '>= 1.24.0'),
|
||||
dependency('libnma-gtk4', version: '>= 1.8.0'),
|
||||
dependency('libnma', version: '>= 1.8.0'),
|
||||
dependency('mm-glib', version: '>= 0.7')
|
||||
]
|
||||
endif
|
||||
@@ -232,14 +228,10 @@ 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
|
||||
gnome_bluetooth_dep = dependency('gnome-bluetooth-ui-3.0')
|
||||
gnome_bluetooth_dep = dependency('gnome-bluetooth-1.0', version: '>= 3.18.2')
|
||||
|
||||
libwacom_dep = dependency('libwacom', version: '>= 0.7')
|
||||
|
||||
@@ -281,6 +273,7 @@ install_subdir(
|
||||
top_inc = include_directories('.')
|
||||
shell_inc = include_directories('shell')
|
||||
|
||||
subdir('build-aux')
|
||||
subdir('data/icons')
|
||||
subdir('po')
|
||||
subdir('panels')
|
||||
@@ -295,11 +288,6 @@ if get_option('documentation')
|
||||
subdir('man')
|
||||
endif
|
||||
|
||||
gnome.post_install(
|
||||
glib_compile_schemas: true,
|
||||
gtk_update_icon_cache: true,
|
||||
)
|
||||
|
||||
configure_file(
|
||||
output: 'config.h',
|
||||
configuration: config_h
|
||||
@@ -319,6 +307,7 @@ summary({
|
||||
}, section: 'Dependencies')
|
||||
|
||||
summary({
|
||||
'Cheese': enable_cheese,
|
||||
'IBus': enable_ibus,
|
||||
'Snap': enable_snap,
|
||||
'Malcontent': enable_malcontent,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
option('cheese', type: 'boolean', value: true, description: 'build with cheese webcam support')
|
||||
option('documentation', type: 'boolean', value: false, description: 'build documentation')
|
||||
option('ibus', type: 'boolean', value: true, description: 'build with IBus support')
|
||||
option('privileged_group', type: 'string', value: 'wheel', description: 'name of group that has elevated permissions')
|
||||
@@ -7,5 +8,3 @@ option('tracing', type: 'boolean', value: false, description: 'add extra debuggi
|
||||
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('distributor_logo', type: 'string', description: 'absolute path to distributor logo for the About panel')
|
||||
option('dark_mode_distributor_logo', type: 'string', description: 'absolute path to distributor logo dark mode variant')
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/control-center/applications">
|
||||
<file preprocess="xml-stripblanks">cc-action-row.ui</file>
|
||||
<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>
|
||||
</gresources>
|
||||
|
||||
218
panels/applications/cc-action-row.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/* cc-action-row.c
|
||||
*
|
||||
* Copyright 2018 Matthias Clasen <matthias.clasen@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 <config.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "cc-action-row.h"
|
||||
#include "cc-applications-resources.h"
|
||||
|
||||
struct _CcActionRow
|
||||
{
|
||||
GtkListBoxRow parent;
|
||||
|
||||
GtkWidget *title;
|
||||
GtkWidget *subtitle;
|
||||
GtkWidget *button;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcActionRow, cc_action_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
static int activated_signal;
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_SUBTITLE,
|
||||
PROP_ACTION,
|
||||
PROP_ENABLED,
|
||||
PROP_DESTRUCTIVE
|
||||
};
|
||||
|
||||
static void
|
||||
clicked_cb (CcActionRow *row)
|
||||
{
|
||||
g_signal_emit (row, activated_signal, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_action_row_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcActionRow *row = CC_ACTION_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (row->title)));
|
||||
break;
|
||||
|
||||
case PROP_SUBTITLE:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (row->subtitle)));
|
||||
break;
|
||||
|
||||
case PROP_ACTION:
|
||||
g_value_set_string (value, gtk_button_get_label (GTK_BUTTON (row->button)));
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
g_value_set_boolean (value, gtk_widget_get_sensitive (row->button));
|
||||
break;
|
||||
|
||||
case PROP_DESTRUCTIVE:
|
||||
g_value_set_boolean (value,
|
||||
gtk_style_context_has_class (gtk_widget_get_style_context (row->button), "destructive-action"));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_action_row_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcActionRow *row = CC_ACTION_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
gtk_label_set_label (GTK_LABEL (row->title), g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SUBTITLE:
|
||||
gtk_label_set_label (GTK_LABEL (row->subtitle), g_value_get_string (value));
|
||||
gtk_widget_set_visible (row->subtitle, strlen (g_value_get_string (value)) > 0);
|
||||
break;
|
||||
|
||||
case PROP_ACTION:
|
||||
gtk_button_set_label (GTK_BUTTON (row->button), g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
gtk_widget_set_sensitive (row->button, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_DESTRUCTIVE:
|
||||
if (g_value_get_boolean (value))
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (row->button), "destructive-action");
|
||||
else
|
||||
gtk_style_context_remove_class (gtk_widget_get_style_context (row->button), "destructive-action");
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_action_row_class_init (CcActionRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->get_property = cc_action_row_get_property;
|
||||
object_class->set_property = cc_action_row_set_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TITLE,
|
||||
g_param_spec_string ("title", "title", "title",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SUBTITLE,
|
||||
g_param_spec_string ("subtitle", "subtitle", "subtitle",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ACTION,
|
||||
g_param_spec_string ("action", "action", "action",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ENABLED,
|
||||
g_param_spec_boolean ("enabled", "enabled", "enabled",
|
||||
TRUE, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DESTRUCTIVE,
|
||||
g_param_spec_boolean ("destructive", "destructive", "destructive",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
|
||||
activated_signal = g_signal_new ("activated",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-action-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcActionRow, title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcActionRow, subtitle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcActionRow, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, clicked_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_action_row_init (CcActionRow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
CcActionRow *
|
||||
cc_action_row_new (void)
|
||||
{
|
||||
return CC_ACTION_ROW (g_object_new (CC_TYPE_ACTION_ROW, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
cc_action_row_set_title (CcActionRow *row,
|
||||
const gchar *name)
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (row->title), name);
|
||||
}
|
||||
|
||||
void
|
||||
cc_action_row_set_subtitle (CcActionRow *row,
|
||||
const gchar *name)
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (row->subtitle), name);
|
||||
gtk_widget_set_visible (row->subtitle, strlen (name) > 0);
|
||||
}
|
||||
|
||||
void
|
||||
cc_action_row_set_action (CcActionRow *row,
|
||||
const gchar *action,
|
||||
gboolean sensitive)
|
||||
{
|
||||
gtk_button_set_label (GTK_BUTTON (row->button), action);
|
||||
gtk_widget_set_sensitive (row->button, sensitive);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* cc-list-row.h
|
||||
/* cc-action-row.h
|
||||
*
|
||||
* Copyright 2020 Red Hat Inc
|
||||
* Copyright 2018 Matthias Clasen <matthias.clasen@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
|
||||
@@ -16,9 +15,6 @@
|
||||
* 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):
|
||||
* Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
@@ -28,9 +24,19 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_POWER_PROFILE_INFO_ROW (cc_power_profile_info_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcPowerProfileInfoRow, cc_power_profile_info_row, CC, POWER_PROFILE_INFO_ROW, GtkListBoxRow)
|
||||
#define CC_TYPE_ACTION_ROW (cc_action_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcActionRow, cc_action_row, CC, ACTION_ROW, GtkListBoxRow)
|
||||
|
||||
CcPowerProfileInfoRow *cc_power_profile_info_row_new (const char *text);
|
||||
CcActionRow* cc_action_row_new (void);
|
||||
|
||||
void cc_action_row_set_title (CcActionRow *row,
|
||||
const gchar *label);
|
||||
|
||||
void cc_action_row_set_subtitle (CcActionRow *row,
|
||||
const gchar *label);
|
||||
|
||||
void cc_action_row_set_action (CcActionRow *row,
|
||||
const gchar *action,
|
||||
gboolean sensitive);
|
||||
|
||||
G_END_DECLS
|
||||
51
panels/applications/cc-action-row.ui
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcActionRow" 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">1</property>
|
||||
<property name="border-width">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">4</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<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>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="subtitle">
|
||||
<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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="clicked" handler="clicked_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
11
panels/applications/cc-applications-panel.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.section-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.sidebar-icon.fullcolor {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -1,245 +1,407 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcApplicationsPanel" parent="CcPanel">
|
||||
|
||||
<child type="titlebar">
|
||||
<object class="AdwHeaderBar">
|
||||
<property name="show-end-title-buttons">True</property>
|
||||
<property name="show-start-title-buttons">False</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="visible" bind-source="CcApplicationsPanel" bind-property="folded" bind-flags="default|sync-create" />
|
||||
<property name="icon-name">go-previous-symbolic</property>
|
||||
<property name="action-name">window.navigate</property>
|
||||
<property name="action-target">0</property> <!-- 0: ADW_NAVIGATION_DIRECTION_BACK -->
|
||||
</object>
|
||||
</child>
|
||||
<property name="title-widget">
|
||||
<object class="AdwWindowTitle" id="header_title">
|
||||
<property name="title" translatable="yes">Applications</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="content">
|
||||
<object class="GtkStack" id="stack">
|
||||
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="main_scroll">
|
||||
<property name="visible">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="empty_box">
|
||||
<property name="icon-name">org.gnome.Software-symbolic</property>
|
||||
<property name="title" translatable="yes">No applications</property>
|
||||
<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="GtkButton" id="install_button">
|
||||
<property name="label" translatable="yes">Install some…</property>
|
||||
<property name="halign">center</property>
|
||||
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesPage" id="settings_box">
|
||||
|
||||
<!-- App icon & buttons -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="empty_box">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">18</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="app_icon_image">
|
||||
<property name="icon-name">org.gnome.Software</property>
|
||||
<property name="pixel-size">96</property>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="pixel-size">80</property>
|
||||
<property name="icon-name">org.gnome.Software-symbolic</property>
|
||||
<style>
|
||||
<class name="icon-dropshadow" />
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="fill">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel" id="app_name_label">
|
||||
<property name="wrap">True</property>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="margin-bottom">15</property>
|
||||
<property name="label" translatable="yes">No applications</property>
|
||||
<style>
|
||||
<class name="title" />
|
||||
<class name="title-1" />
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkButton" id="install_button">
|
||||
<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>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="spacing">18</property>
|
||||
<signal name="clicked" handler="open_software_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="fill">0</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="settings_box">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">24</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="permission_section">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<style>
|
||||
<class name="section"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton" id="launch_button">
|
||||
<property name="label" translatable="yes">Open</property>
|
||||
<signal name="clicked" handler="on_launch_button_clicked_cb" object="CcApplicationsPanel" swapped="no" />
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Permissions & Access</property>
|
||||
<style>
|
||||
<class name="section-title"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<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">Data and services that this app has asked for access to and permissions that it requires.</property>
|
||||
<style>
|
||||
<class name="section-subtitle"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<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"/>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<signal name="notify::allowed" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<signal name="notify::allowed" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<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"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="builtin">
|
||||
<property name="title" translatable="yes">Built-in Permissions</property>
|
||||
<property name="info" translatable="yes">Cannot be changed</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
<class name="suggested-action" />
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="view_details_button">
|
||||
<property name="label" translatable="yes">View Details</property>
|
||||
<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">Individual permissions for applications can be reviewed in the <a href="privacy">Privacy</a> Settings.</property>
|
||||
<property name="use-markup">1</property>
|
||||
<signal name="activate-link" handler="privacy_link_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="integration_section">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<style>
|
||||
<class name="section"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Integration</property>
|
||||
<style>
|
||||
<class name="section-title"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<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">System features used by this application.</property>
|
||||
<style>
|
||||
<class name="section-subtitle"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="integration_list">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<signal name="notify::allowed" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<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"/>
|
||||
</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"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<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="pill" />
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="handler_section">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<style>
|
||||
<class name="section"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Default Handlers</property>
|
||||
<style>
|
||||
<class name="section-title"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<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">Types of files and links that this application opens.</property>
|
||||
<style>
|
||||
<class name="section-subtitle"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="handler_reset">
|
||||
<property name="visible">1</property>
|
||||
<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"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<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"/>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="usage_section">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<style>
|
||||
<class name="section"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Usage</property>
|
||||
<style>
|
||||
<class name="section-title"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<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 resources this application is using.</property>
|
||||
<style>
|
||||
<class name="section-subtitle"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<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"/>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="storage">
|
||||
<property name="title" translatable="yes">Storage</property>
|
||||
<property name="info">unknown</property>
|
||||
<property name="has-expander">1</property>
|
||||
<property name="is-link">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="integration_section">
|
||||
<child>
|
||||
<object class="CcToggleRow" id="search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results.</property>
|
||||
<signal name="notify::allowed" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="notification">
|
||||
<property name="title" translatable="yes">Notifications</property>
|
||||
<property name="subtitle" translatable="yes">Show system 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>
|
||||
<property name="subtitle" translatable="yes">Allow activity when the app is closed.</property>
|
||||
<signal name="notify::allowed" handler="background_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="screenshot">
|
||||
<property name="title" translatable="yes">Screenshots</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures of the screen at any time.</property>
|
||||
<signal name="notify::allowed" handler="screenshot_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="wallpaper">
|
||||
<property name="title" translatable="yes">Change Wallpaper</property>
|
||||
<property name="subtitle" translatable="yes">Change the desktop wallpaper.</property>
|
||||
<signal name="notify::allowed" handler="wallpaper_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds.</property>
|
||||
<signal name="notify::allowed" handler="sound_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="shortcuts">
|
||||
<property name="title" translatable="yes">Inhibit Shortcuts</property>
|
||||
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts.</property>
|
||||
<signal name="notify::allowed" handler="shortcuts_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera.</property>
|
||||
<signal name="notify::allowed" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone.</property>
|
||||
<signal name="notify::allowed" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data.</property>
|
||||
<signal name="notify::allowed" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="usage_section">
|
||||
<child>
|
||||
<object class="CcInfoRow" id="builtin">
|
||||
<property name="title" translatable="yes">Built-in Permissions</property>
|
||||
<property name="subtitle" translatable="yes">System access that is required by the app</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
<signal name="activated" handler="on_builtin_row_activated_cb" object="CcApplicationsPanel" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="handler_row">
|
||||
<property name="title" translatable="yes">File &amp; Link Associations</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
<signal name="activated" handler="on_handler_row_activated_cb" object="CcApplicationsPanel" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="storage">
|
||||
<property name="title" translatable="yes">Storage</property>
|
||||
<property name="has-expander">1</property>
|
||||
<property name="is-link">1</property>
|
||||
<signal name="activated" handler="on_storage_row_activated_cb" object="CcApplicationsPanel" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -249,16 +411,29 @@
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="GtkLabel" id="title_label">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Applications</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
</object>
|
||||
<object class="GtkButton" id="header_button">
|
||||
<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="margin-top">12</property>
|
||||
<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>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</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" />
|
||||
@@ -266,27 +441,23 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="sidebar_listbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="selection-mode">browse</property>
|
||||
<style>
|
||||
<class name="navigation-sidebar" />
|
||||
</style>
|
||||
|
||||
<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="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="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>
|
||||
@@ -297,6 +468,7 @@
|
||||
</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>
|
||||
@@ -307,6 +479,7 @@
|
||||
</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>
|
||||
@@ -325,78 +498,35 @@
|
||||
<object class="GtkDialog" id="builtin_dialog">
|
||||
<property name="title" translatable="yes">Built-in Permissions</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage">
|
||||
<property name="resizable">0</property>
|
||||
<property name="border-width">24</property>
|
||||
<signal name="delete-event" handler="gtk_widget_hide_on_delete"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="builtin_group">
|
||||
<child>
|
||||
<object class="GtkListBox" id="builtin_list">
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
</object>
|
||||
</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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
<!-- File & Link handlers dialog -->
|
||||
<object class="GtkDialog" id="handler_dialog">
|
||||
<property name="title" translatable="yes">File & Link Associations</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="default-height">400</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage">
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkLabel" id="handler_title_label">
|
||||
<property name="wrap">True</property>
|
||||
<property name="xalign">0.0</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkListBox" id="builtin_list">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="handler_file_group">
|
||||
<property name="title" translatable="yes">File Types</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="handler_link_group">
|
||||
<property name="title" translatable="yes">Link Types</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkButton" id="handler_reset">
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
<signal name="clicked" handler="handler_reset_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="destructive-action" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -405,16 +535,29 @@
|
||||
<object class="GtkDialog" id="storage_dialog">
|
||||
<property name="title" translatable="yes">Storage</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="default-width">420</property>
|
||||
<property name="default-height">420</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage">
|
||||
<property name="resizable">0</property>
|
||||
<property name="border-width">24</property>
|
||||
<signal name="delete-event" handler="gtk_widget_hide_on_delete"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="description" translatable="yes">How much disk space this application is occupying with app data and caches.</property>
|
||||
<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>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="storage_list">
|
||||
<property name="visible">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="app">
|
||||
<property name="title" translatable="yes">Application</property>
|
||||
@@ -436,30 +579,32 @@
|
||||
<child>
|
||||
<object class="CcInfoRow" id="total">
|
||||
<property name="title" translatable="yes"><b>Total</b></property>
|
||||
<property name="use-markup">1</property>
|
||||
<property name="info">Unknown</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<child>
|
||||
<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"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
<object class="GtkSizeGroup">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="launch_button" />
|
||||
<widget name="view_details_button" />
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -86,9 +86,9 @@ cc_applications_row_new (GAppInfo *info)
|
||||
|
||||
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_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_image_set_from_icon_name (GTK_IMAGE (self->image), "application-x-executable", GTK_ICON_SIZE_BUTTON);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (self->label), g_app_info_get_display_name (info));
|
||||
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcApplicationsRow" parent="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="visible">1</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="visible">1</property>
|
||||
<property name="pixel-size">32</property>
|
||||
<style>
|
||||
<class name="sidebar-icon"/>
|
||||
<class name="fullcolor"/>
|
||||
<class name="lowres-icon"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
|
||||
struct _CcInfoRow
|
||||
{
|
||||
AdwActionRow parent;
|
||||
GtkListBoxRow parent;
|
||||
|
||||
GtkWidget *title;
|
||||
GtkWidget *info;
|
||||
GtkWidget *expander;
|
||||
|
||||
@@ -35,11 +36,13 @@ struct _CcInfoRow
|
||||
gboolean link;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcInfoRow, cc_info_row, ADW_TYPE_ACTION_ROW)
|
||||
G_DEFINE_TYPE (CcInfoRow, cc_info_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_USE_MARKUP,
|
||||
PROP_INFO,
|
||||
PROP_HAS_EXPANDER,
|
||||
PROP_IS_LINK,
|
||||
@@ -56,12 +59,18 @@ cc_info_row_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (row->title)));
|
||||
break;
|
||||
case PROP_INFO:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (row->info)));
|
||||
break;
|
||||
case PROP_HAS_EXPANDER:
|
||||
g_value_set_boolean (value, gtk_widget_get_visible (row->expander));
|
||||
break;
|
||||
case PROP_USE_MARKUP:
|
||||
g_value_set_boolean (value, gtk_label_get_use_markup (GTK_LABEL (row->title)));
|
||||
break;
|
||||
case PROP_IS_LINK:
|
||||
g_value_set_boolean (value, row->link);
|
||||
break;
|
||||
@@ -78,11 +87,11 @@ static void
|
||||
update_expander (CcInfoRow *row)
|
||||
{
|
||||
if (row->link)
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (row->expander), "go-next-symbolic");
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (row->expander), "go-next-symbolic", GTK_ICON_SIZE_BUTTON);
|
||||
else if (row->expanded)
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (row->expander), "pan-down-symbolic");
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (row->expander), "pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
|
||||
else
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (row->expander), "pan-end-symbolic");
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (row->expander), "pan-end-symbolic", GTK_ICON_SIZE_BUTTON);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -95,6 +104,10 @@ cc_info_row_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
gtk_label_set_label (GTK_LABEL (row->title), g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_INFO:
|
||||
gtk_label_set_label (GTK_LABEL (row->info), g_value_get_string (value));
|
||||
break;
|
||||
@@ -104,6 +117,10 @@ cc_info_row_set_property (GObject *object,
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_USE_MARKUP:
|
||||
gtk_label_set_use_markup (GTK_LABEL (row->title), g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_IS_LINK:
|
||||
row->link = g_value_get_boolean (value);
|
||||
update_expander (row);
|
||||
@@ -130,11 +147,21 @@ cc_info_row_class_init (CcInfoRowClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-info-row.ui");
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TITLE,
|
||||
g_param_spec_string ("title", "title", "title",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INFO,
|
||||
g_param_spec_string ("info", "info", "info",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_USE_MARKUP,
|
||||
g_param_spec_boolean ("use-markup", "use-markup", "use-markup",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_HAS_EXPANDER,
|
||||
g_param_spec_boolean ("has-expander", "has-expander", "has-expander",
|
||||
@@ -150,6 +177,7 @@ cc_info_row_class_init (CcInfoRowClass *klass)
|
||||
g_param_spec_boolean ("is-link", "is-link", "is-link",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcInfoRow, title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcInfoRow, info);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcInfoRow, expander);
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_INFO_ROW (cc_info_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcInfoRow, cc_info_row, CC, INFO_ROW, AdwActionRow)
|
||||
G_DECLARE_FINAL_TYPE (CcInfoRow, cc_info_row, CC, INFO_ROW, GtkListBoxRow)
|
||||
|
||||
CcInfoRow* cc_info_row_new (void);
|
||||
|
||||
|
||||
@@ -1,19 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcInfoRow" parent="AdwActionRow">
|
||||
<template class="CcInfoRow" parent="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="activatable">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="info">
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="expander">
|
||||
<property name="visible">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="border-width">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="info">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="expander">
|
||||
<property name="valign">center</property>
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
|
||||
struct _CcSnapRow
|
||||
{
|
||||
AdwActionRow parent;
|
||||
GtkListBoxRow parent;
|
||||
|
||||
GtkLabel *title_label;
|
||||
GtkSwitch *slot_toggle;
|
||||
GtkComboBox *slots_combo;
|
||||
GtkListStore *slots_combo_model;
|
||||
@@ -39,7 +40,7 @@ struct _CcSnapRow
|
||||
GPtrArray *slots;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcSnapRow, cc_snap_row, ADW_TYPE_ACTION_ROW)
|
||||
G_DEFINE_TYPE (CcSnapRow, cc_snap_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -244,6 +245,7 @@ cc_snap_row_class_init (CcSnapRowClass *klass)
|
||||
|
||||
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);
|
||||
@@ -293,7 +295,7 @@ cc_snap_row_new (GCancellable *cancellable, SnapdInterface *interface, SnapdPlug
|
||||
label = snapd_interface_make_label (interface);
|
||||
else
|
||||
label = g_strdup (snapd_plug_get_interface (plug));
|
||||
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self), label);
|
||||
gtk_label_set_label (self->title_label, label);
|
||||
|
||||
/* Add option into combo box */
|
||||
gtk_list_store_append (self->slots_combo_model, &iter);
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
#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, AdwActionRow)
|
||||
G_DECLARE_FINAL_TYPE (CcSnapRow, cc_snap_row, CC, SNAP_ROW, GtkListBoxRow)
|
||||
|
||||
CcSnapRow* cc_snap_row_new (GCancellable *cancellable,
|
||||
SnapdInterface *interface,
|
||||
|
||||
@@ -8,27 +8,45 @@
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<template class="CcSnapRow" parent="AdwActionRow">
|
||||
<template class="CcSnapRow" parent="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="activatable">False</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="slot_toggle">
|
||||
<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="valign">center</property>
|
||||
<property name="model">slots_combo_model</property>
|
||||
<signal name="changed" handler="combo_changed_cb" swapped="yes"/>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="border-width">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<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>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</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>
|
||||
|
||||
@@ -26,16 +26,18 @@
|
||||
|
||||
struct _CcToggleRow
|
||||
{
|
||||
AdwActionRow parent;
|
||||
GtkListBoxRow parent;
|
||||
|
||||
GtkWidget *title;
|
||||
GtkWidget *toggle;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcToggleRow, cc_toggle_row, ADW_TYPE_ACTION_ROW)
|
||||
G_DEFINE_TYPE (CcToggleRow, cc_toggle_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_ALLOWED
|
||||
};
|
||||
|
||||
@@ -55,6 +57,9 @@ cc_toggle_row_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (row->title)));
|
||||
break;
|
||||
case PROP_ALLOWED:
|
||||
g_value_set_boolean (value, cc_toggle_row_get_allowed (row));
|
||||
break;
|
||||
@@ -74,6 +79,9 @@ cc_toggle_row_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
gtk_label_set_label (GTK_LABEL (row->title), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ALLOWED:
|
||||
cc_toggle_row_set_allowed (row, g_value_get_boolean (value));
|
||||
break;
|
||||
@@ -94,11 +102,17 @@ cc_toggle_row_class_init (CcToggleRowClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/applications/cc-toggle-row.ui");
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TITLE,
|
||||
g_param_spec_string ("title", "title", "title",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ALLOWED,
|
||||
g_param_spec_boolean ("allowed", "allowed", "allowed",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcToggleRow, title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcToggleRow, toggle);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, changed_cb);
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_TOGGLE_ROW (cc_toggle_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcToggleRow, cc_toggle_row, CC, TOGGLE_ROW, AdwActionRow)
|
||||
G_DECLARE_FINAL_TYPE (CcToggleRow, cc_toggle_row, CC, TOGGLE_ROW, GtkListBoxRow)
|
||||
|
||||
CcToggleRow* cc_toggle_row_new (void);
|
||||
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcToggleRow" parent="AdwActionRow">
|
||||
<property name="activatable-widget">toggle</property>
|
||||
<template class="CcToggleRow" parent="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="activatable">False</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="toggle">
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::active" handler="changed_cb" swapped="yes"/>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="border-width">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="visible">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="toggle">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::active" handler="changed_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -4,13 +4,13 @@ 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=org.gnome.Settings-applications-symbolic
|
||||
Icon=preferences-desktop-apps
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-AccountSettings;
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
# Translators: Search terms to find the Applications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
# 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
|
||||
X-GNOME-ControlCenter-HasSidebar=true
|
||||
@@ -1,4 +0,0 @@
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-applications-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 2 0 c -1.089844 0 -2 0.910156 -2 2 v 3 c 0 1.089844 0.910156 2 2 2 h 3 c 1.089844 0 2 -0.910156 2 -2 v -3 c 0 -1.089844 -0.910156 -2 -2 -2 z m 8 0 c -1.089844 0 -2 0.910156 -2 2 v 3 c 0 1.089844 0.910156 2 2 2 h 3 c 1.089844 0 2 -0.910156 2 -2 v -3 c 0 -1.089844 -0.910156 -2 -2 -2 z m -8 2 h 3 v 3 h -3 z m 8 0 h 3 v 3 h -3 z m -8 6 c -1.089844 0 -2 0.910156 -2 2 v 3 c 0 1.089844 0.910156 2 2 2 h 3 c 1.089844 0 2 -0.910156 2 -2 v -3 c 0 -1.089844 -0.910156 -2 -2 -2 z m 8 0 c -1.089844 0 -2 0.910156 -2 2 v 3 c 0 1.089844 0.910156 2 2 2 h 3 c 1.089844 0 2 -0.910156 2 -2 v -3 c 0 -1.089844 -0.910156 -2 -2 -2 z m -8 2 h 3 v 3 h -3 z m 8 0 h 3 v 3 h -3 z m 0 0" fill="#2e3436"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 830 B |
@@ -21,6 +21,7 @@ sources = files(
|
||||
'cc-applications-row.c',
|
||||
'cc-toggle-row.c',
|
||||
'cc-info-row.c',
|
||||
'cc-action-row.c',
|
||||
'globs.c',
|
||||
'search.c',
|
||||
'utils.c',
|
||||
@@ -54,5 +55,3 @@ panels_libs += static_library(
|
||||
dependencies : deps,
|
||||
c_args : cflags
|
||||
)
|
||||
|
||||
subdir('icons')
|
||||
|
||||
@@ -143,12 +143,14 @@ file_size_finish (GFile *file,
|
||||
}
|
||||
|
||||
void
|
||||
listbox_remove_all (GtkListBox *listbox)
|
||||
container_remove_all (GtkContainer *container)
|
||||
{
|
||||
GtkWidget *child;
|
||||
g_autoptr(GList) children = NULL;
|
||||
GList *l;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (listbox))))
|
||||
gtk_list_box_remove (listbox, child);
|
||||
children = gtk_container_get_children (container);
|
||||
for (l = children; l; l = l->next)
|
||||
gtk_widget_destroy (GTK_WIDGET (l->data));
|
||||
}
|
||||
|
||||
static gchar *
|
||||
@@ -166,7 +168,7 @@ get_output_of (const gchar **argv)
|
||||
&status, NULL))
|
||||
return NULL;
|
||||
|
||||
if (!g_spawn_check_wait_status (status, NULL))
|
||||
if (!g_spawn_check_exit_status (status, NULL))
|
||||
return NULL;
|
||||
|
||||
return g_steal_pointer (&output);
|
||||
|
||||
@@ -44,7 +44,7 @@ gboolean file_size_finish (GFile *file,
|
||||
guint64 *size,
|
||||
GError **error);
|
||||
|
||||
void listbox_remove_all (GtkListBox *listbox);
|
||||
void container_remove_all (GtkContainer *container);
|
||||
|
||||
GKeyFile* get_flatpak_metadata (const gchar *app_id);
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 4.233 4.233" xmlns="http://www.w3.org/2000/svg"><path d="M3.843.627a.397.397 0 0 0-.56.034L1.45 2.73l-.775-.763a.397.397 0 0 0-.56.004.397.397 0 0 0 .003.562L1.191 3.59a.397.397 0 0 0 .576-.02l2.11-2.382a.397.397 0 0 0-.034-.56Z" style="fill:#3d3846"/></svg>
|
||||
|
Before Width: | Height: | Size: 299 B |
@@ -6,9 +6,4 @@
|
||||
<file preprocess="xml-stripblanks">cc-background-preview.ui</file>
|
||||
<file>preview.css</file>
|
||||
</gresource>
|
||||
|
||||
<gresource prefix="/org/gnome/Settings/icons/scalable/actions">
|
||||
<file preprocess="xml-stripblanks">background-selected-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">slideshow-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
855
panels/background/bg-pictures-source.c
Normal file
@@ -0,0 +1,855 @@
|
||||
/* bg-pictures-source.c */
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "bg-pictures-source.h"
|
||||
|
||||
#include "cc-background-grilo-miner.h"
|
||||
#include "cc-background-item.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <cairo-gobject.h>
|
||||
#include <gio/gio.h>
|
||||
#include <grilo.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
#include <gdesktop-enums.h>
|
||||
|
||||
#define ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_NAME "," \
|
||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED
|
||||
|
||||
struct _BgPicturesSource
|
||||
{
|
||||
BgSource parent_instance;
|
||||
|
||||
GCancellable *cancellable;
|
||||
|
||||
CcBackgroundGriloMiner *grl_miner;
|
||||
|
||||
GFileMonitor *picture_dir_monitor;
|
||||
GFileMonitor *cache_dir_monitor;
|
||||
|
||||
GHashTable *known_items;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (BgPicturesSource, bg_pictures_source, BG_TYPE_SOURCE)
|
||||
|
||||
const char * const content_types[] = {
|
||||
"image/png",
|
||||
"image/jp2",
|
||||
"image/jpeg",
|
||||
"image/bmp",
|
||||
"image/svg+xml",
|
||||
"image/x-portable-anymap",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const screenshot_types[] = {
|
||||
"image/png",
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *bg_pictures_source_get_unique_filename (const char *uri);
|
||||
|
||||
static void picture_opened_for_read (GObject *source_object, GAsyncResult *res, gpointer user_data);
|
||||
|
||||
static void
|
||||
bg_pictures_source_dispose (GObject *object)
|
||||
{
|
||||
BgPicturesSource *source = BG_PICTURES_SOURCE (object);
|
||||
|
||||
if (source->cancellable)
|
||||
{
|
||||
g_cancellable_cancel (source->cancellable);
|
||||
g_clear_object (&source->cancellable);
|
||||
}
|
||||
|
||||
g_clear_object (&source->grl_miner);
|
||||
|
||||
G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
bg_pictures_source_finalize (GObject *object)
|
||||
{
|
||||
BgPicturesSource *bg_source = BG_PICTURES_SOURCE (object);
|
||||
|
||||
g_clear_pointer (&bg_source->known_items, g_hash_table_destroy);
|
||||
|
||||
g_clear_object (&bg_source->picture_dir_monitor);
|
||||
g_clear_object (&bg_source->cache_dir_monitor);
|
||||
|
||||
G_OBJECT_CLASS (bg_pictures_source_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
bg_pictures_source_class_init (BgPicturesSourceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = bg_pictures_source_dispose;
|
||||
object_class->finalize = bg_pictures_source_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_placeholder (BgPicturesSource *bg_source,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
GListStore *store;
|
||||
guint i;
|
||||
|
||||
store = bg_source_get_liststore (BG_SOURCE (bg_source));
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (store)); i++)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) item_n = NULL;
|
||||
|
||||
item_n = g_list_model_get_item (G_LIST_MODEL (store), i);
|
||||
|
||||
if (item_n == item)
|
||||
{
|
||||
g_list_store_remove (store, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
picture_needs_rotation (GdkPixbuf *pixbuf)
|
||||
{
|
||||
const gchar *str;
|
||||
|
||||
str = gdk_pixbuf_get_option (pixbuf, "orientation");
|
||||
if (str == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (*str == '5' || *str == '6' || *str == '7' || *str == '8')
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
swap_rotated_pixbuf (GdkPixbuf *pixbuf)
|
||||
{
|
||||
GdkPixbuf *tmp_pixbuf;
|
||||
|
||||
tmp_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
|
||||
if (tmp_pixbuf == NULL)
|
||||
return pixbuf;
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
return tmp_pixbuf;
|
||||
}
|
||||
|
||||
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
|
||||
picture_scaled (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgPicturesSource *bg_source;
|
||||
CcBackgroundItem *item;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
const char *software;
|
||||
const char *uri;
|
||||
GListStore *store;
|
||||
cairo_surface_t *surface = NULL;
|
||||
int scale_factor;
|
||||
gboolean rotation_applied;
|
||||
|
||||
item = g_object_get_data (source_object, "item");
|
||||
pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_warning ("Failed to load image: %s", error->message);
|
||||
remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* since we were not cancelled, we can now cast user_data
|
||||
* back to BgPicturesSource.
|
||||
*/
|
||||
bg_source = BG_PICTURES_SOURCE (user_data);
|
||||
store = bg_source_get_liststore (BG_SOURCE (bg_source));
|
||||
uri = cc_background_item_get_uri (item);
|
||||
if (uri == NULL)
|
||||
uri = cc_background_item_get_source_url (item);
|
||||
|
||||
/* Ignore screenshots */
|
||||
software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
|
||||
if (software != NULL &&
|
||||
g_str_equal (software, "gnome-screenshot"))
|
||||
{
|
||||
g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", uri);
|
||||
remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Process embedded orientation */
|
||||
rotation_applied = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "rotation-applied"));
|
||||
|
||||
if (!rotation_applied && picture_needs_rotation (pixbuf))
|
||||
{
|
||||
/* the width and height of pixbuf we requested are wrong for EXIF
|
||||
* orientations 5, 6, 7 and 8. the file has to be reloaded. */
|
||||
g_autoptr(GFile) file = NULL;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
g_object_set_data (G_OBJECT (item), "needs-rotation", GINT_TO_POINTER (TRUE));
|
||||
g_object_set_data_full (G_OBJECT (file), "item", g_object_ref (item), g_object_unref);
|
||||
g_file_read_async (G_FILE (file), G_PRIORITY_DEFAULT,
|
||||
bg_source->cancellable,
|
||||
picture_opened_for_read, bg_source);
|
||||
return;
|
||||
}
|
||||
|
||||
pixbuf = swap_rotated_pixbuf (pixbuf);
|
||||
|
||||
scale_factor = bg_source_get_scale_factor (BG_SOURCE (bg_source));
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
|
||||
cc_background_item_load (item, NULL);
|
||||
|
||||
/* insert the item into the liststore */
|
||||
g_list_store_insert_sorted (store, item, sort_func, bg_source);
|
||||
|
||||
g_hash_table_insert (bg_source->known_items,
|
||||
bg_pictures_source_get_unique_filename (uri),
|
||||
GINT_TO_POINTER (TRUE));
|
||||
|
||||
g_clear_pointer (&surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
picture_opened_for_read (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgPicturesSource *bg_source;
|
||||
CcBackgroundItem *item;
|
||||
g_autoptr(GFileInputStream) stream = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gint thumbnail_height;
|
||||
gint thumbnail_width;
|
||||
gboolean needs_rotation;
|
||||
|
||||
item = g_object_get_data (source_object, "item");
|
||||
stream = g_file_read_finish (G_FILE (source_object), res, &error);
|
||||
if (stream == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_autofree gchar *filename = g_file_get_path (G_FILE (source_object));
|
||||
g_warning ("Failed to load picture '%s': %s", filename, error->message);
|
||||
remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* since we were not cancelled, we can now cast user_data
|
||||
* back to BgPicturesSource.
|
||||
*/
|
||||
bg_source = BG_PICTURES_SOURCE (user_data);
|
||||
|
||||
needs_rotation = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "needs-rotation"));
|
||||
if (needs_rotation)
|
||||
{
|
||||
/* swap width and height for EXIF orientations that need it */
|
||||
thumbnail_width = bg_source_get_thumbnail_height (BG_SOURCE (bg_source));
|
||||
thumbnail_height = bg_source_get_thumbnail_width (BG_SOURCE (bg_source));
|
||||
g_object_set_data (G_OBJECT (item), "rotation-applied", GINT_TO_POINTER (TRUE));
|
||||
}
|
||||
else
|
||||
{
|
||||
thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (bg_source));
|
||||
thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (bg_source));
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT (stream), "item", g_object_ref (item), g_object_unref);
|
||||
gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream),
|
||||
thumbnail_width, thumbnail_height,
|
||||
TRUE,
|
||||
bg_source->cancellable,
|
||||
picture_scaled, bg_source);
|
||||
}
|
||||
|
||||
static void
|
||||
picture_copied_for_read (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgPicturesSource *bg_source;
|
||||
CcBackgroundItem *item;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GFile *thumbnail_file = G_FILE (source_object);
|
||||
GFile *native_file;
|
||||
|
||||
if (!g_file_copy_finish (thumbnail_file, res, &error))
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
|
||||
{
|
||||
g_autofree gchar *uri = NULL;
|
||||
|
||||
uri = g_file_get_uri (thumbnail_file);
|
||||
g_warning ("Failed to download '%s': %s", uri, error->message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bg_source = BG_PICTURES_SOURCE (user_data);
|
||||
|
||||
native_file = g_object_get_data (G_OBJECT (thumbnail_file), "native-file");
|
||||
item = g_object_get_data (G_OBJECT (thumbnail_file), "item");
|
||||
g_object_set_data_full (G_OBJECT (native_file), "item", g_object_ref (item), g_object_unref);
|
||||
g_file_read_async (native_file,
|
||||
G_PRIORITY_DEFAULT,
|
||||
bg_source->cancellable,
|
||||
picture_opened_for_read,
|
||||
bg_source);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
in_content_types (const char *content_type)
|
||||
{
|
||||
guint i;
|
||||
for (i = 0; content_types[i]; i++)
|
||||
if (g_str_equal (content_types[i], content_type))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GFile *
|
||||
bg_pictures_source_get_cache_file (void)
|
||||
{
|
||||
g_autofree gchar *path = NULL;
|
||||
GFile *file;
|
||||
|
||||
path = bg_pictures_source_get_cache_path ();
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_single_file (BgPicturesSource *bg_source,
|
||||
GFile *file,
|
||||
const gchar *content_type,
|
||||
guint64 mtime)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) item = NULL;
|
||||
CcBackgroundItemFlags flags = 0;
|
||||
g_autofree gchar *source_uri = NULL;
|
||||
g_autofree gchar *uri = NULL;
|
||||
gboolean needs_download;
|
||||
gboolean retval = FALSE;
|
||||
const gchar *pictures_path;
|
||||
g_autoptr(GFile) pictures_dir = NULL;
|
||||
g_autoptr(GFile) cache_dir = NULL;
|
||||
GrlMedia *media;
|
||||
|
||||
/* find png and jpeg files */
|
||||
if (!content_type)
|
||||
goto out;
|
||||
if (!in_content_types (content_type))
|
||||
goto out;
|
||||
|
||||
/* create a new CcBackgroundItem */
|
||||
uri = g_file_get_uri (file);
|
||||
|
||||
pictures_path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
|
||||
if (pictures_path == NULL)
|
||||
pictures_path = g_get_home_dir ();
|
||||
pictures_dir = g_file_new_for_path (pictures_path);
|
||||
cache_dir = bg_pictures_source_get_cache_file ();
|
||||
needs_download = !g_file_has_parent (file, pictures_dir) &&
|
||||
!g_file_has_parent (file, cache_dir);
|
||||
|
||||
if (!needs_download)
|
||||
{
|
||||
source_uri = g_strdup (uri);
|
||||
flags |= CC_BACKGROUND_ITEM_HAS_URI;
|
||||
}
|
||||
else
|
||||
{
|
||||
source_uri = g_steal_pointer (&uri);
|
||||
}
|
||||
|
||||
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", needs_download,
|
||||
"source-url", source_uri,
|
||||
NULL);
|
||||
|
||||
media = g_object_get_data (G_OBJECT (file), "grl-media");
|
||||
if (media == NULL)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT (file), "item", g_object_ref (item), g_object_unref);
|
||||
g_file_read_async (file, G_PRIORITY_DEFAULT,
|
||||
bg_source->cancellable,
|
||||
picture_opened_for_read, bg_source);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GFile) native_file = NULL;
|
||||
g_autoptr(GFile) thumbnail_file = NULL;
|
||||
g_autofree gchar *native_dir = NULL;
|
||||
g_autofree gchar *native_path = NULL;
|
||||
const gchar *title;
|
||||
const gchar *thumbnail_uri;
|
||||
|
||||
title = grl_media_get_title (media);
|
||||
g_object_set (G_OBJECT (item), "name", title, NULL);
|
||||
|
||||
thumbnail_uri = grl_media_get_thumbnail (media);
|
||||
thumbnail_file = g_file_new_for_uri (thumbnail_uri);
|
||||
|
||||
native_path = gnome_desktop_thumbnail_path_for_uri (source_uri, GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
native_file = g_file_new_for_path (native_path);
|
||||
|
||||
native_dir = g_path_get_dirname (native_path);
|
||||
g_mkdir_with_parents (native_dir, USER_DIR_MODE);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (thumbnail_file), "item", g_object_ref (item), g_object_unref);
|
||||
g_object_set_data_full (G_OBJECT (thumbnail_file),
|
||||
"native-file",
|
||||
g_object_ref (native_file),
|
||||
g_object_unref);
|
||||
g_file_copy_async (thumbnail_file,
|
||||
native_file,
|
||||
G_FILE_COPY_ALL_METADATA,
|
||||
G_PRIORITY_DEFAULT,
|
||||
bg_source->cancellable,
|
||||
NULL,
|
||||
NULL,
|
||||
picture_copied_for_read,
|
||||
bg_source);
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_single_file_from_info (BgPicturesSource *bg_source,
|
||||
GFile *file,
|
||||
GFileInfo *info)
|
||||
{
|
||||
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);
|
||||
return add_single_file (bg_source, file, content_type, mtime);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_single_file_from_media (BgPicturesSource *bg_source,
|
||||
GFile *file,
|
||||
GrlMedia *media)
|
||||
{
|
||||
GDateTime *mtime;
|
||||
const gchar *content_type;
|
||||
gint64 mtime_unix;
|
||||
|
||||
content_type = grl_media_get_mime (media);
|
||||
|
||||
/* only GRL_METADATA_KEY_CREATION_DATE is implemented in the Flickr
|
||||
* plugin, GRL_METADATA_KEY_MODIFICATION_DATE is not
|
||||
*/
|
||||
mtime = grl_media_get_creation_date (media);
|
||||
if (!mtime)
|
||||
mtime = grl_media_get_modification_date (media);
|
||||
if (mtime)
|
||||
mtime_unix = g_date_time_to_unix (mtime);
|
||||
else
|
||||
mtime_unix = g_get_real_time () / G_USEC_PER_SEC;
|
||||
|
||||
return add_single_file (bg_source, file, content_type, (guint64) mtime_unix);
|
||||
}
|
||||
|
||||
gboolean
|
||||
bg_pictures_source_add (BgPicturesSource *bg_source,
|
||||
const char *uri,
|
||||
GtkTreeRowReference **ret_row_ref)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
GFileInfo *info;
|
||||
gboolean retval;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
info = g_file_query_info (file, ATTRIBUTES, G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
||||
if (info == NULL)
|
||||
return FALSE;
|
||||
|
||||
retval = add_single_file_from_info (bg_source, file, info);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
gboolean
|
||||
bg_pictures_source_remove (BgPicturesSource *bg_source,
|
||||
const char *uri)
|
||||
{
|
||||
GListStore *store;
|
||||
gboolean retval;
|
||||
guint i;
|
||||
|
||||
retval = FALSE;
|
||||
store = bg_source_get_liststore (BG_SOURCE (bg_source));
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (store)); i++)
|
||||
{
|
||||
g_autoptr(CcBackgroundItem) tmp_item = NULL;
|
||||
const char *tmp_uri;
|
||||
|
||||
tmp_item = g_list_model_get_item (G_LIST_MODEL (store), i);
|
||||
tmp_uri = cc_background_item_get_uri (tmp_item);
|
||||
if (g_str_equal (tmp_uri, uri))
|
||||
{
|
||||
char *uuid;
|
||||
uuid = bg_pictures_source_get_unique_filename (uri);
|
||||
g_hash_table_insert (bg_source->known_items,
|
||||
uuid, NULL);
|
||||
|
||||
g_list_store_remove (store, i);
|
||||
retval = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
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 (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgPicturesSource *bg_source;
|
||||
GList *files, *l;
|
||||
g_autoptr(GError) err = NULL;
|
||||
GFile *parent;
|
||||
|
||||
files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source),
|
||||
res,
|
||||
&err);
|
||||
if (err)
|
||||
{
|
||||
if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Could not get pictures file information: %s", err->message);
|
||||
|
||||
g_list_foreach (files, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (files);
|
||||
return;
|
||||
}
|
||||
|
||||
bg_source = BG_PICTURES_SOURCE (user_data);
|
||||
|
||||
parent = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source));
|
||||
|
||||
files = g_list_sort (files, file_sort_func);
|
||||
|
||||
/* iterate over the available files */
|
||||
for (l = files; l; l = g_list_next (l))
|
||||
{
|
||||
GFileInfo *info = l->data;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
|
||||
file = g_file_get_child (parent, g_file_info_get_name (info));
|
||||
|
||||
add_single_file_from_info (bg_source, file, info);
|
||||
}
|
||||
|
||||
g_list_foreach (files, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (files);
|
||||
}
|
||||
|
||||
static void
|
||||
dir_enum_async_ready (GObject *s,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
BgPicturesSource *source = (BgPicturesSource *) user_data;
|
||||
g_autoptr(GFileEnumerator) enumerator = NULL;
|
||||
g_autoptr(GError) err = NULL;
|
||||
|
||||
enumerator = g_file_enumerate_children_finish (G_FILE (s), res, &err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Could not fill pictures source: %s", err->message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the files */
|
||||
g_file_enumerator_next_files_async (enumerator,
|
||||
G_MAXINT,
|
||||
G_PRIORITY_LOW,
|
||||
source->cancellable,
|
||||
file_info_async_ready,
|
||||
user_data);
|
||||
}
|
||||
|
||||
char *
|
||||
bg_pictures_source_get_cache_path (void)
|
||||
{
|
||||
return g_build_filename (g_get_user_cache_dir (),
|
||||
"gnome-control-center",
|
||||
"backgrounds",
|
||||
NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
bg_pictures_source_get_unique_filename (const char *uri)
|
||||
{
|
||||
g_autoptr(GChecksum) csum = NULL;
|
||||
char *ret;
|
||||
|
||||
csum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
g_checksum_update (csum, (guchar *) uri, -1);
|
||||
ret = g_strdup (g_checksum_get_string (csum));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
bg_pictures_source_get_unique_path (const char *uri)
|
||||
{
|
||||
g_autoptr(GFile) parent = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autofree gchar *cache_path = NULL;
|
||||
g_autofree gchar *filename = NULL;
|
||||
|
||||
cache_path = bg_pictures_source_get_cache_path ();
|
||||
parent = g_file_new_for_path (cache_path);
|
||||
|
||||
filename = bg_pictures_source_get_unique_filename (uri);
|
||||
file = g_file_get_child (parent, filename);
|
||||
|
||||
return g_file_get_path (file);
|
||||
}
|
||||
|
||||
gboolean
|
||||
bg_pictures_source_is_known (BgPicturesSource *bg_source,
|
||||
const char *uri)
|
||||
{
|
||||
g_autofree gchar *uuid = NULL;
|
||||
|
||||
uuid = bg_pictures_source_get_unique_filename (uri);
|
||||
|
||||
return GPOINTER_TO_INT (g_hash_table_lookup (bg_source->known_items, uuid));
|
||||
}
|
||||
|
||||
static void
|
||||
file_info_ready (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileInfo *info;
|
||||
GError *error = NULL;
|
||||
GFile *file = G_FILE (object);
|
||||
|
||||
info = g_file_query_info_finish (file, res, &error);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Problem looking up file info: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info);
|
||||
}
|
||||
|
||||
static void
|
||||
file_added (GFile *file,
|
||||
BgPicturesSource *self)
|
||||
{
|
||||
g_autofree gchar *uri = NULL;
|
||||
uri = g_file_get_uri (file);
|
||||
|
||||
if (!bg_pictures_source_is_known (self, uri))
|
||||
{
|
||||
g_file_query_info_async (file,
|
||||
ATTRIBUTES,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_LOW,
|
||||
NULL,
|
||||
file_info_ready,
|
||||
self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
files_changed_cb (BgPicturesSource *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:
|
||||
file_added (file, self);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
uri = g_file_get_uri (file);
|
||||
bg_pictures_source_remove (self, uri);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static GFileMonitor *
|
||||
monitor_path (BgPicturesSource *self,
|
||||
const char *path)
|
||||
{
|
||||
GFileMonitor *monitor;
|
||||
g_autoptr(GFile) dir = NULL;
|
||||
|
||||
g_mkdir_with_parents (path, USER_DIR_MODE);
|
||||
|
||||
dir = g_file_new_for_path (path);
|
||||
g_file_enumerate_children_async (dir,
|
||||
ATTRIBUTES,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_LOW, self->cancellable,
|
||||
dir_enum_async_ready, self);
|
||||
|
||||
monitor = g_file_monitor_directory (dir,
|
||||
G_FILE_MONITOR_NONE,
|
||||
self->cancellable,
|
||||
NULL);
|
||||
|
||||
if (monitor)
|
||||
g_signal_connect_object (monitor,
|
||||
"changed",
|
||||
G_CALLBACK (files_changed_cb),
|
||||
self, G_CONNECT_SWAPPED);
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
media_found_cb (BgPicturesSource *self, GrlMedia *media)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
const gchar *uri;
|
||||
|
||||
uri = grl_media_get_url (media);
|
||||
file = g_file_new_for_uri (uri);
|
||||
g_object_set_data_full (G_OBJECT (file), "grl-media", g_object_ref (media), g_object_unref);
|
||||
add_single_file_from_media (self, file, media);
|
||||
}
|
||||
|
||||
static void
|
||||
bg_pictures_source_init (BgPicturesSource *self)
|
||||
{
|
||||
const gchar *pictures_path;
|
||||
g_autofree gchar *cache_path = NULL;
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
self->known_items = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
NULL);
|
||||
|
||||
pictures_path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
|
||||
if (pictures_path == NULL)
|
||||
pictures_path = g_get_home_dir ();
|
||||
|
||||
self->picture_dir_monitor = monitor_path (self, pictures_path);
|
||||
|
||||
cache_path = bg_pictures_source_get_cache_path ();
|
||||
self->cache_dir_monitor = monitor_path (self, cache_path);
|
||||
|
||||
self->grl_miner = cc_background_grilo_miner_new ();
|
||||
g_signal_connect_object (self->grl_miner, "media-found", G_CALLBACK (media_found_cb), self, G_CONNECT_SWAPPED);
|
||||
cc_background_grilo_miner_start (self->grl_miner);
|
||||
}
|
||||
|
||||
BgPicturesSource *
|
||||
bg_pictures_source_new (GtkWidget *widget)
|
||||
{
|
||||
return g_object_new (BG_TYPE_PICTURES_SOURCE, "widget", widget, NULL);
|
||||
}
|
||||
|
||||
const char * const *
|
||||
bg_pictures_get_support_content_types (void)
|
||||
{
|
||||
return content_types;
|
||||
}
|
||||
46
panels/background/bg-pictures-source.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#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 (GtkWidget *widget);
|
||||
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
|
||||
@@ -41,6 +41,17 @@ struct _BgRecentSource
|
||||
|
||||
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,
|
||||
@@ -78,7 +89,7 @@ add_file_from_info (BgRecentSource *self,
|
||||
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_content_type_is_a (content_type, "image/*"))
|
||||
if (!content_type || !g_strv_contains (content_types, content_type))
|
||||
return;
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#define THUMBNAIL_WIDTH 144
|
||||
#define THUMBNAIL_WIDTH 154
|
||||
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -35,27 +35,6 @@ struct _BgWallpapersSource
|
||||
|
||||
G_DEFINE_TYPE (BgWallpapersSource, bg_wallpapers_source, BG_TYPE_SOURCE)
|
||||
|
||||
static int
|
||||
sort_func (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundItem *item_a;
|
||||
CcBackgroundItem *item_b;
|
||||
|
||||
item_a = (CcBackgroundItem *) a;
|
||||
item_b = (CcBackgroundItem *) b;
|
||||
|
||||
if (strcmp (cc_background_item_get_name (item_a), "Default Background") == 0)
|
||||
return -1;
|
||||
if (strcmp (cc_background_item_get_name (item_b), "Default Background") == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
return strcmp (cc_background_item_get_name (item_a),
|
||||
cc_background_item_get_name (item_b));
|
||||
}
|
||||
|
||||
static void
|
||||
load_wallpapers (gchar *key,
|
||||
CcBackgroundItem *item,
|
||||
@@ -69,7 +48,7 @@ load_wallpapers (gchar *key,
|
||||
if (deleted)
|
||||
return;
|
||||
|
||||
g_list_store_insert_sorted (store, item, sort_func, NULL);
|
||||
g_list_store_append (store, item);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
#include "bg-colors-source.h"
|
||||
#include "bg-pictures-source.h"
|
||||
#include "bg-recent-source.h"
|
||||
#include "bg-wallpapers-source.h"
|
||||
#include "cc-background-chooser.h"
|
||||
#include "cc-background-paintable.h"
|
||||
|
||||
struct _CcBackgroundChooser
|
||||
{
|
||||
@@ -85,63 +85,54 @@ on_delete_background_clicked_cb (GtkButton *button,
|
||||
bg_recent_source_remove_item (source, item);
|
||||
}
|
||||
|
||||
static void
|
||||
direction_changed_cb (GtkWidget *widget,
|
||||
GtkTextDirection *previous_direction,
|
||||
GdkPaintable *paintable)
|
||||
{
|
||||
g_object_set (paintable,
|
||||
"text-direction", gtk_widget_get_direction (widget),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_widget_func (gpointer model_item,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(CcBackgroundPaintable) paintable = NULL;
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
CcBackgroundItem *item;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *child;
|
||||
GtkWidget *picture;
|
||||
GtkWidget *image;
|
||||
GtkWidget *icon;
|
||||
GtkWidget *check;
|
||||
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);
|
||||
|
||||
paintable = cc_background_paintable_new (source, item);
|
||||
|
||||
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (paintable));
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
|
||||
g_object_bind_property (picture, "scale-factor",
|
||||
paintable, "scale-factor", G_BINDING_SYNC_CREATE);
|
||||
g_signal_connect_object (picture, "direction-changed",
|
||||
G_CALLBACK (direction_changed_cb), paintable, 0);
|
||||
|
||||
icon = gtk_image_new_from_icon_name ("slideshow-symbolic");
|
||||
gtk_widget_set_halign (icon, GTK_ALIGN_START);
|
||||
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_widget_add_css_class (icon, "slideshow-icon");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (icon), "slideshow-emblem");
|
||||
|
||||
check = gtk_image_new_from_icon_name ("background-selected-symbolic");
|
||||
gtk_widget_set_halign (check, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (check, GTK_ALIGN_END);
|
||||
gtk_widget_add_css_class (check, "selected-check");
|
||||
|
||||
if (BG_IS_RECENT_SOURCE (source))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("window-close-symbolic");
|
||||
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_widget_add_css_class (button, "osd");
|
||||
gtk_widget_add_css_class (button, "circular");
|
||||
gtk_widget_add_css_class (button, "remove-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",
|
||||
@@ -150,23 +141,17 @@ create_widget_func (gpointer model_item,
|
||||
}
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_widget_set_overflow (overlay, GTK_OVERFLOW_HIDDEN);
|
||||
gtk_widget_add_css_class (overlay, "background-thumbnail");
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), picture);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), image);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), icon);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), check);
|
||||
if (button)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (overlay),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL,
|
||||
cc_background_item_get_name (item),
|
||||
-1);
|
||||
gtk_widget_show (overlay);
|
||||
|
||||
|
||||
child = gtk_flow_box_child_new ();
|
||||
child = gtk_flow_box_child_new();
|
||||
gtk_widget_set_halign (child, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||
gtk_flow_box_child_set_child (GTK_FLOW_BOX_CHILD (child), overlay);
|
||||
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);
|
||||
|
||||
@@ -234,20 +219,67 @@ on_file_chooser_response_cb (GtkDialog *filechooser,
|
||||
{
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
g_autoptr(GListModel) files = NULL;
|
||||
guint i;
|
||||
g_autoptr(GSList) filenames = NULL;
|
||||
GSList *l;
|
||||
|
||||
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (filechooser));
|
||||
for (i = 0; i < g_list_model_get_n_items (files); i++)
|
||||
filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (filechooser));
|
||||
for (l = filenames; l != NULL; l = l->next)
|
||||
{
|
||||
g_autoptr(GFile) file = g_list_model_get_item (files, i);
|
||||
g_autofree gchar *filename = g_file_get_path (file);
|
||||
g_autofree gchar *filename = l->data;
|
||||
|
||||
bg_recent_source_add_file (self->recent_source, filename);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_window_destroy (GTK_WINDOW (filechooser));
|
||||
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 */
|
||||
@@ -301,14 +333,15 @@ cc_background_chooser_init (CcBackgroundChooser *self)
|
||||
void
|
||||
cc_background_chooser_select_file (CcBackgroundChooser *self)
|
||||
{
|
||||
g_autoptr(GFile) pictures_folder = NULL;
|
||||
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_native (GTK_WIDGET (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,
|
||||
@@ -317,15 +350,30 @@ cc_background_chooser_select_file (CcBackgroundChooser *self)
|
||||
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_select_multiple (GTK_FILE_CHOOSER (filechooser), TRUE);
|
||||
|
||||
pictures_folder = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser),
|
||||
pictures_folder,
|
||||
NULL);
|
||||
g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
|
||||
|
||||
g_signal_connect_object (filechooser,
|
||||
"response",
|
||||
|
||||
@@ -1,62 +1,88 @@
|
||||
<?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>
|
||||
|
||||
<!-- Recent -->
|
||||
<child>
|
||||
<object class="GtkBox" id="recent_box">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="halign">center</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="recent_flowbox">
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">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" />
|
||||
<style>
|
||||
<class name="background-flowbox"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="flowbox">
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">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" />
|
||||
<style>
|
||||
<class name="background-flowbox"/>
|
||||
</style>
|
||||
<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>
|
||||
|
||||
|
||||
315
panels/background/cc-background-grilo-miner.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <grilo.h>
|
||||
|
||||
#define GOA_API_IS_SUBJECT_TO_CHANGE
|
||||
#include <goa/goa.h>
|
||||
|
||||
#include "bg-pictures-source.h"
|
||||
#include "cc-background-grilo-miner.h"
|
||||
|
||||
struct _CcBackgroundGriloMiner
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GCancellable *cancellable;
|
||||
GList *accounts;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcBackgroundGriloMiner, cc_background_grilo_miner, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
MEDIA_FOUND,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
#define REMOTE_ITEM_COUNT 50
|
||||
|
||||
static gchar *
|
||||
get_grilo_id (GoaObject *goa_object)
|
||||
{
|
||||
GoaAccount *account;
|
||||
|
||||
account = goa_object_peek_account (goa_object);
|
||||
return g_strdup_printf ("grl-flickr-%s", goa_account_get_id (account));
|
||||
}
|
||||
|
||||
static void
|
||||
is_online_data_cached (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundGriloMiner *self;
|
||||
GError *error = NULL;
|
||||
GFileInfo *info = NULL;
|
||||
GFile *cache_file = G_FILE (object);
|
||||
GrlMedia *media;
|
||||
const gchar *uri;
|
||||
|
||||
info = g_file_query_info_finish (cache_file, res, &error);
|
||||
if (info == NULL)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
goto out;
|
||||
}
|
||||
|
||||
self = CC_BACKGROUND_GRILO_MINER (user_data);
|
||||
|
||||
media = g_object_get_data (G_OBJECT (cache_file), "grl-media");
|
||||
uri = grl_media_get_url (media);
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
g_debug ("Ignored URL '%s' as it is already in the cache", uri);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[MEDIA_FOUND], 0, media);
|
||||
|
||||
out:
|
||||
g_clear_object (&info);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
searched_online_source (GrlSource *source,
|
||||
guint operation_id,
|
||||
GrlMedia *media,
|
||||
guint remaining,
|
||||
gpointer user_data,
|
||||
const GError *error)
|
||||
{
|
||||
CcBackgroundGriloMiner *self = CC_BACKGROUND_GRILO_MINER (user_data);
|
||||
g_autoptr(GFile) cache_file = NULL;
|
||||
const gchar *uri;
|
||||
g_autofree gchar *cache_path = NULL;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
const gchar *source_id;
|
||||
|
||||
source_id = grl_source_get_id (source);
|
||||
g_warning ("Error searching %s: %s", source_id, error->message);
|
||||
grl_operation_cancel (operation_id);
|
||||
remaining = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uri = grl_media_get_url (media);
|
||||
cache_path = bg_pictures_source_get_unique_path (uri);
|
||||
cache_file = g_file_new_for_path (cache_path);
|
||||
g_object_set_data_full (G_OBJECT (cache_file), "grl-media", media, g_object_unref);
|
||||
g_file_query_info_async (cache_file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
is_online_data_cached,
|
||||
self);
|
||||
|
||||
out:
|
||||
if (remaining == 0)
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
static void
|
||||
query_online_source (CcBackgroundGriloMiner *self, GrlSource *source)
|
||||
{
|
||||
const GList *keys;
|
||||
GrlCaps *caps;
|
||||
GrlOperationOptions *options;
|
||||
|
||||
keys = grl_source_supported_keys (source);
|
||||
caps = grl_source_get_caps (source, GRL_OP_BROWSE);
|
||||
options = grl_operation_options_new (caps);
|
||||
grl_operation_options_set_count (options, REMOTE_ITEM_COUNT);
|
||||
grl_operation_options_set_resolution_flags (options, GRL_RESOLVE_FAST_ONLY);
|
||||
grl_operation_options_set_type_filter (options, GRL_TYPE_FILTER_IMAGE);
|
||||
|
||||
grl_source_search (source, NULL, keys, options, searched_online_source, g_object_ref (self));
|
||||
g_object_unref (options);
|
||||
}
|
||||
|
||||
static void
|
||||
add_online_source_cb (CcBackgroundGriloMiner *self,
|
||||
GrlSource *source)
|
||||
{
|
||||
GList *l;
|
||||
gboolean found = FALSE;
|
||||
const gchar *source_id;
|
||||
|
||||
source_id = grl_source_get_id (source);
|
||||
for (l = self->accounts; l != NULL && !found; l = l->next)
|
||||
{
|
||||
GoaObject *goa_object = GOA_OBJECT (l->data);
|
||||
g_autofree gchar *account_id = NULL;
|
||||
|
||||
account_id = get_grilo_id (goa_object);
|
||||
if (g_strcmp0 (source_id, account_id) == 0)
|
||||
{
|
||||
query_online_source (self, source);
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_async_ready (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundGriloMiner *self;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GList *accounts = NULL;
|
||||
GList *photo_accounts = NULL;
|
||||
GList *l;
|
||||
GoaClient *client = NULL;
|
||||
GrlRegistry *registry;
|
||||
|
||||
client = goa_client_new_finish (res, &error);
|
||||
if (client == NULL)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to create GoaClient: %s", error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
self = CC_BACKGROUND_GRILO_MINER (user_data);
|
||||
|
||||
accounts = goa_client_get_accounts (client);
|
||||
for (l = accounts; l != NULL; l = l->next)
|
||||
{
|
||||
GoaObject *goa_object = GOA_OBJECT (l->data);
|
||||
GoaAccount *account;
|
||||
GoaPhotos *photos;
|
||||
const gchar *provider_type;
|
||||
|
||||
account = goa_object_peek_account (goa_object);
|
||||
provider_type = goa_account_get_provider_type (account);
|
||||
|
||||
photos = goa_object_peek_photos (goa_object);
|
||||
if (photos != NULL && g_strcmp0 (provider_type, "flickr") == 0)
|
||||
photo_accounts = g_list_prepend (photo_accounts, g_object_ref (goa_object));
|
||||
}
|
||||
|
||||
if (photo_accounts == NULL)
|
||||
goto out;
|
||||
|
||||
registry = grl_registry_get_default ();
|
||||
|
||||
for (l = photo_accounts; l != NULL; l = l->next)
|
||||
{
|
||||
GoaObject *goa_object = GOA_OBJECT (l->data);
|
||||
GrlSource *source;
|
||||
g_autofree gchar *account_id = NULL;
|
||||
|
||||
account_id = get_grilo_id (goa_object);
|
||||
source = grl_registry_lookup_source (registry, account_id);
|
||||
if (source != NULL)
|
||||
query_online_source (self, source);
|
||||
}
|
||||
|
||||
self->accounts = photo_accounts;
|
||||
photo_accounts = NULL;
|
||||
|
||||
g_signal_connect_object (registry, "source-added", G_CALLBACK (add_online_source_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
out:
|
||||
g_list_free_full (photo_accounts, g_object_unref);
|
||||
g_list_free_full (accounts, g_object_unref);
|
||||
g_clear_object (&client);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_online_accounts (CcBackgroundGriloMiner *self)
|
||||
{
|
||||
goa_client_new (self->cancellable, client_async_ready, self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_grilo_miner_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundGriloMiner *self = CC_BACKGROUND_GRILO_MINER (object);
|
||||
|
||||
if (self->cancellable)
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
}
|
||||
|
||||
if (self->accounts)
|
||||
{
|
||||
g_list_free_full (self->accounts, g_object_unref);
|
||||
self->accounts = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (cc_background_grilo_miner_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_grilo_miner_init (CcBackgroundGriloMiner *self)
|
||||
{
|
||||
self->cancellable = g_cancellable_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_grilo_miner_class_init (CcBackgroundGriloMinerClass *klass)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GrlRegistry *registry;
|
||||
|
||||
object_class->dispose = cc_background_grilo_miner_dispose;
|
||||
|
||||
signals[MEDIA_FOUND] = g_signal_new ("media-found",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, /* class_offset */
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accu_data */
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
GRL_TYPE_MEDIA);
|
||||
|
||||
grl_init (NULL, NULL);
|
||||
registry = grl_registry_get_default ();
|
||||
|
||||
error = NULL;
|
||||
if (!grl_registry_load_all_plugins (registry, FALSE, &error) ||
|
||||
!grl_registry_activate_plugin_by_id (registry, "grl-flickr", &error))
|
||||
g_warning ("%s", error->message);
|
||||
}
|
||||
|
||||
CcBackgroundGriloMiner *
|
||||
cc_background_grilo_miner_new (void)
|
||||
{
|
||||
return g_object_new (CC_TYPE_BACKGROUND_GRILO_MINER, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cc_background_grilo_miner_start (CcBackgroundGriloMiner *self)
|
||||
{
|
||||
setup_online_accounts (self);
|
||||
}
|
||||
31
panels/background/cc-background-grilo-miner.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#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);
|
||||
|
||||
CcBackgroundGriloMiner *cc_background_grilo_miner_new (void);
|
||||
|
||||
void cc_background_grilo_miner_start (CcBackgroundGriloMiner *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -26,20 +26,12 @@
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include <gnome-bg/gnome-bg.h>
|
||||
#include <libgnome-desktop/gnome-bg.h>
|
||||
#include <gdesktop-enums.h>
|
||||
|
||||
#include "cc-background-item.h"
|
||||
#include "gdesktop-enums-types.h"
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
int frame;
|
||||
int scale_factor;
|
||||
GdkPixbuf *thumbnail;
|
||||
} CachedThumbnail;
|
||||
|
||||
struct _CcBackgroundItem
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -47,7 +39,6 @@ struct _CcBackgroundItem
|
||||
/* properties */
|
||||
char *name;
|
||||
char *uri;
|
||||
char *uri_dark;
|
||||
char *size;
|
||||
GDesktopBackgroundStyle placement;
|
||||
GDesktopBackgroundShading shading;
|
||||
@@ -66,17 +57,19 @@ struct _CcBackgroundItem
|
||||
int width;
|
||||
int height;
|
||||
|
||||
GnomeBG *bg_dark;
|
||||
|
||||
CachedThumbnail cached_thumbnail;
|
||||
CachedThumbnail cached_thumbnail_dark;
|
||||
struct {
|
||||
int width;
|
||||
int height;
|
||||
int frame;
|
||||
int scale_factor;
|
||||
GdkPixbuf *thumbnail;
|
||||
} cached_thumbnail;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_URI,
|
||||
PROP_URI_DARK,
|
||||
PROP_PLACEMENT,
|
||||
PROP_SHADING,
|
||||
PROP_PRIMARY_COLOR,
|
||||
@@ -109,15 +102,6 @@ set_bg_properties (CcBackgroundItem *item)
|
||||
gnome_bg_set_filename (item->bg, filename);
|
||||
}
|
||||
|
||||
if (item->uri_dark) {
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autofree gchar *filename = NULL;
|
||||
|
||||
file = g_file_new_for_commandline_arg (item->uri_dark);
|
||||
filename = g_file_get_path (file);
|
||||
gnome_bg_set_filename (item->bg_dark, filename);
|
||||
}
|
||||
|
||||
if (item->primary_color != NULL) {
|
||||
gdk_rgba_parse (&pcolor, item->primary_color);
|
||||
}
|
||||
@@ -126,9 +110,7 @@ set_bg_properties (CcBackgroundItem *item)
|
||||
}
|
||||
|
||||
gnome_bg_set_rgba (item->bg, item->shading, &pcolor, &scolor);
|
||||
gnome_bg_set_rgba (item->bg_dark, item->shading, &pcolor, &scolor);
|
||||
gnome_bg_set_placement (item->bg, item->placement);
|
||||
gnome_bg_set_placement (item->bg_dark, item->placement);
|
||||
}
|
||||
|
||||
|
||||
@@ -143,20 +125,9 @@ cc_background_item_changes_with_time (CcBackgroundItem *item)
|
||||
if (item->bg != NULL) {
|
||||
changes = gnome_bg_changes_with_time (item->bg);
|
||||
}
|
||||
if (item->bg_dark != NULL) {
|
||||
changes |= gnome_bg_changes_with_time (item->bg_dark);
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_background_item_has_dark_version (CcBackgroundItem *item)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), FALSE);
|
||||
|
||||
return item->uri && item->uri_dark;
|
||||
}
|
||||
|
||||
static void
|
||||
update_size (CcBackgroundItem *item)
|
||||
{
|
||||
@@ -185,7 +156,11 @@ 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;
|
||||
}
|
||||
@@ -197,27 +172,21 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
int height,
|
||||
int scale_factor,
|
||||
int frame,
|
||||
gboolean force_size,
|
||||
gboolean dark)
|
||||
gboolean force_size)
|
||||
{
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
g_autoptr(GdkPixbuf) retval = NULL;
|
||||
CachedThumbnail *thumbnail;
|
||||
GnomeBG *bg;
|
||||
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
|
||||
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
||||
|
||||
thumbnail = dark ? &item->cached_thumbnail_dark : &item->cached_thumbnail;
|
||||
bg = dark ? item->bg_dark : item->bg;
|
||||
|
||||
/* Use the cached thumbnail if the sizes match */
|
||||
if (thumbnail->thumbnail &&
|
||||
thumbnail->width == width &&
|
||||
thumbnail->height == height &&
|
||||
thumbnail->scale_factor == scale_factor &&
|
||||
thumbnail->frame == frame)
|
||||
return g_object_ref (thumbnail->thumbnail);
|
||||
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);
|
||||
|
||||
@@ -229,30 +198,19 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
* the slideshow frame though, so we can't do much better than this
|
||||
* for now.
|
||||
*/
|
||||
pixbuf = render_at_size (bg, width, height);
|
||||
pixbuf = render_at_size (item->bg, width, height);
|
||||
} else {
|
||||
g_autoptr(GdkMonitor) monitor = NULL;
|
||||
GdkDisplay *display;
|
||||
GListModel *monitors;
|
||||
GdkRectangle monitor_layout;
|
||||
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
monitors = gdk_display_get_monitors (display);
|
||||
monitor = g_list_model_get_item (monitors, 0);
|
||||
gdk_monitor_get_geometry (monitor, &monitor_layout);
|
||||
|
||||
if (frame >= 0) {
|
||||
pixbuf = gnome_bg_create_frame_thumbnail (bg,
|
||||
pixbuf = gnome_bg_create_frame_thumbnail (item->bg,
|
||||
thumbs,
|
||||
&monitor_layout,
|
||||
gdk_screen_get_default (),
|
||||
width,
|
||||
height,
|
||||
frame);
|
||||
} else {
|
||||
pixbuf = gnome_bg_create_thumbnail (bg,
|
||||
pixbuf = gnome_bg_create_thumbnail (item->bg,
|
||||
thumbs,
|
||||
&monitor_layout,
|
||||
gdk_screen_get_default (),
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@@ -260,7 +218,7 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
|
||||
retval = g_steal_pointer (&pixbuf);
|
||||
|
||||
gnome_bg_get_image_size (bg,
|
||||
gnome_bg_get_image_size (item->bg,
|
||||
thumbs,
|
||||
width,
|
||||
height,
|
||||
@@ -270,11 +228,11 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
update_size (item);
|
||||
|
||||
/* Cache the new thumbnail */
|
||||
g_set_object (&thumbnail->thumbnail, retval);
|
||||
thumbnail->width = width;
|
||||
thumbnail->height = height;
|
||||
thumbnail->scale_factor = scale_factor;
|
||||
thumbnail->frame = frame;
|
||||
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);
|
||||
}
|
||||
@@ -285,10 +243,9 @@ cc_background_item_get_thumbnail (CcBackgroundItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs,
|
||||
int width,
|
||||
int height,
|
||||
int scale_factor,
|
||||
gboolean dark)
|
||||
int scale_factor)
|
||||
{
|
||||
return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, scale_factor, -1, FALSE, dark);
|
||||
return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, scale_factor, -1, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -398,21 +355,6 @@ _set_uri (CcBackgroundItem *item,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_set_uri_dark (CcBackgroundItem *item,
|
||||
const char *value)
|
||||
{
|
||||
g_free (item->uri_dark);
|
||||
if (value && *value == '\0') {
|
||||
item->uri_dark = NULL;
|
||||
} else {
|
||||
if (value && strstr (value, "://") == NULL)
|
||||
g_warning ("URI '%s' is invalid", value);
|
||||
item->uri_dark = g_strdup (value);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
cc_background_item_get_uri (CcBackgroundItem *item)
|
||||
{
|
||||
@@ -421,14 +363,6 @@ cc_background_item_get_uri (CcBackgroundItem *item)
|
||||
return item->uri;
|
||||
}
|
||||
|
||||
const char *
|
||||
cc_background_item_get_uri_dark (CcBackgroundItem *item)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
|
||||
|
||||
return item->uri_dark;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_placement (CcBackgroundItem *item,
|
||||
GDesktopBackgroundStyle value)
|
||||
@@ -600,9 +534,6 @@ cc_background_item_set_property (GObject *object,
|
||||
case PROP_URI:
|
||||
_set_uri (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_URI_DARK:
|
||||
_set_uri_dark (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PLACEMENT:
|
||||
_set_placement (self, g_value_get_enum (value));
|
||||
break;
|
||||
@@ -653,12 +584,9 @@ cc_background_item_get_property (GObject *object,
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, self->name);
|
||||
break;
|
||||
case PROP_URI:
|
||||
case PROP_URI:
|
||||
g_value_set_string (value, self->uri);
|
||||
break;
|
||||
case PROP_URI_DARK:
|
||||
g_value_set_string (value, self->uri_dark);
|
||||
break;
|
||||
case PROP_PLACEMENT:
|
||||
g_value_set_enum (value, self->placement);
|
||||
break;
|
||||
@@ -736,13 +664,6 @@ cc_background_item_class_init (CcBackgroundItemClass *klass)
|
||||
"uri",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_URI_DARK,
|
||||
g_param_spec_string ("uri-dark",
|
||||
"uri-dark",
|
||||
"uri-dark",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PLACEMENT,
|
||||
g_param_spec_enum ("placement",
|
||||
@@ -839,7 +760,6 @@ static void
|
||||
cc_background_item_init (CcBackgroundItem *item)
|
||||
{
|
||||
item->bg = gnome_bg_new ();
|
||||
item->bg_dark = gnome_bg_new ();
|
||||
|
||||
item->shading = G_DESKTOP_BACKGROUND_SHADING_SOLID;
|
||||
item->placement = G_DESKTOP_BACKGROUND_STYLE_SCALED;
|
||||
@@ -863,7 +783,6 @@ cc_background_item_finalize (GObject *object)
|
||||
g_return_if_fail (item != NULL);
|
||||
|
||||
g_clear_object (&item->cached_thumbnail.thumbnail);
|
||||
g_clear_object (&item->cached_thumbnail_dark.thumbnail);
|
||||
g_free (item->name);
|
||||
g_free (item->uri);
|
||||
g_free (item->primary_color);
|
||||
@@ -873,8 +792,8 @@ cc_background_item_finalize (GObject *object)
|
||||
g_free (item->source_url);
|
||||
g_free (item->source_xml);
|
||||
|
||||
g_clear_object (&item->bg);
|
||||
g_clear_object (&item->bg_dark);
|
||||
if (item->bg != NULL)
|
||||
g_object_unref (item->bg);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_item_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -1033,10 +952,6 @@ cc_background_item_compare (CcBackgroundItem *saved,
|
||||
if (files_equal (saved->uri, configured->uri) == FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
if (flags & CC_BACKGROUND_ITEM_HAS_URI_DARK) {
|
||||
if (files_equal (saved->uri_dark, configured->uri_dark) == FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
if (flags & CC_BACKGROUND_ITEM_HAS_SHADING) {
|
||||
if (saved->shading != configured->shading)
|
||||
return FALSE;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
#include <gdesktop-enums.h>
|
||||
#include <gnome-bg/gnome-bg.h>
|
||||
#include <libgnome-desktop/gnome-bg.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -35,8 +35,7 @@ typedef enum {
|
||||
CC_BACKGROUND_ITEM_HAS_PLACEMENT = 1 << 1,
|
||||
CC_BACKGROUND_ITEM_HAS_PCOLOR = 1 << 2,
|
||||
CC_BACKGROUND_ITEM_HAS_SCOLOR = 1 << 3,
|
||||
CC_BACKGROUND_ITEM_HAS_URI = 1 << 4,
|
||||
CC_BACKGROUND_ITEM_HAS_URI_DARK = 1 << 5
|
||||
CC_BACKGROUND_ITEM_HAS_URI = 1 << 4
|
||||
} CcBackgroundItemFlags;
|
||||
|
||||
#define CC_BACKGROUND_ITEM_HAS_ALL (CC_BACKGROUND_ITEM_HAS_SHADING & \
|
||||
@@ -47,30 +46,26 @@ typedef enum {
|
||||
|
||||
CcBackgroundItem * cc_background_item_new (const char *uri);
|
||||
CcBackgroundItem * cc_background_item_copy (CcBackgroundItem *item);
|
||||
gboolean cc_background_item_load (CcBackgroundItem *item,
|
||||
GFileInfo *info);
|
||||
gboolean cc_background_item_load (CcBackgroundItem *item,
|
||||
GFileInfo *info);
|
||||
gboolean cc_background_item_changes_with_time (CcBackgroundItem *item);
|
||||
gboolean cc_background_item_has_dark_version (CcBackgroundItem *item);
|
||||
|
||||
GdkPixbuf * cc_background_item_get_thumbnail (CcBackgroundItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs,
|
||||
int width,
|
||||
int height,
|
||||
int scale_factor,
|
||||
gboolean dark);
|
||||
int scale_factor);
|
||||
GdkPixbuf * cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs,
|
||||
int width,
|
||||
int height,
|
||||
int scale_factor,
|
||||
int frame,
|
||||
gboolean force_size,
|
||||
gboolean dark);
|
||||
gboolean force_size);
|
||||
|
||||
GDesktopBackgroundStyle cc_background_item_get_placement (CcBackgroundItem *item);
|
||||
GDesktopBackgroundShading cc_background_item_get_shading (CcBackgroundItem *item);
|
||||
const char * cc_background_item_get_uri (CcBackgroundItem *item);
|
||||
const char * cc_background_item_get_uri_dark (CcBackgroundItem *item);
|
||||
const char * cc_background_item_get_source_url (CcBackgroundItem *item);
|
||||
const char * cc_background_item_get_source_xml (CcBackgroundItem *item);
|
||||
CcBackgroundItemFlags cc_background_item_get_flags (CcBackgroundItem *item);
|
||||
|
||||
@@ -1,314 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2021 Alexander Mikhaylenko <alexm@gnome.org>
|
||||
*
|
||||
* 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 "cc-background-paintable.h"
|
||||
|
||||
struct _CcBackgroundPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
BgSource *source;
|
||||
CcBackgroundItem *item;
|
||||
int scale_factor;
|
||||
GtkTextDirection text_direction;
|
||||
|
||||
GdkPaintable *texture;
|
||||
GdkPaintable *dark_texture;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_SOURCE,
|
||||
PROP_ITEM,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_TEXT_DIRECTION,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void cc_background_paintable_paintable_init (GdkPaintableInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (CcBackgroundPaintable, cc_background_paintable, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
cc_background_paintable_paintable_init))
|
||||
|
||||
static void
|
||||
update_cache (CcBackgroundPaintable *self)
|
||||
{
|
||||
g_autoptr (GdkPixbuf) pixbuf = NULL;
|
||||
GnomeDesktopThumbnailFactory *factory;
|
||||
int width, height;
|
||||
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_object (&self->dark_texture);
|
||||
|
||||
factory = bg_source_get_thumbnail_factory (self->source);
|
||||
width = bg_source_get_thumbnail_width (self->source);
|
||||
height = bg_source_get_thumbnail_height (self->source);
|
||||
|
||||
pixbuf = cc_background_item_get_thumbnail (self->item,
|
||||
factory,
|
||||
width,
|
||||
height,
|
||||
self->scale_factor,
|
||||
FALSE);
|
||||
|
||||
self->texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
|
||||
|
||||
if (cc_background_item_has_dark_version (self->item))
|
||||
{
|
||||
g_autoptr (GdkPixbuf) dark_pixbuf = NULL;
|
||||
|
||||
dark_pixbuf = cc_background_item_get_thumbnail (self->item,
|
||||
factory,
|
||||
width,
|
||||
height,
|
||||
self->scale_factor,
|
||||
TRUE);
|
||||
self->dark_texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (dark_pixbuf));
|
||||
}
|
||||
|
||||
gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object);
|
||||
|
||||
g_clear_object (&self->item);
|
||||
g_clear_object (&self->source);
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_object (&self->dark_texture);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_paintable_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_constructed (GObject *object)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_paintable_parent_class)->constructed (object);
|
||||
|
||||
update_cache (self);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, self->source);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, self->item);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, self->scale_factor);
|
||||
break;
|
||||
|
||||
case PROP_TEXT_DIRECTION:
|
||||
g_value_set_enum (value, self->text_direction);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_set_object (&self->source, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_set_object (&self->item, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
self->scale_factor = g_value_get_int (value);
|
||||
update_cache (self);
|
||||
break;
|
||||
|
||||
case PROP_TEXT_DIRECTION:
|
||||
self->text_direction = g_value_get_enum (value);
|
||||
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_class_init (CcBackgroundPaintableClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = cc_background_paintable_dispose;
|
||||
object_class->constructed = cc_background_paintable_constructed;
|
||||
object_class->get_property = cc_background_paintable_get_property;
|
||||
object_class->set_property = cc_background_paintable_set_property;
|
||||
|
||||
properties[PROP_SOURCE] =
|
||||
g_param_spec_object ("source",
|
||||
"Source",
|
||||
"Source",
|
||||
BG_TYPE_SOURCE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_ITEM] =
|
||||
g_param_spec_object ("item",
|
||||
"Item",
|
||||
"Item",
|
||||
CC_TYPE_BACKGROUND_ITEM,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
"Scale Factor",
|
||||
"Scale Factor",
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_TEXT_DIRECTION] =
|
||||
g_param_spec_enum ("text-direction",
|
||||
"Text Direction",
|
||||
"Text Direction",
|
||||
GTK_TYPE_TEXT_DIRECTION,
|
||||
GTK_TEXT_DIR_LTR,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_init (CcBackgroundPaintable *self)
|
||||
{
|
||||
self->scale_factor = 1;
|
||||
self->text_direction = GTK_TEXT_DIR_LTR;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
gboolean is_rtl;
|
||||
|
||||
if (!self->dark_texture)
|
||||
{
|
||||
gdk_paintable_snapshot (self->texture, snapshot, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
is_rtl = self->text_direction == GTK_TEXT_DIR_RTL;
|
||||
|
||||
gtk_snapshot_push_clip (GTK_SNAPSHOT (snapshot),
|
||||
&GRAPHENE_RECT_INIT (is_rtl ? width / 2.0f : 0.0f,
|
||||
0.0f,
|
||||
width / 2.0f,
|
||||
height));
|
||||
gdk_paintable_snapshot (self->texture, snapshot, width, height);
|
||||
gtk_snapshot_pop (GTK_SNAPSHOT (snapshot));
|
||||
|
||||
gtk_snapshot_push_clip (GTK_SNAPSHOT (snapshot),
|
||||
&GRAPHENE_RECT_INIT (is_rtl ? 0.0f : width / 2.0f,
|
||||
0.0f,
|
||||
width / 2.0f,
|
||||
height));
|
||||
gdk_paintable_snapshot (self->dark_texture, snapshot, width, height);
|
||||
gtk_snapshot_pop (GTK_SNAPSHOT (snapshot));
|
||||
}
|
||||
|
||||
static int
|
||||
cc_background_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
|
||||
return gdk_paintable_get_intrinsic_width (self->texture) / self->scale_factor;
|
||||
}
|
||||
|
||||
static int
|
||||
cc_background_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
|
||||
return gdk_paintable_get_intrinsic_height (self->texture) / self->scale_factor;
|
||||
}
|
||||
|
||||
static double
|
||||
cc_background_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
{
|
||||
CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable);
|
||||
|
||||
return gdk_paintable_get_intrinsic_aspect_ratio (self->texture);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_paintable_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = cc_background_paintable_snapshot;
|
||||
iface->get_intrinsic_width = cc_background_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = cc_background_paintable_get_intrinsic_height;
|
||||
iface->get_intrinsic_aspect_ratio = cc_background_paintable_get_intrinsic_aspect_ratio;
|
||||
}
|
||||
|
||||
CcBackgroundPaintable *
|
||||
cc_background_paintable_new (BgSource *source,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
g_return_val_if_fail (BG_IS_SOURCE (source), NULL);
|
||||
g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
|
||||
|
||||
return g_object_new (CC_TYPE_BACKGROUND_PAINTABLE,
|
||||
"source", source,
|
||||
"item", item,
|
||||
NULL);
|
||||
}
|
||||
@@ -35,18 +35,16 @@
|
||||
#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"
|
||||
#define WP_URI_DARK_KEY "picture-uri-dark"
|
||||
#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"
|
||||
|
||||
#define INTERFACE_PATH_ID "org.gnome.desktop.interface"
|
||||
#define INTERFACE_COLOR_SCHEME_KEY "color-scheme"
|
||||
|
||||
struct _CcBackgroundPanel
|
||||
{
|
||||
CcPanel parent_instance;
|
||||
@@ -55,135 +53,25 @@ struct _CcBackgroundPanel
|
||||
|
||||
GSettings *settings;
|
||||
GSettings *lock_settings;
|
||||
GSettings *interface_settings;
|
||||
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
CcBackgroundItem *current_background;
|
||||
|
||||
CcBackgroundChooser *background_chooser;
|
||||
CcBackgroundPreview *default_preview;
|
||||
CcBackgroundPreview *dark_preview;
|
||||
GtkToggleButton *default_toggle;
|
||||
GtkToggleButton *dark_toggle;
|
||||
GtkButton *add_picture_button;
|
||||
CcBackgroundPreview *desktop_preview;
|
||||
};
|
||||
|
||||
CC_PANEL_REGISTER (CcBackgroundPanel, cc_background_panel)
|
||||
|
||||
static void
|
||||
load_custom_css (CcBackgroundPanel *self)
|
||||
{
|
||||
g_autoptr(GtkCssProvider) provider = NULL;
|
||||
|
||||
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_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_color_scheme_toggles (CcBackgroundPanel *self)
|
||||
{
|
||||
GDesktopColorScheme scheme;
|
||||
|
||||
scheme = g_settings_get_enum (self->interface_settings, INTERFACE_COLOR_SCHEME_KEY);
|
||||
|
||||
if (scheme == G_DESKTOP_COLOR_SCHEME_DEFAULT)
|
||||
{
|
||||
gtk_toggle_button_set_active (self->default_toggle, TRUE);
|
||||
}
|
||||
else if (scheme == G_DESKTOP_COLOR_SCHEME_PREFER_DARK)
|
||||
{
|
||||
gtk_toggle_button_set_active (self->dark_toggle, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_toggle_button_set_active (self->default_toggle, FALSE);
|
||||
gtk_toggle_button_set_active (self->dark_toggle, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
transition_screen (CcBackgroundPanel *self)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!self->proxy)
|
||||
return;
|
||||
|
||||
g_dbus_proxy_call_sync (self->proxy,
|
||||
"ScreenTransition",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
g_warning ("Couldn't transition screen: %s", error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
set_color_scheme (CcBackgroundPanel *self,
|
||||
GDesktopColorScheme color_scheme)
|
||||
{
|
||||
GDesktopColorScheme scheme;
|
||||
|
||||
scheme = g_settings_get_enum (self->interface_settings,
|
||||
INTERFACE_COLOR_SCHEME_KEY);
|
||||
|
||||
/* We have to check the equality manually to avoid starting an unnecessary
|
||||
* screen transition */
|
||||
if (color_scheme == scheme)
|
||||
return;
|
||||
|
||||
transition_screen (self);
|
||||
|
||||
g_settings_set_enum (self->interface_settings,
|
||||
INTERFACE_COLOR_SCHEME_KEY,
|
||||
color_scheme);
|
||||
}
|
||||
|
||||
/* Color schemes */
|
||||
|
||||
static void
|
||||
on_color_scheme_toggle_active_cb (CcBackgroundPanel *self)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (self->default_toggle))
|
||||
set_color_scheme (self, G_DESKTOP_COLOR_SCHEME_DEFAULT);
|
||||
else if (gtk_toggle_button_get_active (self->dark_toggle))
|
||||
set_color_scheme (self, G_DESKTOP_COLOR_SCHEME_PREFER_DARK);
|
||||
}
|
||||
|
||||
static void
|
||||
got_transition_proxy_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
CcBackgroundPanel *self = data;
|
||||
|
||||
self->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
|
||||
if (self->proxy == NULL)
|
||||
{
|
||||
g_warning ("Error creating proxy: %s", error->message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Background */
|
||||
|
||||
static void
|
||||
update_preview (CcBackgroundPanel *panel)
|
||||
{
|
||||
CcBackgroundItem *current_background;
|
||||
|
||||
current_background = panel->current_background;
|
||||
cc_background_preview_set_item (panel->default_preview, current_background);
|
||||
cc_background_preview_set_item (panel->dark_preview, current_background);
|
||||
cc_background_preview_set_item (panel->desktop_preview, current_background);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
@@ -203,7 +91,6 @@ reload_current_bg (CcBackgroundPanel *panel)
|
||||
CcBackgroundItem *configured;
|
||||
GSettings *settings = NULL;
|
||||
g_autofree gchar *uri = NULL;
|
||||
g_autofree gchar *dark_uri = NULL;
|
||||
g_autofree gchar *pcolor = NULL;
|
||||
g_autofree gchar *scolor = NULL;
|
||||
|
||||
@@ -217,15 +104,12 @@ reload_current_bg (CcBackgroundPanel *panel)
|
||||
if (uri && *uri == '\0')
|
||||
g_clear_pointer (&uri, g_free);
|
||||
|
||||
|
||||
configured = cc_background_item_new (uri);
|
||||
|
||||
dark_uri = g_settings_get_string (settings, WP_URI_DARK_KEY);
|
||||
pcolor = g_settings_get_string (settings, WP_PCOLOR_KEY);
|
||||
scolor = g_settings_get_string (settings, WP_SCOLOR_KEY);
|
||||
g_object_set (G_OBJECT (configured),
|
||||
"name", _("Current background"),
|
||||
"uri-dark", dark_uri,
|
||||
"placement", g_settings_get_enum (settings, WP_OPTIONS_KEY),
|
||||
"shading", g_settings_get_enum (settings, WP_SHADING_KEY),
|
||||
"primary-color", pcolor,
|
||||
@@ -272,8 +156,7 @@ create_save_dir (void)
|
||||
static void
|
||||
set_background (CcBackgroundPanel *panel,
|
||||
GSettings *settings,
|
||||
CcBackgroundItem *item,
|
||||
gboolean set_dark)
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
GDesktopBackgroundStyle style;
|
||||
CcBackgroundItemFlags flags;
|
||||
@@ -288,18 +171,6 @@ set_background (CcBackgroundPanel *panel,
|
||||
|
||||
g_settings_set_string (settings, WP_URI_KEY, uri);
|
||||
|
||||
if (set_dark)
|
||||
{
|
||||
const char *uri_dark;
|
||||
|
||||
uri_dark = cc_background_item_get_uri_dark (item);
|
||||
|
||||
if (uri_dark && uri_dark[0])
|
||||
g_settings_set_string (settings, WP_URI_DARK_KEY, uri_dark);
|
||||
else
|
||||
g_settings_set_string (settings, WP_URI_DARK_KEY, uri);
|
||||
}
|
||||
|
||||
/* Also set the placement if we have a URI and the previous value was none */
|
||||
if (flags & CC_BACKGROUND_ITEM_HAS_PLACEMENT)
|
||||
{
|
||||
@@ -327,12 +198,13 @@ set_background (CcBackgroundPanel *panel,
|
||||
cc_background_xml_save (panel->current_background, filename);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_chooser_background_chosen_cb (CcBackgroundPanel *self,
|
||||
CcBackgroundItem *item)
|
||||
on_chooser_background_chosen_cb (CcBackgroundPanel *self,
|
||||
CcBackgroundItem *item)
|
||||
{
|
||||
set_background (self, self->settings, item, TRUE);
|
||||
set_background (self, self->lock_settings, item, FALSE);
|
||||
set_background (self, self->settings, item);
|
||||
set_background (self, self->lock_settings, item);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -347,6 +219,20 @@ cc_background_panel_get_help_uri (CcPanel *panel)
|
||||
return "help:gnome-help/look-background";
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_constructed (GObject *object)
|
||||
{
|
||||
CcBackgroundPanel *self;
|
||||
CcShell *shell;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_panel_dispose (GObject *object)
|
||||
{
|
||||
@@ -354,9 +240,7 @@ cc_background_panel_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&panel->settings);
|
||||
g_clear_object (&panel->lock_settings);
|
||||
g_clear_object (&panel->interface_settings);
|
||||
g_clear_object (&panel->thumb_factory);
|
||||
g_clear_object (&panel->proxy);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -383,18 +267,16 @@ cc_background_panel_class_init (CcBackgroundPanelClass *klass)
|
||||
|
||||
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, default_preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, dark_preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, default_toggle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, dark_toggle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, desktop_preview);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_color_scheme_toggle_active_cb);
|
||||
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);
|
||||
}
|
||||
@@ -423,33 +305,10 @@ cc_background_panel_init (CcBackgroundPanel *panel)
|
||||
panel->lock_settings = g_settings_new (WP_LOCK_PATH_ID);
|
||||
g_settings_delay (panel->lock_settings);
|
||||
|
||||
panel->interface_settings = g_settings_new (INTERFACE_PATH_ID);
|
||||
|
||||
/* Load the background */
|
||||
reload_current_bg (panel);
|
||||
update_preview (panel);
|
||||
|
||||
/* Background settings */
|
||||
g_signal_connect_object (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel, G_CONNECT_SWAPPED);
|
||||
|
||||
/* Interface settings */
|
||||
reload_color_scheme_toggles (panel);
|
||||
|
||||
g_signal_connect_object (panel->interface_settings,
|
||||
"changed::" INTERFACE_COLOR_SCHEME_KEY,
|
||||
G_CALLBACK (reload_color_scheme_toggles),
|
||||
panel,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
"org.gnome.Shell",
|
||||
"/org/gnome/Shell",
|
||||
"org.gnome.Shell",
|
||||
NULL,
|
||||
got_transition_proxy_cb,
|
||||
panel);
|
||||
|
||||
load_custom_css (panel);
|
||||
}
|
||||
|
||||
@@ -1,134 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcBackgroundPanel" parent="CcPanel">
|
||||
<child type="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<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="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Style</property>
|
||||
|
||||
<object class="HdyClamp">
|
||||
<property name="visible">1</property>
|
||||
<property name="maximum_size">300</property>
|
||||
<property name="tightening_threshold">200</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesRow">
|
||||
<property name="activatable">False</property>
|
||||
<property name="focusable">False</property>
|
||||
<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="AdwClamp">
|
||||
<property name="maximum_size">400</property>
|
||||
<property name="tightening_threshold">300</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="column-homogeneous">True</property>
|
||||
<property name="column-spacing">24</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="default_toggle">
|
||||
<accessibility>
|
||||
<relation name="labelled-by">default_label</relation>
|
||||
</accessibility>
|
||||
<signal name="notify::active" handler="on_color_scheme_toggle_active_cb" swapped="true"/>
|
||||
<child>
|
||||
<object class="CcBackgroundPreview" id="default_preview"/>
|
||||
</child>
|
||||
<style>
|
||||
<class name="background-preview-button"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="default_label">
|
||||
<property name="label" translatable="yes">Default</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="dark_toggle">
|
||||
<property name="group">default_toggle</property>
|
||||
<accessibility>
|
||||
<relation name="labelled-by">dark_label</relation>
|
||||
</accessibility>
|
||||
<signal name="notify::active" handler="on_color_scheme_toggle_active_cb" swapped="true"/>
|
||||
<child>
|
||||
<object class="CcBackgroundPreview" id="dark_preview">
|
||||
<property name="is-dark">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="background-preview-button"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="dark_label">
|
||||
<property name="label" translatable="yes">Dark</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</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="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Background</property>
|
||||
<property name="header-suffix">
|
||||
<object class="GtkButton">
|
||||
<child>
|
||||
<object class="AdwButtonContent">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<property name="label" translatable="yes">Add Picture…</property>
|
||||
</object>
|
||||
</child>
|
||||
<signal name="clicked" handler="on_add_picture_button_clicked_cb" object="CcBackgroundPanel" swapped="yes" />
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
|
||||
<child>
|
||||
<object class="AdwBin">
|
||||
<style>
|
||||
<class name="card"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="CcBackgroundChooser" id="background_chooser">
|
||||
<property name="hexpand">True</property>
|
||||
<signal name="background-chosen" handler="on_chooser_background_chosen_cb" object="CcBackgroundPanel" swapped="yes" />
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</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>
|
||||
|
||||
@@ -24,105 +24,180 @@
|
||||
|
||||
struct _CcBackgroundPreview
|
||||
{
|
||||
GtkWidget parent;
|
||||
GtkBox parent;
|
||||
|
||||
GtkWidget *drawing_area;
|
||||
GtkWidget *light_dark_window;
|
||||
GtkWidget *dark_window;
|
||||
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;
|
||||
|
||||
gboolean is_dark;
|
||||
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_WIDGET)
|
||||
G_DEFINE_TYPE (CcBackgroundPreview, cc_background_preview, GTK_TYPE_BOX)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_IS_DARK,
|
||||
PROP_IS_LOCK_SCREEN,
|
||||
PROP_ITEM,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
/* Callbacks */
|
||||
/* Auxiliary methods */
|
||||
|
||||
static void
|
||||
draw_preview_func (GtkDrawingArea *drawing_area,
|
||||
cairo_t *cr,
|
||||
gint width,
|
||||
gint height,
|
||||
gpointer user_data)
|
||||
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)
|
||||
{
|
||||
CcBackgroundPreview *self = CC_BACKGROUND_PREVIEW (user_data);
|
||||
g_autoptr(GdkPixbuf) pixbuf = NULL;
|
||||
GtkAllocation allocation;
|
||||
gint scale_factor;
|
||||
|
||||
if (!self->item)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (drawing_area));
|
||||
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,
|
||||
width,
|
||||
height,
|
||||
allocation.width,
|
||||
allocation.height,
|
||||
scale_factor,
|
||||
0,
|
||||
TRUE,
|
||||
self->is_dark &&
|
||||
cc_background_item_has_dark_version (self->item));
|
||||
TRUE);
|
||||
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* GObject overrides */
|
||||
|
||||
static void
|
||||
cc_background_preview_dispose (GObject *object)
|
||||
{
|
||||
CcBackgroundPreview *self = (CcBackgroundPreview *)object;
|
||||
|
||||
g_clear_pointer (&self->drawing_area, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->light_dark_window, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->dark_window, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_preview_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
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
|
||||
set_is_dark (CcBackgroundPreview *self,
|
||||
gboolean is_dark)
|
||||
{
|
||||
self->is_dark = is_dark;
|
||||
|
||||
if (self->is_dark)
|
||||
{
|
||||
gtk_widget_add_css_class (self->light_dark_window, "dark");
|
||||
gtk_widget_remove_css_class (self->light_dark_window, "light");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_add_css_class (self->light_dark_window, "light");
|
||||
gtk_widget_remove_css_class (self->light_dark_window, "dark");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -133,8 +208,8 @@ cc_background_preview_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_IS_DARK:
|
||||
g_value_set_boolean (value, self->is_dark);
|
||||
case PROP_IS_LOCK_SCREEN:
|
||||
g_value_set_boolean (value, self->is_lock_screen);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
@@ -156,8 +231,10 @@ cc_background_preview_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_IS_DARK:
|
||||
set_is_dark (self, g_value_get_boolean (value));
|
||||
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:
|
||||
@@ -175,108 +252,47 @@ cc_background_preview_get_request_mode (GtkWidget *widget)
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
get_primary_monitor_geometry (int *width, int *height)
|
||||
static gfloat
|
||||
get_primary_monitor_aspect_ratio (void)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GListModel *monitors;
|
||||
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;
|
||||
|
||||
monitors = gdk_display_get_monitors (display);
|
||||
if (monitors)
|
||||
if (primary_monitor)
|
||||
{
|
||||
g_autoptr(GdkMonitor) primary_monitor = NULL;
|
||||
GdkRectangle monitor_layout;
|
||||
|
||||
primary_monitor = g_list_model_get_item (monitors, 0);
|
||||
gdk_monitor_get_geometry (primary_monitor, &monitor_layout);
|
||||
if (width)
|
||||
*width = monitor_layout.width;
|
||||
if (height)
|
||||
*height = monitor_layout.height;
|
||||
|
||||
return;
|
||||
aspect_ratio = monitor_layout.width / (gfloat) monitor_layout.height;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = 1920;
|
||||
if (height)
|
||||
*height = 1080;
|
||||
return aspect_ratio;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
cc_background_preview_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int width;
|
||||
gfloat aspect_ratio = get_primary_monitor_aspect_ratio ();
|
||||
|
||||
get_primary_monitor_geometry (&width, NULL);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*natural = width;
|
||||
else if (for_size < 0)
|
||||
*natural = 0;
|
||||
else
|
||||
*natural = floor ((double) for_size * 0.75); /* 4:3 aspect ratio */
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
*minimum = *natural;
|
||||
else
|
||||
*minimum = 0;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min, child_nat;
|
||||
|
||||
gtk_widget_measure (child, orientation, for_size,
|
||||
&child_min, &child_nat, NULL, NULL);
|
||||
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
}
|
||||
*minimum = *natural = MAX (2, width / aspect_ratio);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_background_preview_size_allocate (GtkWidget *widget,
|
||||
gint width,
|
||||
gint height,
|
||||
gint baseline)
|
||||
cc_background_preview_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
CcBackgroundPreview *self = CC_BACKGROUND_PREVIEW (widget);
|
||||
int window_width, window_height, margin_x, margin_y;
|
||||
int opposite_margin_x, opposite_margin_y;
|
||||
GskTransform *front_transform, *back_transform;
|
||||
gboolean is_rtl;
|
||||
gfloat aspect_ratio = get_primary_monitor_aspect_ratio ();
|
||||
|
||||
window_width = ceil (width * 0.5);
|
||||
window_height = ceil (height * 0.5);
|
||||
margin_x = floor (width * 0.15);
|
||||
margin_y = floor (height * 0.15);
|
||||
opposite_margin_x = width - window_width - margin_x;
|
||||
opposite_margin_y = height - window_height - margin_y;
|
||||
is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
|
||||
|
||||
front_transform =
|
||||
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (is_rtl ? opposite_margin_x : margin_x,
|
||||
opposite_margin_y));
|
||||
back_transform =
|
||||
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (is_rtl ? margin_x : opposite_margin_x,
|
||||
margin_y));
|
||||
|
||||
gtk_widget_allocate (self->drawing_area, width, height, baseline, NULL);
|
||||
gtk_widget_allocate (self->dark_window, window_width, window_height,
|
||||
baseline, back_transform);
|
||||
gtk_widget_allocate (self->light_dark_window, window_width, window_height,
|
||||
baseline, front_transform);
|
||||
*minimum = *natural = MAX (2, height * aspect_ratio);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -285,20 +301,19 @@ cc_background_preview_class_init (CcBackgroundPreviewClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = cc_background_preview_dispose;
|
||||
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->measure = cc_background_preview_measure;
|
||||
widget_class->size_allocate = cc_background_preview_size_allocate;
|
||||
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_DARK] = g_param_spec_boolean ("is-dark",
|
||||
"Is dark",
|
||||
"Whether the preview is dark",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
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",
|
||||
@@ -310,11 +325,15 @@ cc_background_preview_class_init (CcBackgroundPreviewClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-preview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, 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, light_dark_window);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPreview, dark_window);
|
||||
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_set_css_name (widget_class, "background-preview");
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_preview_draw_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -323,6 +342,17 @@ 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*
|
||||
@@ -343,9 +373,10 @@ cc_background_preview_set_item (CcBackgroundPreview *self,
|
||||
if (!g_set_object (&self->item, item))
|
||||
return;
|
||||
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (self->drawing_area),
|
||||
draw_preview_func, self, NULL);
|
||||
gtk_widget_queue_draw (self->drawing_area);
|
||||
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]);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_BACKGROUND_PREVIEW (cc_background_preview_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcBackgroundPreview, cc_background_preview, CC, BACKGROUND_PREVIEW, GtkWidget)
|
||||
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,
|
||||
|
||||
@@ -1,55 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcBackgroundPreview" parent="GtkWidget">
|
||||
<property name="overflow">hidden</property>
|
||||
<property name="width-request">2</property>
|
||||
<property name="height-request">2</property>
|
||||
<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>
|
||||
|
||||
<!-- Wallpaper -->
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="drawing_area"/>
|
||||
</child>
|
||||
<object class="GtkOverlay">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
|
||||
<!-- Always dark window -->
|
||||
<child>
|
||||
<object class="AdwBin" id="dark_window">
|
||||
<property name="overflow">hidden</property>
|
||||
<style>
|
||||
<class name="window"/>
|
||||
<class name="back"/>
|
||||
<class name="dark"/>
|
||||
</style>
|
||||
<!-- Wallpaper -->
|
||||
<child>
|
||||
<object class="AdwBin">
|
||||
<style>
|
||||
<class name="header-bar"/>
|
||||
</style>
|
||||
<property name="valign">start</property>
|
||||
<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>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Light/dark window -->
|
||||
<child>
|
||||
<object class="AdwBin" id="light_dark_window">
|
||||
<property name="overflow">hidden</property>
|
||||
<style>
|
||||
<class name="window"/>
|
||||
<class name="front"/>
|
||||
<class name="light"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="AdwBin">
|
||||
<style>
|
||||
<class name="header-bar"/>
|
||||
</style>
|
||||
<property name="valign">start</property>
|
||||
<!-- 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>
|
||||
|
||||
@@ -210,27 +210,6 @@ cc_background_xml_load_xml_internal (CcBackgroundXml *xml,
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp ((gchar *)wpa->name, "filename-dark")) {
|
||||
if (wpa->last != NULL && wpa->last->content != NULL) {
|
||||
gchar *content = g_strstrip ((gchar *)wpa->last->content);
|
||||
g_autofree gchar *bg_uri = NULL;
|
||||
|
||||
/* FIXME same rubbish as in other parts of the code */
|
||||
if (strcmp (content, NONE) == 0) {
|
||||
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);
|
||||
bg_uri = g_file_get_uri (file);
|
||||
}
|
||||
SET_FLAG(CC_BACKGROUND_ITEM_HAS_URI_DARK);
|
||||
g_object_set (G_OBJECT (item), "uri-dark", bg_uri, NULL);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp ((gchar *)wpa->name, "name")) {
|
||||
if (wpa->last != NULL && wpa->last->content != NULL) {
|
||||
g_autofree gchar *name = NULL;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
[Desktop Entry]
|
||||
Name=Appearance
|
||||
Comment=Change your background image or the UI colors
|
||||
Name=Background
|
||||
Comment=Change your background image to a wallpaper or photo
|
||||
Exec=gnome-control-center background
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=org.gnome.Settings-appearance-symbolic
|
||||
Icon=preferences-desktop-wallpaper
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-PersonalizationSettings;
|
||||
OnlyShowIn=GNOME;
|
||||
# Translators: Search terms to find the Appearance panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=Background;Wallpaper;Screen;Desktop;Style;Light;Dark;Appearance;
|
||||
# Translators: Search terms to find the Background panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=Wallpaper;Screen;Desktop;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-appearance-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#2e3436">
|
||||
<path d="m 3.011719 1 c -1.644531 0 -3.0000002 1.355469 -3.0000002 3 v 6 c 0 1.644531 1.3554692 3 3.0000002 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -6 c 0 -0.570312 -0.167969 -1.101562 -0.449219 -1.558594 l -1.550781 1.554688 v 6.003906 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570313 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429687 -1 1 -1 h 5.96875 l 2.007812 -2 z m 0 0"/>
|
||||
<path d="m 11.011719 7 c 0 1.65625 -1.339844 3.007812 -3 3 h -3 v -3 c 0 -1.660156 1.34375 -3 3 -3 c 1.660156 0 3 1.339844 3 3 z m 0 0"/>
|
||||
<path d="m 13.410156 0 l -3.46875 3.457031 c 0.683594 0.355469 1.234375 0.910157 1.589844 1.589844 l 0.171875 -0.171875 l 0.007813 0.007812 l 4.300781 -4.300781 v -0.582031 z m 0 0"/>
|
||||
<path d="m 5.011719 14 c -1.105469 0 -2 0.894531 -2 2 h 10 c 0 -1.105469 -0.894531 -2 -2 -2 z m 0 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 999 B |
@@ -16,6 +16,16 @@ i18n.merge_file(
|
||||
install_dir: control_center_desktopdir
|
||||
)
|
||||
|
||||
install_data(
|
||||
'slideshow-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'categories')
|
||||
)
|
||||
|
||||
install_data(
|
||||
'slideshow-emblem.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'emblems')
|
||||
)
|
||||
|
||||
install_data(
|
||||
'noise-texture-light.png',
|
||||
install_dir: join_paths(control_center_pkgdatadir, 'pixmaps')
|
||||
@@ -65,12 +75,13 @@ common_sources += gnome.compile_resources(
|
||||
|
||||
sources = common_sources + files(
|
||||
'bg-colors-source.c',
|
||||
'bg-pictures-source.c',
|
||||
'bg-recent-source.c',
|
||||
'bg-source.c',
|
||||
'bg-wallpapers-source.c',
|
||||
'cc-background-chooser.c',
|
||||
'cc-background-grilo-miner.c',
|
||||
'cc-background-item.c',
|
||||
'cc-background-paintable.c',
|
||||
'cc-background-panel.c',
|
||||
'cc-background-preview.c',
|
||||
'cc-background-xml.c',
|
||||
@@ -78,9 +89,11 @@ sources = common_sources + files(
|
||||
|
||||
deps = common_deps + [
|
||||
gdk_pixbuf_dep,
|
||||
gnome_bg_dep,
|
||||
gnome_desktop_dep,
|
||||
goa_dep,
|
||||
libxml_dep,
|
||||
dependency('cairo-gobject'),
|
||||
dependency('grilo-0.3', version: '>= 0.3.0')
|
||||
]
|
||||
|
||||
cflags += [
|
||||
@@ -88,6 +101,10 @@ cflags += [
|
||||
'-DGNOME_DESKTOP_USE_UNSTABLE_API'
|
||||
]
|
||||
|
||||
if gnome_desktop_dep.version().version_compare('>=3.35.4')
|
||||
cflags += '-DGNOME_DESKTOP_BG_API_BREAK'
|
||||
endif
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
sources: sources,
|
||||
@@ -95,5 +112,3 @@ panels_libs += static_library(
|
||||
dependencies: deps,
|
||||
c_args: cflags,
|
||||
)
|
||||
|
||||
subdir('icons')
|
||||
|
||||
@@ -1,96 +1,40 @@
|
||||
background-preview {
|
||||
border-radius: 6px;
|
||||
frame.desktop-preview {
|
||||
min-height: 10px;
|
||||
padding: 0 4px;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
background-preview .window {
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 4px 1px alpha(black, 0.13),
|
||||
0 1px 10px 5px alpha(black, 0.09),
|
||||
0 3px 16px 8px alpha(black, 0.04),
|
||||
0 0 0 1px alpha(black, .05);
|
||||
}
|
||||
|
||||
background-preview .window .header-bar {
|
||||
min-height: 15px;
|
||||
}
|
||||
|
||||
background-preview .window.light {
|
||||
background-color: #fafafa;
|
||||
color: alpha(black, .8);
|
||||
}
|
||||
|
||||
background-preview .window.light .header-bar {
|
||||
box-shadow: inset 0 -1px alpha(black, .07);
|
||||
}
|
||||
|
||||
background-preview .window.front.light .header-bar {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
|
||||
background-preview .window.dark {
|
||||
background-color: #242424;
|
||||
frame.desktop-preview image {
|
||||
color: white;
|
||||
}
|
||||
|
||||
background-preview .window.dark .header-bar {
|
||||
box-shadow: inset 0 -1px alpha(black, .36);
|
||||
frame.desktop-preview label {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 6px;
|
||||
}
|
||||
|
||||
background-preview .window.front.dark .header-bar {
|
||||
background-color: #303030;
|
||||
frame.lock-screen-preview {
|
||||
border: solid rgba(0, 0, 0, 0.33);
|
||||
border-width: 10px 0 0 0;
|
||||
}
|
||||
|
||||
.background-preview-button {
|
||||
background: none;
|
||||
border-radius: 9px;
|
||||
padding: 3px;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
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;
|
||||
}
|
||||
|
||||
.background-preview-button:checked {
|
||||
box-shadow: 0 0 0 3px @accent_color;
|
||||
}
|
||||
|
||||
.background-preview-button:focus:focus-visible {
|
||||
box-shadow: 0 0 0 3px alpha(@accent_color, .3);
|
||||
}
|
||||
|
||||
.background-preview-button:checked:focus:focus-visible {
|
||||
box-shadow: 0 0 0 3px @accent_color, 0 0 0 6px alpha(@accent_color, .3);
|
||||
}
|
||||
|
||||
.background-flowbox > flowboxchild {
|
||||
background: none;
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
.background-thumbnail {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.slideshow-icon {
|
||||
image.slideshow-icon {
|
||||
color: white;
|
||||
-gtk-icon-shadow: 0 1px 2px rgba(0, 0, 0, 0.33);
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.selected-check {
|
||||
color: @accent_fg_color;
|
||||
background: @accent_bg_color;
|
||||
border-radius: 100px;
|
||||
padding: 2px;
|
||||
opacity: 0;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
flowboxchild:selected .selected-check {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.remove-button {
|
||||
padding: 2px;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
margin: 6px;
|
||||
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;
|
||||
}
|
||||
|
||||
104
panels/background/slideshow-emblem.svg
Normal file
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
height="128"
|
||||
id="svg4978"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="slideshow-emblem.svg">
|
||||
<defs
|
||||
id="defs4980" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="41.944792"
|
||||
inkscape:cy="39.155574"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="962"
|
||||
inkscape:window-height="817"
|
||||
inkscape:window-x="4"
|
||||
inkscape:window-y="51"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata4983">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36215)">
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g14317"
|
||||
transform="matrix(7.1989829,0,0,7.1989829,-772.01578,-783.40043)">
|
||||
<g
|
||||
style="stroke:#000000;stroke-opacity:1"
|
||||
transform="translate(69,-449)"
|
||||
id="g14258"
|
||||
inkscape:label="document-open-recent">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:2.15384626;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path14260"
|
||||
sodipodi:cx="48"
|
||||
sodipodi:cy="696"
|
||||
sodipodi:rx="7"
|
||||
sodipodi:ry="7"
|
||||
d="m 55,696 c 0,3.86599 -3.134007,7 -7,7 -3.865993,0 -7,-3.13401 -7,-7 0,-3.86599 3.134007,-7 7,-7 3.865993,0 7,3.13401 7,7 z"
|
||||
transform="matrix(0.92857143,0,0,0.92857143,2.9285714,49.21429)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 45.5,693.5 2,2 3,-3"
|
||||
id="path14262"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="document-open-recent"
|
||||
id="g4692"
|
||||
transform="translate(69,-450)">
|
||||
<path
|
||||
transform="matrix(0.92857143,0,0,0.92857143,2.9285714,49.21429)"
|
||||
d="m 55,696 c 0,3.86599 -3.134007,7 -7,7 -3.865993,0 -7,-3.13401 -7,-7 0,-3.86599 3.134007,-7 7,-7 3.865993,0 7,3.13401 7,7 z"
|
||||
sodipodi:ry="7"
|
||||
sodipodi:rx="7"
|
||||
sodipodi:cy="696"
|
||||
sodipodi:cx="48"
|
||||
id="path3869"
|
||||
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.15384626;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4639"
|
||||
d="m 45.5,693.5 2,2 3,-3"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -1 +1,70 @@
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.486.02A7.492 7.492 0 0 0 0 7.508a7.492 7.492 0 0 0 7.486 7.484 7.492 7.492 0 0 0 7.487-7.484A7.492 7.492 0 0 0 7.486.02zm0 1.972A5.508 5.508 0 0 1 13 7.508a5.508 5.508 0 0 1-5.514 5.512 5.508 5.508 0 0 1-5.513-5.512 5.508 5.508 0 0 1 5.513-5.516zm3.01 2.01a.5.5 0 0 0-.103.006.5.5 0 0 0-.25.154L7.486 6.818 5.83 5.162a.5.5 0 1 0-.687.688l2 2a.5.5 0 0 0 .687 0l3-3a.5.5 0 0 0-.334-.848z" style="fill:#000"/></svg>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
id="svg5594"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="slideshow-emblem-symbolic.svg">
|
||||
<defs
|
||||
id="defs5596" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.4"
|
||||
inkscape:cx="10.858512"
|
||||
inkscape:cy="10.780448"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="789"
|
||||
inkscape:window-height="774"
|
||||
inkscape:window-x="4"
|
||||
inkscape:window-y="51"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata5599">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<g
|
||||
id="g3763"
|
||||
transform="matrix(0.86221939,0,0,0.86221939,1.0303599,144.13347)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path14584"
|
||||
d="m 7.9642862,1038.3322 c -3.3085937,0 -5.9942603,2.6857 -5.9942603,5.9943 0,3.3086 2.6856666,5.9942 5.9942603,5.9942 3.3085938,0 5.9942608,-2.6856 5.9942608,-5.9942 0,-3.3086 -2.685667,-5.9943 -5.9942608,-5.9943 z m 0,0.8457 c 2.8454368,0 5.1485968,2.3031 5.1485968,5.1486 0,2.8454 -2.30316,5.1486 -5.1485968,5.1486 -2.8454368,0 -5.148597,-2.3032 -5.148597,-5.1486 0,-2.8455 2.3031602,-5.1486 5.148597,-5.1486 z"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1.0767436;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path14586"
|
||||
d="m 10.5,1041.3125 a 0.42854288,0.42854288 0 0 0 -0.28125,0.125 l -2.25,2.2813 -1.40625,-1.4063 a 0.4310176,0.4310176 0 1 0 -0.625,0.5937 l 1.71875,1.7188 a 0.42854288,0.42854288 0 0 0 0.625,0 l 2.5625,-2.5625 a 0.42854288,0.42854288 0 0 0 -0.34375,-0.75 z"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#999999;fill-opacity:1;stroke:none;stroke-width:0.85700005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 3.6 KiB |
@@ -1,226 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2021 Red Hat Inc.
|
||||
#
|
||||
# Author: Bastien Nocera <hadess@hadess.net>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import dbus
|
||||
import sys
|
||||
import os
|
||||
import fcntl
|
||||
import gi
|
||||
import subprocess
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from dbusmock import DBusTestCase, mockobject
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from consolemenu import *
|
||||
from consolemenu.items import *
|
||||
|
||||
from gi.repository import Gio
|
||||
from gi.repository import GLib
|
||||
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
|
||||
def set_nonblock(fd):
|
||||
'''Set a file object to non-blocking'''
|
||||
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
|
||||
|
||||
def get_templates_dir():
|
||||
return os.path.join(os.path.dirname(__file__), 'dbusmock-templates')
|
||||
|
||||
def get_template_path(template_name):
|
||||
return os.path.join(get_templates_dir(), template_name + '.py')
|
||||
|
||||
class GccDBusTestCase(DBusTestCase):
|
||||
@classmethod
|
||||
def setUpClass(klass):
|
||||
klass.mocks = OrderedDict()
|
||||
|
||||
# Start system bus
|
||||
DBusTestCase.setUpClass()
|
||||
klass.test_bus = Gio.TestDBus.new(Gio.TestDBusFlags.NONE)
|
||||
klass.test_bus.up()
|
||||
os.environ['DBUS_SYSTEM_BUS_ADDRESS'] = klass.test_bus.get_bus_address()
|
||||
|
||||
# Start session bus
|
||||
klass.session_test_bus = Gio.TestDBus.new(Gio.TestDBusFlags.NONE)
|
||||
klass.session_test_bus.up()
|
||||
os.environ['DBUS_SESSION_BUS_ADDRESS'] = klass.session_test_bus.get_bus_address()
|
||||
|
||||
# process = subprocess.Popen(['gdbus', 'monitor', '--session', '--dest', 'org.gnome.SettingsDaemon.Rfkill'])
|
||||
# process = subprocess.Popen(['gdbus', 'monitor', '--system', '--dest', 'org.bluez'])
|
||||
|
||||
# Start bluez and gsd-rfkill
|
||||
klass.start_from_template('bluez5')
|
||||
klass.start_from_local_template(
|
||||
'gsd_rfkill', {'templates-dir': get_templates_dir()})
|
||||
|
||||
klass.system_bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(klass):
|
||||
for (mock_server, mock_obj) in reversed(klass.mocks.values()):
|
||||
mock_server.terminate()
|
||||
mock_server.wait()
|
||||
|
||||
DBusTestCase.tearDownClass()
|
||||
|
||||
@classmethod
|
||||
def start_from_template(klass, template, params={}):
|
||||
mock_server, mock_obj = \
|
||||
klass.spawn_server_template(template,
|
||||
params,
|
||||
stdout=subprocess.PIPE)
|
||||
set_nonblock(mock_server.stdout)
|
||||
|
||||
mocks = (mock_server, mock_obj)
|
||||
assert klass.mocks.setdefault(template, mocks) == mocks
|
||||
return mocks
|
||||
|
||||
@classmethod
|
||||
def start_from_local_template(klass, template_file_name, params={}):
|
||||
template = get_template_path(template_file_name)
|
||||
ret = klass.start_from_template(template, params)
|
||||
klass.mocks.setdefault(template_file_name, ret)
|
||||
return ret
|
||||
|
||||
def __init__(self):
|
||||
self.devices = {}
|
||||
self.rfkill = self.mocks['gsd_rfkill'][1]
|
||||
|
||||
self.bluez_mock = self.mocks['bluez5'][1]
|
||||
self.hci0_powered = True
|
||||
self.hci0_plugged_in = True
|
||||
self.add_adapter()
|
||||
bus = dbus.SystemBus()
|
||||
self.hci0_props = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/hci0'), 'org.freedesktop.DBus.Properties')
|
||||
|
||||
def adapter_exists(self):
|
||||
try:
|
||||
self.get_dbus(True).get_object('org.bluez', '/org/bluez/hci0').Get('org.bluez.Adapter1', 'Name')
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
def add_adapter(self):
|
||||
if self.adapter_exists():
|
||||
return
|
||||
self.bluez_mock.AddAdapter('hci0', 'hci0')
|
||||
adapter = self.get_dbus(True).get_object('org.bluez', '/org/bluez/hci0')
|
||||
adapter.AddProperties('org.bluez.Adapter1',
|
||||
{'Blocked': dbus.Boolean(not self.hci0_powered, variant_level=1)})
|
||||
adapter.UpdateProperties('org.bluez.Adapter1',
|
||||
{'Powered': dbus.Boolean(self.hci0_powered, variant_level=1)})
|
||||
self.devices = []
|
||||
self.add_device('hci0', '22:33:44:55:66:77', "Bastienʼs mouse", True, 0x580, 'input-mouse')
|
||||
self.add_device('hci0', '22:33:44:55:66:78', 'Bloutouf keyboard & keys', True, 0x540, 'input-keyboard')
|
||||
self.add_device('hci0', '60:8B:0E:55:66:79', 'iPhoone 19S', True, 0x20C, 'phone')
|
||||
# Uncategorised audio device
|
||||
self.add_device('hci0', '22:33:44:55:66:79', 'MEGA Speakers', True, 0x200400, 'audio-card')
|
||||
self.add_device('hci0', '22:33:44:55:66:80', 'Ski-bi dibby dib yo da dub dub Yo da dub dub Ski-bi dibby dib yo da dub dub Yo da dub dub (I\'m the Scatman) Ski-bi dibby dib yo da dub dub Yo da dub dub Ski-bi dibby dib yo da dub dub Yo da dub dub Ba-da-ba-da-ba-be bop bop bodda bope Bop ba bodda bope Be bop ba bodda bope Bop ba bodda Ba-da-ba-da-ba-be bop ba bodda bope Bop ba bodda bope Be bop ba bodda bope Bop ba bodda bope', True, 0x80C, '')
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'BluetoothHasAirplaneMode', dbus.Boolean(True))
|
||||
|
||||
def remove_adapter(self):
|
||||
if not self.adapter_exists():
|
||||
return
|
||||
for dev in self.devices:
|
||||
adapter = self.get_dbus(True).get_object('org.bluez', '/org/bluez/hci0')
|
||||
adapter.RemoveDevice(dev)
|
||||
self.devices = []
|
||||
self.bluez_mock.RemoveAdapter('hci0')
|
||||
if self.rfkill.Get('org.gnome.SettingsDaemon.Rfkill', 'BluetoothHardwareAirplaneMode') == 0:
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'BluetoothHasAirplaneMode', dbus.Boolean(False))
|
||||
|
||||
def add_device(self, adapter, address, name, paired, klass, icon):
|
||||
dev_path = self.bluez_mock.AddDevice(adapter, address, name)
|
||||
dev = self.get_dbus(True).get_object('org.bluez', str(dev_path))
|
||||
dev.UpdateProperties('org.bluez.Device1',
|
||||
{'Paired': dbus.Boolean(paired, variant_level=1),
|
||||
'Class': dbus.UInt32(klass, variant_level=1),
|
||||
'Icon': dbus.String(icon, variant_level=1)})
|
||||
self.devices.append(dev)
|
||||
|
||||
def get_rfkill_prop(self, prop_name):
|
||||
return self.rfkill.Get('org.gnome.SettingsDaemon.Rfkill', prop_name)
|
||||
|
||||
def toggle_hw_rfkill(self):
|
||||
if self.rfkill.Get('org.gnome.SettingsDaemon.Rfkill', 'BluetoothHardwareAirplaneMode') == 0:
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'BluetoothHardwareAirplaneMode', dbus.Boolean(True))
|
||||
if self.adapter_exists():
|
||||
self.remove_adapter()
|
||||
else:
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'BluetoothHardwareAirplaneMode', dbus.Boolean(False))
|
||||
if not self.adapter_exists():
|
||||
self.add_adapter()
|
||||
|
||||
def set_unpowered(self):
|
||||
if self.hci0_powered:
|
||||
print('hci0 will now default to unpowered')
|
||||
self.hci0_powered = False
|
||||
else:
|
||||
print('hci0 will now default to powered')
|
||||
self.hci0_powered = True
|
||||
|
||||
def unplug_default_adapter(self):
|
||||
if self.hci0_plugged_in:
|
||||
print('default adapter is unplugged')
|
||||
self.hci0_plugged_in = False
|
||||
self.remove_adapter()
|
||||
else:
|
||||
print('default adapter is plugged in')
|
||||
self.hci0_plugged_in = True
|
||||
self.add_adapter()
|
||||
|
||||
def toggle_airplane_mode(self):
|
||||
if self.rfkill.Get('org.gnome.SettingsDaemon.Rfkill', 'AirplaneMode') == 0:
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'AirplaneMode', dbus.Boolean(True))
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'BluetoothAirplaneMode', dbus.Boolean(True))
|
||||
else:
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'AirplaneMode', dbus.Boolean(False))
|
||||
self.rfkill.Set('org.gnome.SettingsDaemon.Rfkill', 'BluetoothAirplaneMode', dbus.Boolean(False))
|
||||
|
||||
def start_menu(self):
|
||||
menu = ConsoleMenu("Bluetooth Panel", "Scenario Tester", clear_screen = False)
|
||||
function_item = FunctionItem("Toggle Bluetooth hardware rfkill", self.toggle_hw_rfkill)
|
||||
menu.append_item(function_item)
|
||||
|
||||
function_item = FunctionItem("Toggle default adapter unpowered", self.set_unpowered)
|
||||
menu.append_item(function_item)
|
||||
|
||||
function_item = FunctionItem("Unplug/plug default adapter", self.unplug_default_adapter)
|
||||
menu.append_item(function_item)
|
||||
|
||||
function_item = FunctionItem("Toggle airplane mode", self.toggle_airplane_mode)
|
||||
menu.append_item(function_item)
|
||||
|
||||
menu.start(show_exit_option=False)
|
||||
|
||||
def wrap_call(self):
|
||||
os.environ['GSETTINGS_BACKEND'] = 'memory'
|
||||
|
||||
wrapper = os.environ.get('META_DBUS_RUNNER_WRAPPER')
|
||||
args = ['gnome-control-center', '-v', 'bluetooth']
|
||||
if wrapper == 'gdb':
|
||||
args = ['gdb', '-ex', 'r', '-ex', 'bt full', '--args'] + args
|
||||
elif wrapper:
|
||||
args = wrapper.split(' ') + args
|
||||
|
||||
p = subprocess.Popen(args, env=os.environ)
|
||||
p.wait()
|
||||
|
||||
if __name__ == '__main__':
|
||||
#if 'umockdev' not in os.environ.get('LD_PRELOAD', ''):
|
||||
# os.execvp('umockdev-wrapper', ['umockdev-wrapper'] + sys.argv)
|
||||
|
||||
GccDBusTestCase.setUpClass()
|
||||
test_case = GccDBusTestCase()
|
||||
test_case.start_menu()
|
||||
try:
|
||||
test_case.wrap_call()
|
||||
finally:
|
||||
GccDBusTestCase.tearDownClass()
|
||||
@@ -22,8 +22,6 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <adwaita.h>
|
||||
|
||||
#include <shell/cc-shell.h>
|
||||
#include <shell/cc-object-storage.h>
|
||||
#include <bluetooth-settings-widget.h>
|
||||
@@ -34,12 +32,12 @@
|
||||
struct _CcBluetoothPanel {
|
||||
CcPanel parent_instance;
|
||||
|
||||
AdwStatusPage *airplane_page;
|
||||
AdwStatusPage *disabled_page;
|
||||
GtkBox *airplane_box;
|
||||
GtkBox *disabled_box;
|
||||
GtkSwitch *enable_switch;
|
||||
GtkBox *header_box;
|
||||
AdwStatusPage *hw_airplane_page;
|
||||
AdwStatusPage *no_devices_page;
|
||||
GtkBox *hw_airplane_box;
|
||||
GtkBox *no_devices_box;
|
||||
BluetoothSettingsWidget *settings_widget;
|
||||
GtkStack *stack;
|
||||
|
||||
@@ -74,33 +72,23 @@ cc_bluetooth_panel_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
airplane_mode_changed_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
cc_bluetooth_panel_constructed (GObject *object)
|
||||
{
|
||||
g_autoptr(GVariant) ret = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean state = GPOINTER_TO_UINT (user_data);
|
||||
CcBluetoothPanel *self = CC_BLUETOOTH_PANEL (object);
|
||||
|
||||
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 {
|
||||
CcBluetoothPanel *self = user_data;
|
||||
G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->constructed (object);
|
||||
|
||||
g_debug ("Changed Bluetooth killswitch state to %s",
|
||||
state ? "on" : "off");
|
||||
|
||||
if (!bluetooth_settings_widget_get_default_adapter_powered (self->settings_widget))
|
||||
bluetooth_settings_widget_set_default_adapter_powered(self->settings_widget, TRUE);
|
||||
}
|
||||
/* add kill switch widgets */
|
||||
cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (self)),
|
||||
GTK_WIDGET (self->header_box), GTK_POS_RIGHT);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_switch_state_set_cb (CcBluetoothPanel *self, gboolean state)
|
||||
enable_switch_changed_cb (CcBluetoothPanel *self)
|
||||
{
|
||||
gboolean state;
|
||||
|
||||
state = gtk_switch_get_active (self->enable_switch);
|
||||
g_debug ("Power switched to %s", state ? "on" : "off");
|
||||
g_dbus_proxy_call (self->properties,
|
||||
"Set",
|
||||
@@ -109,42 +97,43 @@ enable_switch_state_set_cb (CcBluetoothPanel *self, gboolean state)
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
airplane_mode_changed_cb, self);
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
adapter_status_changed_cb (CcBluetoothPanel *self)
|
||||
{
|
||||
GtkAlign valign;
|
||||
gboolean sensitive, powered;
|
||||
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) {
|
||||
g_debug ("No Bluetooth available");
|
||||
sensitive = FALSE;
|
||||
powered = FALSE;
|
||||
page = GTK_WIDGET (self->no_devices_page);
|
||||
page = GTK_WIDGET (self->no_devices_box);
|
||||
} else if (self->hardware_airplane_mode) {
|
||||
g_debug ("Bluetooth is Hard blocked");
|
||||
sensitive = FALSE;
|
||||
powered = FALSE;
|
||||
page = GTK_WIDGET (self->hw_airplane_page);
|
||||
page = GTK_WIDGET (self->hw_airplane_box);
|
||||
} else if (self->airplane_mode) {
|
||||
g_debug ("Airplane mode is on, Wi-Fi and Bluetooth are disabled");
|
||||
sensitive = FALSE;
|
||||
powered = FALSE;
|
||||
page = GTK_WIDGET (self->airplane_page);
|
||||
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;
|
||||
page = GTK_WIDGET (self->disabled_page);
|
||||
change_powered = FALSE;
|
||||
page = GTK_WIDGET (self->disabled_box);
|
||||
} else {
|
||||
g_debug ("Bluetooth is available and powered");
|
||||
sensitive = TRUE;
|
||||
@@ -155,9 +144,12 @@ 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);
|
||||
|
||||
if (change_powered) {
|
||||
g_signal_handlers_block_by_func (self->enable_switch, enable_switch_changed_cb, self);
|
||||
gtk_switch_set_active (self->enable_switch, powered);
|
||||
g_signal_handlers_unblock_by_func (self->enable_switch, enable_switch_changed_cb, self);
|
||||
}
|
||||
|
||||
gtk_stack_set_visible_child (self->stack, page);
|
||||
}
|
||||
@@ -177,7 +169,6 @@ airplane_mode_changed (CcBluetoothPanel *self)
|
||||
self->bt_airplane_mode = g_variant_get_boolean (bluetooth_airplane_mode);
|
||||
|
||||
bluetooth_hardware_airplane_mode = g_dbus_proxy_get_cached_property (self->rfkill, "BluetoothHardwareAirplaneMode");
|
||||
g_message ("BluetoothHardwareAirplaneMode: %d", self->hardware_airplane_mode);
|
||||
self->hardware_airplane_mode = g_variant_get_boolean (bluetooth_hardware_airplane_mode);
|
||||
|
||||
bluetooth_has_airplane_mode = g_dbus_proxy_get_cached_property (self->rfkill, "BluetoothHasAirplaneMode");
|
||||
@@ -220,24 +211,25 @@ cc_bluetooth_panel_class_init (CcBluetoothPanelClass *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_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, disabled_page);
|
||||
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_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBluetoothPanel, hw_airplane_page);
|
||||
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, enable_switch_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, panel_changed_cb);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,64 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<template class="CcBluetoothPanel" parent="CcPanel">
|
||||
|
||||
<child type="titlebar-end">
|
||||
<object class="GtkBox" id="header_box">
|
||||
<child>
|
||||
<object class="GtkSwitch" id="enable_switch">
|
||||
<property name="valign">center</property>
|
||||
<accessibility>
|
||||
<property name="label" translatable="yes">Enable</property>
|
||||
</accessibility>
|
||||
<signal name="state-set" handler="enable_switch_state_set_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="content">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="no_devices_page">
|
||||
<property name="icon-name">bluetooth-active-symbolic</property>
|
||||
<property name="title" translatable="yes">No Bluetooth Found</property>
|
||||
<property name="description" translatable="yes">Plug in a dongle to use Bluetooth.</property>
|
||||
<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="AdwStatusPage" id="disabled_page">
|
||||
<property name="icon-name">bluetooth-active-symbolic</property>
|
||||
<property name="title" translatable="yes">Bluetooth Turned Off</property>
|
||||
<property name="description" translatable="yes">Turn on to connect devices and receive file transfers.</property>
|
||||
<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="AdwStatusPage" id="airplane_page">
|
||||
<property name="icon-name">airplane-mode-symbolic</property>
|
||||
<property name="title" translatable="yes">Airplane Mode is On</property>
|
||||
<property name="description" translatable="yes">Bluetooth is disabled when airplane mode is on.</property>
|
||||
<property name="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"/>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="hw_airplane_page">
|
||||
<property name="icon-name">airplane-mode-symbolic</property>
|
||||
<property name="title" translatable="yes">Hardware Airplane Mode is On</property>
|
||||
<property name="description" translatable="yes">Turn off the Airplane mode switch to enable Bluetooth.</property>
|
||||
<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>
|
||||
@@ -66,4 +177,24 @@
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="GtkBox" id="header_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="enable_switch">
|
||||
<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="notify::active" handler="enable_switch_changed_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">4</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
'''gsd-rfkill mock template
|
||||
|
||||
This creates the expected methods and properties of the main
|
||||
org.gnome.SettingsDaemon.Rfkill object.
|
||||
'''
|
||||
|
||||
# This program 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 3 of the License, or (at your option) any
|
||||
# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
|
||||
# of the license.
|
||||
|
||||
__author__ = 'Bastien Nocera'
|
||||
__copyright__ = '(c) 2022, Red Hat Inc.'
|
||||
|
||||
import dbus
|
||||
import os
|
||||
from dbusmock import mockobject
|
||||
|
||||
BUS_NAME = 'org.gnome.SettingsDaemon.Rfkill'
|
||||
MAIN_OBJ = '/org/gnome/SettingsDaemon/Rfkill'
|
||||
MAIN_IFACE = 'org.gnome.SettingsDaemon.Rfkill'
|
||||
SYSTEM_BUS = False
|
||||
|
||||
ADAPTER_IFACE = 'org.bluez.Adapter1'
|
||||
|
||||
def rfkill_changed(*args, **kwargs):
|
||||
[iface, changed, _invalidated] = args
|
||||
|
||||
rfkill = mockobject.objects[MAIN_OBJ]
|
||||
adapter = dbus.bus.BusConnection(os.environ['DBUS_SYSTEM_BUS_ADDRESS']).get_object('org.bluez', '/org/bluez/hci0')
|
||||
try:
|
||||
adapter.Get(ADAPTER_IFACE, 'Name')
|
||||
except:
|
||||
adapter = None
|
||||
|
||||
if 'BluetoothAirplaneMode' in changed:
|
||||
if adapter and rfkill.props[MAIN_IFACE]['BluetoothAirplaneMode'] == 1:
|
||||
adapter.UpdateProperties(ADAPTER_IFACE,
|
||||
{'Powered': dbus.Boolean(False),
|
||||
'Blocked': dbus.Boolean(True)})
|
||||
elif adapter:
|
||||
adapter.UpdateProperties(ADAPTER_IFACE,
|
||||
{'Blocked': dbus.Boolean(False)})
|
||||
if 'BluetoothHardwareAirplaneMode' in changed:
|
||||
if rfkill.props[MAIN_IFACE]['BluetoothAirplaneMode'] == 0:
|
||||
rfkill.Set(MAIN_IFACE, 'BluetoothAirplaneMode', dbus.Boolean(False))
|
||||
|
||||
def load(mock, parameters):
|
||||
# Loaded!
|
||||
mock.loaded = True
|
||||
|
||||
props = {
|
||||
'AirplaneMode': parameters.get('AirplaneMode', dbus.Boolean(False)),
|
||||
'HardwareAirplaneMode': parameters.get('HardwareAirplaneMode', dbus.Boolean(False)),
|
||||
'HasAirplaneMode': parameters.get('HasAirplaneMode', dbus.Boolean(True)),
|
||||
# True if not desktop, server, vm or container
|
||||
'ShouldShowAirplaneMode': parameters.get('ShouldShowAirplaneMode', dbus.Boolean(True)),
|
||||
'BluetoothAirplaneMode': parameters.get('BluetoothAirplaneMode', dbus.Boolean(False)),
|
||||
'BluetoothHardwareAirplaneMode': parameters.get('BluetoothAirplaneMode', dbus.Boolean(False)),
|
||||
'BluetoothHasAirplaneMode': parameters.get('BluetoothHasAirplaneMode', dbus.Boolean(True)),
|
||||
'WwanAirplaneMode': parameters.get('WwanAirplaneMode', dbus.Boolean(False)),
|
||||
'WwanHardwareAirplaneMode': parameters.get('WwanHardwareAirplaneMode', dbus.Boolean(False)),
|
||||
'WwanHasAirplaneMode': parameters.get('WwanHasAirplaneMode', dbus.Boolean(False)),
|
||||
}
|
||||
mock.AddProperties(MAIN_IFACE, dbus.Dictionary(props, signature='sv'))
|
||||
|
||||
rfkill = mockobject.objects[MAIN_OBJ]
|
||||
rfkill.hci0_power = True
|
||||
|
||||
session_bus = dbus.SessionBus()
|
||||
session_bus.add_signal_receiver(rfkill_changed,
|
||||
signal_name='PropertiesChanged',
|
||||
path=MAIN_OBJ,
|
||||
dbus_interface='org.freedesktop.DBus.Properties')
|
||||
@@ -2,7 +2,7 @@
|
||||
Name=Bluetooth
|
||||
Comment=Turn Bluetooth on and off and connect your devices
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=org.gnome.Settings-bluetooth-symbolic
|
||||
Icon=bluetooth
|
||||
Exec=gnome-control-center bluetooth
|
||||
Terminal=false
|
||||
Type=Application
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-bluetooth-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 7.585938 0.0898438 c -0.355469 0.1640622 -0.585938 0.5195312 -0.585938 0.9101562 v 5.296875 l -2.34375 -2.046875 c -0.414062 -0.363281 -1.042969 -0.324219 -1.40625 0.089844 c -0.363281 0.417968 -0.324219 1.046875 0.09375 1.410156 l 2.566406 2.25 l -2.566406 2.25 c -0.417969 0.363281 -0.457031 0.992188 -0.09375 1.40625 c 0.363281 0.417969 0.992188 0.457031 1.40625 0.09375 l 2.34375 -2.046875 v 5.296875 c 0 0.390625 0.230469 0.746094 0.585938 0.910156 c 0.359374 0.160156 0.777343 0.101563 1.070312 -0.160156 l 4 -3.5 c 0.21875 -0.1875 0.34375 -0.460938 0.34375 -0.75 s -0.125 -0.5625 -0.34375 -0.75 l -3.140625 -2.75 l 3.140625 -2.75 c 0.21875 -0.1875 0.34375 -0.460938 0.34375 -0.75 s -0.125 -0.5625 -0.34375 -0.75 l -4 -3.5 c -0.292969 -0.2617188 -0.710938 -0.3242188 -1.070312 -0.1601562 z m 1.414062 3.1132812 l 1.484375 1.296875 l -1.484375 1.296875 z m 0 7 l 1.484375 1.296875 l -1.484375 1.296875 z m 0 0" fill="#2e3436"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -37,5 +37,3 @@ panels_libs += static_library(
|
||||
dependencies: deps,
|
||||
c_args: cflags
|
||||
)
|
||||
|
||||
subdir('icons')
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
* 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 <adwaita.h>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
@@ -35,7 +35,6 @@ struct _CcCameraPanel
|
||||
|
||||
GtkStack *stack;
|
||||
GtkListBox *camera_apps_list_box;
|
||||
GtkSwitch *main_switch;
|
||||
|
||||
GSettings *privacy_settings;
|
||||
|
||||
@@ -159,7 +158,7 @@ add_camera_app (CcCameraPanel *self,
|
||||
g_autofree gchar *desktop_id = NULL;
|
||||
CameraAppStateData *data;
|
||||
GDesktopAppInfo *app_info;
|
||||
GtkWidget *row, *w;
|
||||
GtkWidget *box, *row, *w;
|
||||
GIcon *icon;
|
||||
|
||||
w = g_hash_table_lookup (self->camera_app_switches, app_id);
|
||||
@@ -174,22 +173,41 @@ add_camera_app (CcCameraPanel *self,
|
||||
if (!app_info)
|
||||
return;
|
||||
|
||||
row = adw_action_row_new ();
|
||||
gtk_list_box_append (self->camera_apps_list_box, row);
|
||||
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);
|
||||
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);
|
||||
adw_action_row_add_prefix (ADW_ACTION_ROW (row), w);
|
||||
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
|
||||
|
||||
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row),
|
||||
g_app_info_get_name (G_APP_INFO (app_info)));
|
||||
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);
|
||||
adw_action_row_add_suffix (ADW_ACTION_ROW (row), w);
|
||||
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
|
||||
g_settings_bind (self->privacy_settings,
|
||||
"disable-camera",
|
||||
w,
|
||||
@@ -359,6 +377,37 @@ 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)
|
||||
{
|
||||
@@ -369,12 +418,12 @@ cc_camera_panel_class_init (CcCameraPanelClass *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);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, main_switch);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -384,20 +433,14 @@ cc_camera_panel_init (CcCameraPanel *self)
|
||||
|
||||
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");
|
||||
|
||||
g_settings_bind (self->privacy_settings, "disable-camera",
|
||||
self->main_switch, "active",
|
||||
G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||||
|
||||
g_object_bind_property_full (self->main_switch, "active",
|
||||
self->stack, "visible-child-name",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
to_child_name,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
|
||||
self->camera_app_switches = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
|
||||
@@ -1,57 +1,107 @@
|
||||
<?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">
|
||||
|
||||
<child type="titlebar-end">
|
||||
<object class="GtkSwitch" id="main_switch">
|
||||
<accessibility>
|
||||
<property name="label" translatable="yes">Enable</property>
|
||||
</accessibility>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="content">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
|
||||
<!-- Empty page -->
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<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>
|
||||
<property name="title" translatable="yes">Camera is Turned Off</property>
|
||||
<property name="description" translatable="yes">No applications can capture photos or video.</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
<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>
|
||||
|
||||
<!-- Cameras -->
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">content</property>
|
||||
<property name="child">
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="description" translatable="yes">Use of the camera allows applications to capture photos and video. Disabling the camera may cause some applications to not function properly.
|
||||
<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>
|
||||
|
||||
Allow the applications below to use your camera.</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="boxed-list"/>
|
||||
<class name="view"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
|
||||
<child type="placeholder">
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<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>
|
||||
@@ -64,11 +114,14 @@ Allow the applications below to use your camera.</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">content</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -4,7 +4,7 @@ Comment=Protect your pictures
|
||||
Exec=gnome-control-center camera
|
||||
# FIXME
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=org.gnome.Settings-camera-symbolic
|
||||
Icon=camera-photo
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
@@ -15,5 +15,5 @@ X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=privacy
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
# Translators: Search terms to find the Camera panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=camera;photos;video;webcam;lock;private;privacy;
|
||||
# Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=screen;lock;diagnostics;crash;private;recent;temporary;tmp;index;name;network;identity;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-camera-symbolic.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 6.414062 0 c -0.265624 0 -0.519531 0.105469 -0.707031 0.292969 l -1.707031 1.707031 h -1.085938 c -1.644531 0 -2.9999995 1.355469 -2.9999995 3 v 7 c 0 1.644531 1.3554685 3 2.9999995 3 h 10 c 1.644532 0 3 -1.355469 3 -3 v -7 c 0 -1.644531 -1.355468 -3 -3 -3 h -1.085937 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707032 -0.292969 z m 0.414063 2 h 2.171875 l 1.707031 1.707031 c 0.1875 0.1875 0.441407 0.292969 0.707031 0.292969 h 1.5 c 0.570313 0 1 0.429688 1 1 v 7 c 0 0.570312 -0.429687 1 -1 1 h -10 c -0.570312 0 -1 -0.429688 -1 -1 v -7 c 0 -0.570312 0.429688 -1 1 -1 h 1.5 c 0.265626 0 0.519532 -0.105469 0.707032 -0.292969 z m 1.085937 3 c -1.644531 0 -3 1.355469 -3 3 s 1.585938 3 3 3 c 1.414063 0 3 -1.355469 3 -3 s -1.355468 -3 -3 -3 z m 0 2 c 0.5625 0 1 0.4375 1 1 s -0.4375 1 -1 1 s -1 -0.4375 -1 -1 s 0.4375 -1 1 -1 z m 0 0" fill="#2e3434"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1021 B |
@@ -37,5 +37,3 @@ panels_libs += static_library(
|
||||
dependencies: common_deps,
|
||||
c_args: cflags
|
||||
)
|
||||
|
||||
subdir('icons')
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <colord-session/cd-session.h>
|
||||
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <gnome-rr/gnome-rr.h>
|
||||
#include <libgnome-desktop/gnome-rr.h>
|
||||
|
||||
#include "cc-color-calibrate.h"
|
||||
|
||||
@@ -170,7 +170,7 @@ cc_color_calibrate_calib_setup_screen (CcColorCalibrate *calibrate,
|
||||
gboolean ret = TRUE;
|
||||
|
||||
/* get screen */
|
||||
calibrate->x11_screen = gnome_rr_screen_new (gdk_display_get_default (), error);
|
||||
calibrate->x11_screen = gnome_rr_screen_new (gdk_screen_get_default (), error);
|
||||
if (calibrate->x11_screen == NULL)
|
||||
{
|
||||
ret = FALSE;
|
||||
@@ -603,6 +603,94 @@ cc_color_calibrate_cancel (CcColorCalibrate *calibrate)
|
||||
g_main_loop_quit (calibrate->loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_move_and_resize_window (GtkWindow *window,
|
||||
CdDevice *device,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *xrandr_name;
|
||||
gboolean ret = TRUE;
|
||||
GdkRectangle rect;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
gint i;
|
||||
gint monitor_num = -1;
|
||||
gint num_monitors;
|
||||
|
||||
/* find the monitor num of the device output */
|
||||
display = gdk_display_get_default ();
|
||||
num_monitors = gdk_display_get_n_monitors (display);
|
||||
xrandr_name = cd_device_get_metadata_item (device, CD_DEVICE_METADATA_XRANDR_NAME);
|
||||
for (i = 0; i < num_monitors; i++)
|
||||
{
|
||||
const gchar *plug_name;
|
||||
|
||||
monitor = gdk_display_get_monitor (display, i);
|
||||
plug_name = gdk_monitor_get_model (monitor);
|
||||
|
||||
if (g_strcmp0 (plug_name, xrandr_name) == 0)
|
||||
monitor_num = i;
|
||||
}
|
||||
if (monitor_num == -1)
|
||||
{
|
||||
ret = FALSE;
|
||||
g_set_error (error,
|
||||
CD_SESSION_ERROR,
|
||||
CD_SESSION_ERROR_INTERNAL,
|
||||
"failed to find output %s",
|
||||
xrandr_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* move the window, and set it to the right size */
|
||||
monitor = gdk_display_get_monitor (display, monitor_num);
|
||||
gdk_monitor_get_geometry (monitor, &rect);
|
||||
gtk_window_move (window, rect.x, rect.y);
|
||||
gtk_window_resize (window, rect.width, rect.height);
|
||||
g_debug ("Setting window to %ix%i with size %ix%i",
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_window_realize_cb (CcColorCalibrate *self)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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"));
|
||||
|
||||
/* check event */
|
||||
if (event->type != GDK_WINDOW_STATE)
|
||||
return TRUE;
|
||||
if (event_state->changed_mask != GDK_WINDOW_STATE_FULLSCREEN)
|
||||
return TRUE;
|
||||
|
||||
/* resize to the correct screen */
|
||||
ret = cc_color_calibrate_move_and_resize_window (window,
|
||||
calibrate->device,
|
||||
&error);
|
||||
if (!ret)
|
||||
g_warning ("Failed to resize window: %s", error->message);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_button_done_cb (CcColorCalibrate *calibrate)
|
||||
{
|
||||
@@ -642,7 +730,6 @@ cc_color_calibrate_button_cancel_cb (CcColorCalibrate *calibrate)
|
||||
cc_color_calibrate_cancel (calibrate);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static gboolean
|
||||
cc_color_calibrate_alpha_window_draw (CcColorCalibrate *calibrate, cairo_t *cr)
|
||||
{
|
||||
@@ -682,7 +769,6 @@ cc_color_calibrate_alpha_screen_changed_cb (CcColorCalibrate *calibrate)
|
||||
visual = gdk_screen_get_system_visual (screen);
|
||||
gtk_widget_set_visual (GTK_WIDGET (window), visual);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cc_color_calibrate_uninhibit (CcColorCalibrate *calibrate)
|
||||
@@ -899,12 +985,20 @@ cc_color_calibrate_start (CcColorCalibrate *calibrate,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_delete_event_cb (CcColorCalibrate *calibrate)
|
||||
{
|
||||
/* do not destroy the window */
|
||||
cc_color_calibrate_cancel (calibrate);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_finalize (GObject *object)
|
||||
{
|
||||
CcColorCalibrate *calibrate = CC_COLOR_CALIBRATE (object);
|
||||
|
||||
g_clear_pointer (&calibrate->window, gtk_window_destroy);
|
||||
g_clear_pointer ((GtkWidget **)&calibrate->window, gtk_widget_destroy);
|
||||
g_clear_object (&calibrate->builder);
|
||||
g_clear_object (&calibrate->device);
|
||||
g_clear_object (&calibrate->proxy_helper);
|
||||
@@ -950,7 +1044,8 @@ cc_color_calibrate_init (CcColorCalibrate *calibrate)
|
||||
"vbox_status"));
|
||||
calibrate->sample_widget = cd_sample_widget_new ();
|
||||
gtk_widget_set_size_request (calibrate->sample_widget, 400, 400);
|
||||
gtk_box_prepend (box, calibrate->sample_widget);
|
||||
gtk_box_pack_start (box, calibrate->sample_widget, FALSE, FALSE, 0);
|
||||
gtk_box_reorder_child (box, calibrate->sample_widget, 0);
|
||||
gtk_widget_set_vexpand (calibrate->sample_widget, FALSE);
|
||||
gtk_widget_set_hexpand (calibrate->sample_widget, FALSE);
|
||||
|
||||
@@ -981,6 +1076,19 @@ cc_color_calibrate_init (CcColorCalibrate *calibrate)
|
||||
/* 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);
|
||||
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);
|
||||
calibrate->window = window;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,65 +2,114 @@
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkDialog" id="dialog_calibrate">
|
||||
<property name="margin_top">32</property>
|
||||
<property name="margin_bottom">32</property>
|
||||
<property name="margin_start">12</property>
|
||||
<property name="margin_end">12</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="title" translatable="yes">Display Calibration</property>
|
||||
<property name="hide_titlebar_when_maximized">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="deletable">False</property>
|
||||
<style>
|
||||
<class name="osd"/>
|
||||
</style>
|
||||
<child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog-vbox4">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkBox" id="dialog-action_area1">
|
||||
<object class="GtkButtonBox" id="dialog-action_area1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_cancel">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
<property name="secondary">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_start">
|
||||
<property name="label" translatable="yes" comments="This starts the calibration process">_Start</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_resume">
|
||||
<property name="label" translatable="yes" comments="This resumes the calibration process">_Resume</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_done">
|
||||
<property name="label" translatable="yes" comments="This button returns the user back to the color control panel">_Done</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox_status">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">15</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image_status">
|
||||
<property name="valign">end</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="yalign">1</property>
|
||||
<property name="pixel_size">192</property>
|
||||
<property name="icon_name">address-book-new</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label_status">
|
||||
<property name="valign">start</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label">Do not disturb the calibration device while in progress</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
@@ -69,12 +118,30 @@
|
||||
<attribute name="foreground" value="#ffffffffffff"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="progressbar_status">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">25</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -77,12 +77,12 @@ cc_color_cell_renderer_text_set_property (GObject *object, guint param_id,
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_cell_renderer_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
cc_color_cell_renderer_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
CcColorCellRendererText *renderer;
|
||||
GtkStyleContext *context;
|
||||
@@ -94,9 +94,9 @@ cc_color_cell_renderer_snapshot (GtkCellRenderer *cell,
|
||||
gtk_style_context_add_class (context, "dim-label");
|
||||
else
|
||||
gtk_style_context_remove_class (context, "dim-label");
|
||||
GTK_CELL_RENDERER_CLASS (parent_class)->snapshot (cell, snapshot, widget,
|
||||
background_area,
|
||||
cell_area, flags);
|
||||
GTK_CELL_RENDERER_CLASS (parent_class)->render (cell, cr, widget,
|
||||
background_area,
|
||||
cell_area, flags);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ cc_color_cell_renderer_text_class_init (CcColorCellRendererTextClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkCellRendererClass *object_class_gcr = GTK_CELL_RENDERER_CLASS (class);
|
||||
object_class_gcr->snapshot = cc_color_cell_renderer_snapshot;
|
||||
object_class_gcr->render = cc_color_cell_renderer_render;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ cc_color_device_refresh (CcColorDevice *color_device)
|
||||
{
|
||||
g_autofree gchar *title = NULL;
|
||||
g_autoptr(GPtrArray) profiles = NULL;
|
||||
AtkObject *accessible;
|
||||
g_autofree gchar *name1 = NULL;
|
||||
g_autofree gchar *name2 = NULL;
|
||||
|
||||
@@ -78,21 +79,20 @@ cc_color_device_refresh (CcColorDevice *color_device)
|
||||
gtk_widget_set_visible (color_device->widget_switch, profiles->len > 0);
|
||||
gtk_widget_set_visible (color_device->widget_button, profiles->len > 0);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (color_device->widget_arrow),
|
||||
color_device->expanded ? "pan-down-symbolic" : "pan-end-symbolic");
|
||||
color_device->expanded ? "pan-down-symbolic" : "pan-end-symbolic",
|
||||
GTK_ICON_SIZE_BUTTON);
|
||||
gtk_widget_set_visible (color_device->widget_nocalib, profiles->len == 0);
|
||||
gtk_widget_set_sensitive (color_device->widget_button, cd_device_get_enabled (color_device->device));
|
||||
gtk_switch_set_active (GTK_SWITCH (color_device->widget_switch),
|
||||
cd_device_get_enabled (color_device->device));
|
||||
|
||||
accessible = gtk_widget_get_accessible (color_device->widget_switch);
|
||||
name1 = g_strdup_printf (_("Enable color management for %s"), title);
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (color_device->widget_switch),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL, name1,
|
||||
-1);
|
||||
atk_object_set_name (accessible, name1);
|
||||
|
||||
name2 = g_strdup_printf (_("Show color profiles for %s"), title);
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (color_device->widget_button),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL, name2,
|
||||
-1);
|
||||
accessible = gtk_widget_get_accessible (color_device->widget_button);
|
||||
atk_object_set_name (accessible, name2);
|
||||
}
|
||||
|
||||
CdDevice *
|
||||
@@ -263,40 +263,41 @@ cc_color_device_init (CcColorDevice *color_device)
|
||||
gtk_widget_set_margin_top (color_device->widget_description, 12);
|
||||
gtk_widget_set_margin_bottom (color_device->widget_description, 12);
|
||||
gtk_widget_set_halign (color_device->widget_description, GTK_ALIGN_START);
|
||||
gtk_widget_set_hexpand (color_device->widget_description, TRUE);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (color_device->widget_description), PANGO_ELLIPSIZE_END);
|
||||
gtk_label_set_xalign (GTK_LABEL (color_device->widget_description), 0);
|
||||
gtk_box_append (GTK_BOX (box), color_device->widget_description);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_device->widget_description, TRUE, TRUE, 0);
|
||||
|
||||
/* switch */
|
||||
color_device->widget_switch = gtk_switch_new ();
|
||||
gtk_widget_set_valign (color_device->widget_switch, GTK_ALIGN_CENTER);
|
||||
gtk_box_append (GTK_BOX (box), color_device->widget_switch);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_device->widget_switch, FALSE, FALSE, 0);
|
||||
|
||||
/* arrow button */
|
||||
color_device->widget_arrow = gtk_image_new_from_icon_name ("pan-end-symbolic");
|
||||
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);
|
||||
gtk_widget_set_valign (color_device->widget_button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_add_css_class (color_device->widget_button, "flat");
|
||||
gtk_button_set_child (GTK_BUTTON (color_device->widget_button), color_device->widget_arrow);
|
||||
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);
|
||||
gtk_widget_set_visible (color_device->widget_arrow, TRUE);
|
||||
gtk_widget_set_margin_top (color_device->widget_button, 9);
|
||||
gtk_widget_set_margin_bottom (color_device->widget_button, 9);
|
||||
gtk_widget_set_margin_end (color_device->widget_button, 12);
|
||||
gtk_box_append (GTK_BOX (box), color_device->widget_button);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_device->widget_button, FALSE, FALSE, 0);
|
||||
|
||||
/* not calibrated */
|
||||
color_device->widget_nocalib = gtk_label_new (_("Not calibrated"));
|
||||
context = gtk_widget_get_style_context (color_device->widget_nocalib);
|
||||
gtk_style_context_add_class (context, "dim-label");
|
||||
gtk_widget_set_margin_end (color_device->widget_nocalib, 18);
|
||||
gtk_box_append (GTK_BOX (box), color_device->widget_nocalib);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_device->widget_nocalib, FALSE, FALSE, 0);
|
||||
|
||||
/* refresh */
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (color_device), box);
|
||||
gtk_container_add (GTK_CONTAINER (color_device), box);
|
||||
gtk_widget_set_visible (box, TRUE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <colord.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/x11/gdkx.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <libsoup/soup.h>
|
||||
|
||||
#include "list-box-helper.h"
|
||||
#include "cc-color-calibrate.h"
|
||||
#include "cc-color-cell-renderer-text.h"
|
||||
#include "cc-color-panel.h"
|
||||
@@ -53,17 +55,22 @@ struct _CcColorPanel
|
||||
GtkWidget *box_calib_temp;
|
||||
GtkWidget *box_calib_title;
|
||||
GtkWidget *box_devices;
|
||||
GtkWidget *button_assign_cancel;
|
||||
GtkWidget *button_assign_import;
|
||||
GtkWidget *button_assign_ok;
|
||||
GtkWidget *button_calib_export;
|
||||
GtkWidget *button_calib_upload;
|
||||
GtkWidget *dialog_assign;
|
||||
GtkWidget *entry_calib_title;
|
||||
GtkWidget *frame_devices;
|
||||
GtkWidget *label_assign_warning;
|
||||
GtkWidget *label_calib_summary_message;
|
||||
GtkWidget *label_calib_upload_location;
|
||||
GtkWidget *label_no_devices;
|
||||
GtkTreeModel *liststore_assign;
|
||||
GtkTreeModel *liststore_calib_kind;
|
||||
GtkTreeModel *liststore_calib_sensor;
|
||||
GtkWidget *main_window;
|
||||
GtkWidget *toolbar_devices;
|
||||
GtkWidget *toolbutton_device_calibrate;
|
||||
GtkWidget *toolbutton_device_default;
|
||||
@@ -215,62 +222,9 @@ gcm_prefs_default_cb (CcColorPanel *prefs)
|
||||
error->message);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkResponseType response;
|
||||
GMainLoop *mainloop;
|
||||
} DialogRunData;
|
||||
|
||||
static void
|
||||
dialog_response_cb (GtkDialog *dialog,
|
||||
GtkResponseType response,
|
||||
DialogRunData *run_data)
|
||||
{
|
||||
run_data->response = response;
|
||||
g_main_loop_quit (run_data->mainloop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dialog_close_cb (GtkDialog *dialog,
|
||||
GtkResponseType response,
|
||||
DialogRunData *run_data)
|
||||
{
|
||||
g_main_loop_quit (run_data->mainloop);
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static GtkResponseType
|
||||
run_dialog (GtkDialog *dialog)
|
||||
{
|
||||
g_autoptr(GMainLoop) mainloop = NULL;
|
||||
DialogRunData run_data;
|
||||
guint response_id;
|
||||
guint close_id;
|
||||
|
||||
mainloop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
run_data = (DialogRunData) {
|
||||
.response = GTK_RESPONSE_DELETE_EVENT,
|
||||
.mainloop = mainloop,
|
||||
};
|
||||
|
||||
response_id = g_signal_connect (dialog, "response", G_CALLBACK (dialog_response_cb), &run_data);
|
||||
close_id = g_signal_connect (dialog, "close-request", G_CALLBACK (dialog_close_cb), &run_data);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
|
||||
g_main_loop_run (mainloop);
|
||||
|
||||
g_signal_handler_disconnect (dialog, response_id);
|
||||
g_signal_handler_disconnect (dialog, close_id);
|
||||
|
||||
return run_data.response;
|
||||
}
|
||||
|
||||
static GFile *
|
||||
gcm_prefs_file_chooser_get_icc_profile (CcColorPanel *prefs)
|
||||
{
|
||||
g_autoptr(GFile) current_folder = NULL;
|
||||
GtkWindow *window;
|
||||
GtkWidget *dialog;
|
||||
GFile *file = NULL;
|
||||
@@ -284,9 +238,9 @@ gcm_prefs_file_chooser_get_icc_profile (CcColorPanel *prefs)
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_Import"), GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
current_folder = g_file_new_for_path (g_get_home_dir ());
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog), current_folder, NULL);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog), g_get_home_dir ());
|
||||
gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER(dialog), FALSE);
|
||||
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(dialog), FALSE);
|
||||
|
||||
/* setup the filter */
|
||||
filter = gtk_file_filter_new ();
|
||||
@@ -304,11 +258,11 @@ gcm_prefs_file_chooser_get_icc_profile (CcColorPanel *prefs)
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
|
||||
|
||||
/* did user choose file */
|
||||
if (run_dialog (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER(dialog));
|
||||
|
||||
/* we're done */
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
/* or NULL for missing */
|
||||
return file;
|
||||
@@ -357,6 +311,7 @@ gcm_prefs_calib_apply_cb (CcColorPanel *prefs)
|
||||
GtkWindow *window = NULL;
|
||||
|
||||
/* setup the calibration object with items that can fail */
|
||||
gtk_widget_show (prefs->button_calib_upload);
|
||||
ret = cc_color_calibrate_setup (prefs->calibrate,
|
||||
&error);
|
||||
if (!ret)
|
||||
@@ -383,6 +338,14 @@ gcm_prefs_calib_apply_cb (CcColorPanel *prefs)
|
||||
gtk_widget_hide (GTK_WIDGET (window));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcm_prefs_calib_delete_event_cb (CcColorPanel *prefs)
|
||||
{
|
||||
/* do not destroy the window */
|
||||
gcm_prefs_calib_cancel_cb (prefs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_temp_treeview_clicked_cb (CcColorPanel *prefs,
|
||||
GtkTreeSelection *selection)
|
||||
@@ -584,7 +547,7 @@ gcm_prefs_calibrate_display (CcColorPanel *prefs)
|
||||
tmp = cd_device_get_vendor (prefs->current_device);
|
||||
if (tmp == NULL)
|
||||
tmp = _("Screen");
|
||||
gtk_editable_set_text (GTK_EDITABLE (prefs->entry_calib_title), tmp);
|
||||
gtk_entry_set_text (GTK_ENTRY (prefs->entry_calib_title), tmp);
|
||||
cc_color_calibrate_set_title (prefs->calibrate, tmp);
|
||||
|
||||
/* set the display whitepoint to D65 by default */
|
||||
@@ -592,7 +555,7 @@ gcm_prefs_calibrate_display (CcColorPanel *prefs)
|
||||
|
||||
/* show ui */
|
||||
gtk_window_set_transient_for (GTK_WINDOW (prefs->assistant_calib),
|
||||
GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (prefs))));
|
||||
GTK_WINDOW (prefs->main_window));
|
||||
gtk_widget_show (prefs->assistant_calib);
|
||||
}
|
||||
|
||||
@@ -603,7 +566,7 @@ gcm_prefs_title_entry_changed_cb (CcColorPanel *prefs)
|
||||
const gchar *value;
|
||||
|
||||
assistant = GTK_ASSISTANT (prefs->assistant_calib);
|
||||
value = gtk_editable_get_text (GTK_EDITABLE (prefs->entry_calib_title));
|
||||
value = gtk_entry_get_text (GTK_ENTRY (prefs->entry_calib_title));
|
||||
cc_color_calibrate_set_title (prefs->calibrate, value);
|
||||
gtk_assistant_set_page_complete (assistant, prefs->box_calib_title, value[0] != '\0');
|
||||
}
|
||||
@@ -611,11 +574,9 @@ gcm_prefs_title_entry_changed_cb (CcColorPanel *prefs)
|
||||
static void
|
||||
gcm_prefs_calibrate_cb (CcColorPanel *prefs)
|
||||
{
|
||||
GtkNative *native;
|
||||
GdkSurface *surface;
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
guint xid = 0;
|
||||
guint xid;
|
||||
g_autoptr(GPtrArray) argv = NULL;
|
||||
|
||||
/* use the new-style calibration helper */
|
||||
@@ -626,11 +587,7 @@ gcm_prefs_calibrate_cb (CcColorPanel *prefs)
|
||||
}
|
||||
|
||||
/* get xid */
|
||||
native = gtk_widget_get_native (GTK_WIDGET (prefs));
|
||||
surface = gtk_native_get_surface (native);
|
||||
|
||||
if (GDK_IS_X11_SURFACE (surface))
|
||||
xid = gdk_x11_surface_get_xid (GDK_X11_SURFACE (surface));
|
||||
xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (prefs->main_window)));
|
||||
|
||||
/* run with modal set */
|
||||
argv = g_ptr_array_new_with_free_func (g_free);
|
||||
@@ -818,6 +775,91 @@ gcm_prefs_add_profiles_suitable_for_devices (CcColorPanel *prefs,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_upload_cb (CcColorPanel *prefs)
|
||||
{
|
||||
CdProfile *profile;
|
||||
const gchar *uri;
|
||||
gboolean ret;
|
||||
g_autofree gchar *upload_uri = NULL;
|
||||
g_autofree gchar *msg_result = NULL;
|
||||
g_autofree gchar *data = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gsize length;
|
||||
guint status_code;
|
||||
g_autoptr(SoupBuffer) buffer = NULL;
|
||||
g_autoptr(SoupMessage) msg = NULL;
|
||||
g_autoptr(SoupMultipart) multipart = NULL;
|
||||
g_autoptr(SoupSession) session = NULL;
|
||||
|
||||
profile = cc_color_calibrate_get_profile (prefs->calibrate);
|
||||
ret = cd_profile_connect_sync (profile, NULL, &error);
|
||||
if (!ret)
|
||||
{
|
||||
g_warning ("Failed to get imported profile: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* read file */
|
||||
ret = g_file_get_contents (cd_profile_get_filename (profile),
|
||||
&data,
|
||||
&length,
|
||||
&error);
|
||||
if (!ret)
|
||||
{
|
||||
g_warning ("Failed to read file: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* setup the session */
|
||||
session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, "gnome-control-center",
|
||||
SOUP_SESSION_TIMEOUT, 5000,
|
||||
NULL);
|
||||
if (session == NULL)
|
||||
{
|
||||
g_warning ("Failed to setup networking");
|
||||
return;
|
||||
}
|
||||
soup_session_add_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
|
||||
|
||||
/* create multipart form and upload file */
|
||||
multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
|
||||
buffer = soup_buffer_new (SOUP_MEMORY_STATIC, data, length);
|
||||
soup_multipart_append_form_file (multipart,
|
||||
"upload",
|
||||
cd_profile_get_filename (profile),
|
||||
NULL,
|
||||
buffer);
|
||||
upload_uri = g_settings_get_string (prefs->settings_colord, "profile-upload-uri");
|
||||
msg = soup_form_request_new_from_multipart (upload_uri, multipart);
|
||||
status_code = soup_session_send_message (session, msg);
|
||||
if (status_code != 201)
|
||||
{
|
||||
/* TRANSLATORS: this is when the upload of the profile failed */
|
||||
msg_result = g_strdup_printf (_("Failed to upload file: %s"), msg->reason_phrase),
|
||||
gtk_label_set_label (GTK_LABEL (prefs->label_calib_upload_location), msg_result);
|
||||
gtk_widget_show (prefs->label_calib_upload_location);
|
||||
return;
|
||||
}
|
||||
|
||||
/* show instructions to the user */
|
||||
uri = soup_message_headers_get_one (msg->response_headers, "Location");
|
||||
msg_result = g_strdup_printf ("%s %s\n\n• %s\n• %s\n• %s",
|
||||
/* TRANSLATORS: these are instructions on how to recover
|
||||
* the ICC profile on the native operating system and are
|
||||
* only shown when the user uses a LiveCD to calibrate */
|
||||
_("The profile has been uploaded to:"),
|
||||
uri,
|
||||
_("Write down this URL."),
|
||||
_("Restart this computer and boot your normal operating system."),
|
||||
_("Type the URL into your browser to download and install the profile.")),
|
||||
gtk_label_set_label (GTK_LABEL (prefs->label_calib_upload_location), msg_result);
|
||||
gtk_widget_show (prefs->label_calib_upload_location);
|
||||
|
||||
/* hide the upload button as duplicate uploads will fail */
|
||||
gtk_widget_hide (prefs->button_calib_upload);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_export_cb (CcColorPanel *prefs)
|
||||
{
|
||||
@@ -839,16 +881,17 @@ gcm_prefs_calib_export_cb (CcColorPanel *prefs)
|
||||
|
||||
/* TRANSLATORS: this is the dialog to save the ICC profile */
|
||||
dialog = gtk_file_chooser_dialog_new (_("Save Profile"),
|
||||
GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (prefs))),
|
||||
GTK_WINDOW (prefs->main_window),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_Save"), GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
|
||||
default_name = g_strdup_printf ("%s.icc", cd_profile_get_title (profile));
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), default_name);
|
||||
|
||||
if (run_dialog (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
source = g_file_new_for_path (cd_profile_get_filename (profile));
|
||||
destination = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
@@ -863,16 +906,17 @@ gcm_prefs_calib_export_cb (CcColorPanel *prefs)
|
||||
g_warning ("Failed to copy profile: %s", error->message);
|
||||
}
|
||||
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_calib_export_link_cb (CcColorPanel *prefs,
|
||||
const gchar *url)
|
||||
{
|
||||
gtk_show_uri (GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (prefs))),
|
||||
"help:gnome-help/color-howtoimport",
|
||||
GDK_CURRENT_TIME);
|
||||
gtk_show_uri_on_window (GTK_WINDOW (prefs->main_window),
|
||||
"help:gnome-help/color-howtoimport",
|
||||
GDK_CURRENT_TIME,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -888,10 +932,8 @@ gcm_prefs_profile_add_cb (CcColorPanel *prefs)
|
||||
gtk_widget_set_sensitive (prefs->button_assign_ok, FALSE);
|
||||
|
||||
/* show the dialog */
|
||||
gtk_window_set_transient_for (GTK_WINDOW (prefs->dialog_assign),
|
||||
GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (prefs))));
|
||||
|
||||
gtk_widget_show (prefs->dialog_assign);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (prefs->dialog_assign), GTK_WINDOW (prefs->main_window));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -977,19 +1019,13 @@ gcm_prefs_device_profile_enable_cb (CcColorPanel *prefs)
|
||||
static void
|
||||
gcm_prefs_profile_view (CcColorPanel *prefs, CdProfile *profile)
|
||||
{
|
||||
GtkNative *native;
|
||||
GdkSurface *surface;
|
||||
g_autoptr(GPtrArray) argv = NULL;
|
||||
guint xid = 0;
|
||||
guint xid;
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
/* get xid */
|
||||
native = gtk_widget_get_native (GTK_WIDGET (prefs));
|
||||
surface = gtk_native_get_surface (native);
|
||||
|
||||
if (GDK_IS_X11_SURFACE (surface))
|
||||
xid = gdk_x11_surface_get_xid (GDK_X11_SURFACE (surface));
|
||||
xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (prefs->main_window)));
|
||||
|
||||
/* open up gcm-viewer as a info pane */
|
||||
argv = g_ptr_array_new_with_free_func (g_free);
|
||||
@@ -1048,6 +1084,12 @@ gcm_prefs_profile_view_cb (CcColorPanel *prefs)
|
||||
gcm_prefs_profile_view (prefs, profile);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_button_assign_cancel_cb (CcColorPanel *prefs)
|
||||
{
|
||||
gtk_widget_hide (prefs->dialog_assign);
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
{
|
||||
@@ -1109,6 +1151,13 @@ gcm_prefs_button_assign_ok_cb (CcColorPanel *prefs)
|
||||
prefs);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcm_prefs_profile_delete_event_cb (CcColorPanel *prefs)
|
||||
{
|
||||
gcm_prefs_button_assign_cancel_cb (prefs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_add_profiles_columns (CcColorPanel *prefs,
|
||||
GtkTreeView *treeview)
|
||||
@@ -1128,6 +1177,7 @@ gcm_prefs_add_profiles_columns (CcColorPanel *prefs,
|
||||
/* image */
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer = gtk_cell_renderer_pixbuf_new ();
|
||||
g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL);
|
||||
gtk_tree_view_column_pack_start (column, renderer, FALSE);
|
||||
gtk_tree_view_column_add_attribute (column, renderer,
|
||||
"icon-name", GCM_PREFS_COMBO_COLUMN_WARNING_FILENAME);
|
||||
@@ -1400,7 +1450,8 @@ gcm_prefs_add_device_profile (CcColorPanel *prefs,
|
||||
|
||||
/* add to listbox */
|
||||
widget = cc_color_profile_new (device, profile, is_default);
|
||||
gtk_list_box_append (prefs->list_box, widget);
|
||||
gtk_widget_show (widget);
|
||||
gtk_container_add (GTK_CONTAINER (prefs->list_box), widget);
|
||||
gtk_size_group_add_widget (prefs->list_box_size, widget);
|
||||
}
|
||||
|
||||
@@ -1476,47 +1527,37 @@ gcm_prefs_find_widget_by_object_path (GList *list,
|
||||
static void
|
||||
gcm_prefs_device_changed_cb (CcColorPanel *prefs, CdDevice *device)
|
||||
{
|
||||
GtkWidget *child;
|
||||
CdDevice *device_tmp;
|
||||
CdProfile *profile_tmp;
|
||||
gboolean ret;
|
||||
GList *l;
|
||||
g_autoptr(GList) list = NULL;
|
||||
GPtrArray *profiles;
|
||||
guint i;
|
||||
|
||||
/* remove anything in the list view that's not in Device.Profiles */
|
||||
profiles = cd_device_get_profiles (device);
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (prefs->list_box));
|
||||
while (child)
|
||||
list = gtk_container_get_children (GTK_CONTAINER (prefs->list_box));
|
||||
for (l = list; l != NULL; l = l->next)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
if (!CC_IS_COLOR_PROFILE (child))
|
||||
{
|
||||
list = g_list_prepend (list, child);
|
||||
goto next;
|
||||
}
|
||||
if (!CC_IS_COLOR_PROFILE (l->data))
|
||||
continue;
|
||||
|
||||
/* correct device ? */
|
||||
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (child));
|
||||
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (l->data));
|
||||
if (g_strcmp0 (cd_device_get_id (device),
|
||||
cd_device_get_id (device_tmp)) != 0)
|
||||
{
|
||||
list = g_list_prepend (list, child);
|
||||
goto next;
|
||||
}
|
||||
continue;
|
||||
|
||||
/* if profile is not in Device.Profiles then remove */
|
||||
profile_tmp = cc_color_profile_get_profile (CC_COLOR_PROFILE (child));
|
||||
profile_tmp = cc_color_profile_get_profile (CC_COLOR_PROFILE (l->data));
|
||||
ret = gcm_prefs_find_profile_by_object_path (profiles,
|
||||
cd_profile_get_object_path (profile_tmp));
|
||||
if (!ret)
|
||||
gtk_list_box_remove (prefs->list_box, child);
|
||||
else
|
||||
list = g_list_prepend (list, child);
|
||||
|
||||
next:
|
||||
child = next;
|
||||
if (!ret) {
|
||||
gtk_widget_destroy (GTK_WIDGET (l->data));
|
||||
/* Don't look at the destroyed widget below */
|
||||
l->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* add anything in Device.Profiles that's not in the list view */
|
||||
@@ -1546,20 +1587,20 @@ gcm_prefs_device_expanded_changed_cb (CcColorPanel *prefs,
|
||||
g_free (prefs->list_box_filter);
|
||||
if (is_expanded)
|
||||
{
|
||||
GtkWidget *child;
|
||||
g_autoptr(GList) list = NULL;
|
||||
GList *l;
|
||||
|
||||
prefs->list_box_filter = g_strdup (cd_device_get_id (cc_color_device_get_device (widget)));
|
||||
|
||||
/* unexpand other device widgets */
|
||||
list = gtk_container_get_children (GTK_CONTAINER (prefs->list_box));
|
||||
prefs->model_is_changing = TRUE;
|
||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (prefs->list_box));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
for (l = list; l != NULL; l = l->next)
|
||||
{
|
||||
if (!CC_IS_COLOR_DEVICE (child))
|
||||
if (!CC_IS_COLOR_DEVICE (l->data))
|
||||
continue;
|
||||
if (CC_COLOR_DEVICE (child) != widget)
|
||||
cc_color_device_set_expanded (CC_COLOR_DEVICE (child), FALSE);
|
||||
if (l->data != widget)
|
||||
cc_color_device_set_expanded (CC_COLOR_DEVICE (l->data), FALSE);
|
||||
}
|
||||
prefs->model_is_changing = FALSE;
|
||||
}
|
||||
@@ -1589,7 +1630,8 @@ gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *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);
|
||||
gtk_list_box_append (prefs->list_box, widget);
|
||||
gtk_widget_show (widget);
|
||||
gtk_container_add (GTK_CONTAINER (prefs->list_box), widget);
|
||||
gtk_size_group_add_widget (prefs->list_box_size, widget);
|
||||
|
||||
/* add profiles */
|
||||
@@ -1605,25 +1647,22 @@ gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *device)
|
||||
static void
|
||||
gcm_prefs_remove_device (CcColorPanel *prefs, CdDevice *device)
|
||||
{
|
||||
GtkWidget *child;
|
||||
CdDevice *device_tmp;
|
||||
GList *l;
|
||||
g_autoptr(GList) list = NULL;
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (prefs->list_box));
|
||||
while (child)
|
||||
list = gtk_container_get_children (GTK_CONTAINER (prefs->list_box));
|
||||
for (l = list; l != NULL; l = l->next)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
if (CC_IS_COLOR_DEVICE (child))
|
||||
device_tmp = cc_color_device_get_device (CC_COLOR_DEVICE (child));
|
||||
if (CC_IS_COLOR_DEVICE (l->data))
|
||||
device_tmp = cc_color_device_get_device (CC_COLOR_DEVICE (l->data));
|
||||
else
|
||||
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (child));
|
||||
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (l->data));
|
||||
if (g_strcmp0 (cd_device_get_object_path (device),
|
||||
cd_device_get_object_path (device_tmp)) == 0)
|
||||
{
|
||||
gtk_list_box_remove (prefs->list_box, child);
|
||||
gtk_widget_destroy (GTK_WIDGET (l->data));
|
||||
}
|
||||
|
||||
child = next;
|
||||
}
|
||||
g_signal_handlers_disconnect_by_func (device,
|
||||
G_CALLBACK (gcm_prefs_device_changed_cb),
|
||||
@@ -1634,16 +1673,18 @@ gcm_prefs_remove_device (CcColorPanel *prefs, CdDevice *device)
|
||||
static void
|
||||
gcm_prefs_update_device_list_extra_entry (CcColorPanel *prefs)
|
||||
{
|
||||
GtkListBoxRow *first_row;
|
||||
g_autoptr(GList) device_widgets = NULL;
|
||||
guint number_of_devices;
|
||||
|
||||
/* any devices to show? */
|
||||
first_row = gtk_list_box_get_row_at_index (prefs->list_box, 0);
|
||||
gtk_widget_set_visible (prefs->label_no_devices, first_row == NULL);
|
||||
gtk_widget_set_visible (prefs->box_devices, first_row != NULL);
|
||||
device_widgets = gtk_container_get_children (GTK_CONTAINER (prefs->list_box));
|
||||
number_of_devices = g_list_length (device_widgets);
|
||||
gtk_widget_set_visible (prefs->label_no_devices, number_of_devices == 0);
|
||||
gtk_widget_set_visible (prefs->box_devices, number_of_devices > 0);
|
||||
|
||||
/* if we have only one device expand it by default */
|
||||
if (gtk_list_box_get_row_at_index (prefs->list_box, 1) == NULL)
|
||||
cc_color_device_set_expanded (CC_COLOR_DEVICE (first_row), TRUE);
|
||||
if (number_of_devices == 1)
|
||||
cc_color_device_set_expanded (CC_COLOR_DEVICE (device_widgets->data), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1704,9 +1745,6 @@ static void
|
||||
gcm_prefs_list_box_row_selected_cb (CcColorPanel *panel,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
if (gtk_widget_in_destruction (panel->toolbar_devices))
|
||||
return;
|
||||
|
||||
gcm_prefs_refresh_toolbar_buttons (panel);
|
||||
}
|
||||
|
||||
@@ -1827,6 +1865,12 @@ gcm_prefs_is_livecd (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gcm_prefs_window_realize_cb (CcColorPanel *prefs)
|
||||
{
|
||||
prefs->main_window = gtk_widget_get_toplevel (GTK_WIDGET (prefs));
|
||||
}
|
||||
|
||||
static const char *
|
||||
cc_color_panel_get_help_uri (CcPanel *panel)
|
||||
{
|
||||
@@ -1873,7 +1917,7 @@ cc_color_panel_dispose (GObject *object)
|
||||
g_clear_object (&prefs->list_box_size);
|
||||
g_clear_pointer (&prefs->sensors, g_ptr_array_unref);
|
||||
g_clear_pointer (&prefs->list_box_filter, g_free);
|
||||
g_clear_pointer ((GtkWindow **)&prefs->dialog_assign, gtk_window_destroy);
|
||||
g_clear_pointer (&prefs->dialog_assign, gtk_widget_destroy);
|
||||
|
||||
G_OBJECT_CLASS (cc_color_panel_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -1909,15 +1953,18 @@ cc_color_panel_class_init (CcColorPanelClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, box_calib_temp);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, box_calib_title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, box_devices);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, button_assign_cancel);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, button_assign_import);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, button_assign_ok);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, button_calib_export);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, button_calib_upload);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, dialog_assign);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, entry_calib_title);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, frame_devices);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, label_assign_warning);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, label_calib_summary_message);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, label_calib_upload_location);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, label_no_devices);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, list_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, liststore_assign);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, liststore_calib_kind);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcColorPanel, liststore_calib_sensor);
|
||||
@@ -1992,6 +2039,7 @@ static void
|
||||
cc_color_panel_init (CcColorPanel *prefs)
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
GtkStyleContext *context;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModel *model_filter;
|
||||
GtkTreeSelection *selection;
|
||||
@@ -2040,7 +2088,16 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
g_signal_connect_object (prefs->toolbutton_device_calibrate, "clicked",
|
||||
G_CALLBACK (gcm_prefs_calibrate_cb), prefs, G_CONNECT_SWAPPED);
|
||||
|
||||
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_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);
|
||||
|
||||
@@ -2049,6 +2106,9 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
G_CALLBACK (gcm_prefs_button_assign_import_cb), prefs, G_CONNECT_SWAPPED);
|
||||
|
||||
/* 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);
|
||||
@@ -2164,6 +2224,7 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
G_CALLBACK (gcm_prefs_device_removed_cb), prefs, 0);
|
||||
|
||||
/* use a listbox for the main UI */
|
||||
prefs->list_box = GTK_LIST_BOX (gtk_list_box_new ());
|
||||
gtk_list_box_set_filter_func (prefs->list_box,
|
||||
cc_color_panel_filter_func,
|
||||
prefs,
|
||||
@@ -2172,6 +2233,12 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
cc_color_panel_sort_func,
|
||||
prefs,
|
||||
NULL);
|
||||
gtk_list_box_set_header_func (prefs->list_box,
|
||||
cc_list_box_update_header_func,
|
||||
prefs, NULL);
|
||||
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);
|
||||
@@ -2180,6 +2247,9 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
prefs, G_CONNECT_SWAPPED);
|
||||
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));
|
||||
gtk_widget_show (GTK_WIDGET (prefs->list_box));
|
||||
|
||||
/* connect to colord */
|
||||
cd_client_connect (prefs->client,
|
||||
cc_panel_get_cancellable (CC_PANEL (prefs)),
|
||||
@@ -2202,6 +2272,12 @@ cc_color_panel_init (CcColorPanel *prefs)
|
||||
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, "realize",
|
||||
G_CALLBACK (gcm_prefs_window_realize_cb),
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -435,10 +435,10 @@ cc_color_profile_init (CcColorProfile *color_profile)
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 9);
|
||||
|
||||
/* default tick */
|
||||
color_profile->widget_image = gtk_image_new_from_icon_name ("object-select-symbolic");
|
||||
color_profile->widget_image = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_set_margin_start (color_profile->widget_image, IMAGE_WIDGET_PADDING);
|
||||
gtk_widget_set_margin_end (color_profile->widget_image, IMAGE_WIDGET_PADDING);
|
||||
gtk_box_append (GTK_BOX (box), color_profile->widget_image);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_profile->widget_image, FALSE, FALSE, 0);
|
||||
|
||||
/* description */
|
||||
color_profile->widget_description = gtk_label_new ("");
|
||||
@@ -447,18 +447,18 @@ cc_color_profile_init (CcColorProfile *color_profile)
|
||||
gtk_widget_set_halign (color_profile->widget_description, GTK_ALIGN_START);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (color_profile->widget_description), PANGO_ELLIPSIZE_END);
|
||||
gtk_label_set_xalign (GTK_LABEL (color_profile->widget_description), 0);
|
||||
gtk_widget_set_hexpand (color_profile->widget_description, TRUE);
|
||||
gtk_widget_set_vexpand (color_profile->widget_description, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), color_profile->widget_description);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_profile->widget_description, TRUE, TRUE, 0);
|
||||
gtk_widget_show (color_profile->widget_description);
|
||||
|
||||
/* profile warnings/info */
|
||||
color_profile->widget_info = gtk_image_new_from_icon_name ("dialog-information-symbolic");
|
||||
color_profile->widget_info = gtk_image_new_from_icon_name ("dialog-information-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_set_margin_start (color_profile->widget_info, IMAGE_WIDGET_PADDING);
|
||||
gtk_widget_set_margin_end (color_profile->widget_info, IMAGE_WIDGET_PADDING);
|
||||
gtk_box_append (GTK_BOX (box), color_profile->widget_info);
|
||||
gtk_box_pack_start (GTK_BOX (box), color_profile->widget_info, FALSE, FALSE, 0);
|
||||
|
||||
/* refresh */
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (color_profile), box);
|
||||
gtk_container_add (GTK_CONTAINER (color_profile), box);
|
||||
gtk_widget_set_visible (box, TRUE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
||||
@@ -3,7 +3,7 @@ Name=Color
|
||||
Comment=Calibrate the color of your devices, such as displays, cameras or printers
|
||||
Exec=gnome-control-center color
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=org.gnome.Settings-color-symbolic
|
||||
Icon=preferences-color
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
@@ -17,4 +17,4 @@ X-GNOME-Bugzilla-Version=@VERSION@
|
||||
# Translators: Search terms to find the Color panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=Color;ICC;Profile;Calibrate;Printer;Display;
|
||||
# Notifications are emitted by gnome-settings-daemon
|
||||
X-GNOME-UsesNotifications=true
|
||||
X-GNOME-UsesNotifications=true
|
||||
BIN
panels/color/icons/16x16/preferences-color.png
Normal file
|
After Width: | Height: | Size: 837 B |
BIN
panels/color/icons/22x22/preferences-color.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
panels/color/icons/24x24/preferences-color.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
panels/color/icons/256x256/preferences-color.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
panels/color/icons/32x32/preferences-color.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
panels/color/icons/48x48/preferences-color.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
panels/color/icons/64x64/preferences-color.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
@@ -1,4 +1,21 @@
|
||||
icon_sizes = [
|
||||
'16x16',
|
||||
'22x22',
|
||||
'24x24',
|
||||
'32x32',
|
||||
'48x48',
|
||||
'64x64',
|
||||
'256x256'
|
||||
]
|
||||
|
||||
foreach icon_size: icon_sizes
|
||||
install_data(
|
||||
join_paths(icon_size, 'preferences-color.png'),
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', icon_size, 'apps')
|
||||
)
|
||||
endforeach
|
||||
|
||||
install_data(
|
||||
'scalable/org.gnome.Settings-color-symbolic.svg',
|
||||
'scalable/preferences-color.svg',
|
||||
install_dir: join_paths(control_center_icondir, 'hicolor', 'scalable', 'apps')
|
||||
)
|
||||
|
||||
149
panels/color/icons/render-icons.py
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import xml.sax
|
||||
import subprocess
|
||||
|
||||
INKSCAPE = '/usr/bin/inkscape'
|
||||
SRC = os.path.join('.', 'src')
|
||||
|
||||
inkscape_process = None
|
||||
|
||||
def wait_for_prompt(process, command=None):
|
||||
if command is not None:
|
||||
process.stdin.write(command+'\n')
|
||||
|
||||
output = process.stdout.read(1)
|
||||
output += process.stdout.read(1)
|
||||
|
||||
while output != "\n>":
|
||||
output = output[-1:]
|
||||
output += process.stdout.read(1)
|
||||
|
||||
def start_inkscape():
|
||||
process = subprocess.Popen([INKSCAPE, '--shell'], bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
wait_for_prompt(process)
|
||||
return process
|
||||
|
||||
def inkscape_render_rect(icon_file, rect, output_file):
|
||||
global inkscape_process
|
||||
if inkscape_process is None:
|
||||
inkscape_process = start_inkscape()
|
||||
wait_for_prompt(inkscape_process, '%s -i %s -e %s' % (icon_file, rect, output_file))
|
||||
|
||||
class ContentHandler(xml.sax.ContentHandler):
|
||||
ROOT = 0
|
||||
SVG = 1
|
||||
LAYER = 2
|
||||
OTHER = 3
|
||||
TEXT = 4
|
||||
def __init__(self, path, force=False):
|
||||
self.stack = [self.ROOT]
|
||||
self.inside = [self.ROOT]
|
||||
self.path = path
|
||||
self.rects = []
|
||||
self.state = self.ROOT
|
||||
self.chars = ""
|
||||
self.force = force
|
||||
|
||||
def endDocument(self):
|
||||
pass
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
if self.inside[-1] == self.ROOT:
|
||||
if name == "svg":
|
||||
self.stack.append(self.SVG)
|
||||
self.inside.append(self.SVG)
|
||||
return
|
||||
elif self.inside[-1] == self.SVG:
|
||||
if (name == "g" and attrs.has_key('inkscape:groupmode') and attrs.has_key('inkscape:label')
|
||||
and attrs['inkscape:groupmode'] == 'layer' and attrs['inkscape:label'].startswith('baseplate')):
|
||||
self.stack.append(self.LAYER)
|
||||
self.inside.append(self.LAYER)
|
||||
self.context = None
|
||||
self.icon_name = None
|
||||
self.rects = []
|
||||
return
|
||||
elif self.inside[-1] == self.LAYER:
|
||||
if name == "text" and attrs.has_key('inkscape:label') and attrs['inkscape:label'] == 'context':
|
||||
self.stack.append(self.TEXT)
|
||||
self.inside.append(self.TEXT)
|
||||
self.text='context'
|
||||
self.chars = ""
|
||||
return
|
||||
elif name == "text" and attrs.has_key('inkscape:label') and attrs['inkscape:label'] == 'icon-name':
|
||||
self.stack.append(self.TEXT)
|
||||
self.inside.append(self.TEXT)
|
||||
self.text='icon-name'
|
||||
self.chars = ""
|
||||
return
|
||||
elif name == "rect":
|
||||
self.rects.append(attrs)
|
||||
|
||||
self.stack.append(self.OTHER)
|
||||
|
||||
|
||||
def endElement(self, name):
|
||||
stacked = self.stack.pop()
|
||||
if self.inside[-1] == stacked:
|
||||
self.inside.pop()
|
||||
|
||||
if stacked == self.TEXT and self.text is not None:
|
||||
assert self.text in ['context', 'icon-name']
|
||||
if self.text == 'context':
|
||||
self.context = self.chars
|
||||
elif self.text == 'icon-name':
|
||||
self.icon_name = self.chars
|
||||
self.text = None
|
||||
elif stacked == self.LAYER:
|
||||
assert self.icon_name
|
||||
assert self.context
|
||||
print '%s %s' % (self.context, self.icon_name)
|
||||
for rect in self.rects:
|
||||
width = rect['width']
|
||||
height = rect['height']
|
||||
id = rect['id']
|
||||
|
||||
dir = os.path.join("icons", "%sx%s" % (width, height), self.context)
|
||||
outfile = os.path.join(dir, self.icon_name+'.png')
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
# Do a time based check!
|
||||
if self.force or not os.path.exists(outfile):
|
||||
inkscape_render_rect(self.path, id, outfile)
|
||||
sys.stdout.write('.')
|
||||
else:
|
||||
stat_in = os.stat(self.path)
|
||||
stat_out = os.stat(outfile)
|
||||
if stat_in.st_mtime > stat_out.st_mtime:
|
||||
inkscape_render_rect(self.path, id, outfile)
|
||||
sys.stdout.write('.')
|
||||
else:
|
||||
sys.stdout.write('-')
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write('\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
def characters(self, chars):
|
||||
self.chars += chars.strip()
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
if not os.path.exists('icons'):
|
||||
os.mkdir('icons')
|
||||
print 'Rendering from SVGs in %s' % SRC
|
||||
for file in os.listdir(SRC):
|
||||
if file[-4:] == '.svg':
|
||||
file = os.path.join(SRC, file)
|
||||
handler = ContentHandler(file)
|
||||
xml.sax.parse(open(file), handler)
|
||||
else:
|
||||
file = os.path.join(SRC, sys.argv[1] + '.svg')
|
||||
if os.path.exists(os.path.join(file)):
|
||||
handler = ContentHandler(file, True)
|
||||
xml.sax.parse(open(file), handler)
|
||||
else:
|
||||
print "Error: No such file %s" % file
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#2e3434">
|
||||
<path d="m 8.085938 0.015625 c -2.203126 0 -4 1.796875 -4 4 s 1.796874 4 4 4 c 2.203124 0 4 -1.796875 4 -4 s -1.796876 -4 -4 -4 z m 0 1.972656 c 1.121093 -0.003906 2.03125 0.90625 2.027343 2.027344 c 0.003907 1.121094 -0.90625 2.03125 -2.027343 2.027344 c -1.121094 0.003906 -2.027344 -0.90625 -2.027344 -2.027344 s 0.90625 -2.03125 2.027344 -2.027344 z m 0 0"/>
|
||||
<path d="m 4.070312 7.015625 c -2.21875 0 -4.0312495 1.8125 -4.0312495 4.03125 s 1.8124995 4.03125 4.0312495 4.03125 c 2.222657 0 4.03125 -1.8125 4.03125 -4.03125 s -1.808593 -4.03125 -4.03125 -4.03125 z m 0 1.988281 c 1.132813 -0.003906 2.046876 0.914063 2.042969 2.042969 c 0.003907 1.128906 -0.910156 2.046875 -2.042969 2.042969 c -1.128906 0.003906 -2.042968 -0.914063 -2.042968 -2.042969 s 0.914062 -2.046875 2.042968 -2.042969 z m 0 0"/>
|
||||
<path d="m 15.992188 11 c 0 2.207031 -1.789063 4 -4 4 c -2.207032 0 -4 -1.789062 -4 -4 s 1.792968 -4 4 -4 c 2.210937 0 4 1.792969 4 4 z m 0 0"/>
|
||||
<path d="m 6.898438 11 c 0 1.554688 -1.257813 2.8125 -2.8125 2.8125 c -1.550782 0 -2.8125 -1.257812 -2.8125 -2.8125 s 1.261718 -2.8125 2.8125 -2.8125 c 1.554687 0 2.8125 1.257812 2.8125 2.8125 z m 0 0" fill-opacity="0.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
728
panels/color/icons/scalable/preferences-color.svg
Normal file
|
After Width: | Height: | Size: 100 KiB |