Skip to content

Commit

Permalink
Replace GSettings with GtkSettings (#193)
Browse files Browse the repository at this point in the history
GSettings may not be accessible when running confined - use GtkSettings
instead.
  • Loading branch information
jpnurmi committed Sep 9, 2022
1 parent b9cf4cd commit b84780b
Show file tree
Hide file tree
Showing 15 changed files with 405 additions and 116 deletions.
28 changes: 24 additions & 4 deletions .metadata
@@ -1,10 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.

version:
revision: ba78539bdb74dd05144a2490c453383078f81cdd
channel: master
revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
channel: stable

project_type: package
project_type: plugin

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
- platform: linux
create_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543
base_revision: ffccd96b62ee8cec7740dab303538c5fc26ac543

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
4 changes: 4 additions & 0 deletions example/linux/flutter/generated_plugin_registrant.cc
Expand Up @@ -7,9 +7,13 @@
#include "generated_plugin_registrant.h"

#include <handy_window/handy_window_plugin.h>
#include <yaru/yaru_plugin.h>

void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) handy_window_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "HandyWindowPlugin");
handy_window_plugin_register_with_registrar(handy_window_registrar);
g_autoptr(FlPluginRegistrar) yaru_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "YaruPlugin");
yaru_plugin_register_with_registrar(yaru_registrar);
}
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Expand Up @@ -4,6 +4,7 @@

list(APPEND FLUTTER_PLUGIN_LIST
handy_window
yaru
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down
32 changes: 32 additions & 0 deletions lib/src/settings.dart
@@ -0,0 +1,32 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

abstract class YaruSettings {
const YaruSettings._();
const factory YaruSettings() = YaruMethodChannel;

Future<String?> getThemeName();
Stream<String?> get themeNameChanged;
}

class YaruMethodChannel extends YaruSettings {
const YaruMethodChannel() : super._();

@visibleForTesting
final methodChannel = const MethodChannel('yaru');

@visibleForTesting
final eventChannel = const EventChannel('yaru/events');

@override
Future<String?> getThemeName() async {
return methodChannel.invokeMethod<String>('getThemeName');
}

@override
Stream<String?> get themeNameChanged {
return eventChannel
.receiveBroadcastStream('themeNameChanged')
.map((event) => event as String?);
}
}
41 changes: 17 additions & 24 deletions lib/src/widgets/inherited_theme.dart
@@ -1,11 +1,9 @@
import 'dart:async';

import 'package:dbus/dbus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gsettings/gsettings.dart';
import 'package:platform/platform.dart';

import 'package:yaru/src/settings.dart';
import 'package:yaru/yaru.dart';

YaruVariant? _detectYaruVariant(Platform platform) {
Expand Down Expand Up @@ -84,7 +82,7 @@ class YaruTheme extends StatefulWidget {
this.child,
this.data = const YaruThemeData(),
@visibleForTesting Platform? platform,
@visibleForTesting GSettings? settings,
@visibleForTesting YaruSettings? settings,
}) : assert(
builder != null || child != null,
'Either builder or child must be provided',
Expand All @@ -102,7 +100,7 @@ class YaruTheme extends StatefulWidget {
final YaruThemeData data;

final Platform _platform;
final GSettings? _settings;
final YaruSettings? _settings;

/// The data from the closest [YaruTheme] instance that encloses the given
/// context.
Expand All @@ -122,18 +120,16 @@ class YaruTheme extends StatefulWidget {

class _YaruThemeState extends State<YaruTheme> {
YaruVariant? _variant;
GSettings? _settings;
StreamSubscription<List<String>>? _subscription;
YaruSettings? _settings;
StreamSubscription<String?>? _subscription;

@override
void initState() {
super.initState();
if (widget.data.variant == null && !kIsWeb && widget._platform.isLinux) {
_settings = widget._settings ?? GSettings('org.gnome.desktop.interface');
_subscription = _settings!.keysChanged.listen((keys) {
if (keys.contains('gtk-theme')) {
updateVariant();
}
_settings = widget._settings ?? const YaruSettings();
_subscription = _settings!.themeNameChanged.listen((name) {
updateVariant(name);
});
updateVariant();
}
Expand All @@ -143,34 +139,31 @@ class _YaruThemeState extends State<YaruTheme> {
void dispose() {
super.dispose();
_subscription?.cancel();
if (widget._settings == null) {
_settings?.close();
}
}

// "Yaru-prussiangreen-dark" => YaruAccent.prussianGreen
YaruVariant? resolveVariant(String name) {
if (name.endsWith('-dark')) {
name = name.substring(0, name.length - 5);
YaruVariant? resolveVariant(String? name) {
if (name?.endsWith('-dark') == true) {
name = name!.substring(0, name.length - 5);
}
if (name.startsWith('Yaru-')) {
name = name.substring(5);
if (name?.startsWith('Yaru-') == true) {
name = name!.substring(5);
}
if (name == 'Yaru') {
return YaruVariant.orange;
}
for (final value in YaruVariant.values) {
if (value.name.toLowerCase() == name.toLowerCase()) {
if (value.name.toLowerCase() == name?.toLowerCase()) {
return value;
}
}
return _detectYaruVariant(widget._platform);
}

Future<void> updateVariant() async {
Future<void> updateVariant([String? value]) async {
assert(!kIsWeb && widget._platform.isLinux);
final name = await _settings?.get('gtk-theme') as DBusString;
setState(() => _variant = resolveVariant(name.value));
final name = value ?? await _settings?.getThemeName();
setState(() => _variant = resolveVariant(name));
}

ThemeMode resolveMode() {
Expand Down
47 changes: 47 additions & 0 deletions linux/CMakeLists.txt
@@ -0,0 +1,47 @@
# The Flutter tooling requires that developers have CMake 3.10 or later
# installed. You should not increase this version, as doing so will cause
# the plugin to fail to compile for some customers of the plugin.
cmake_minimum_required(VERSION 3.10)

# Project-level configuration.
set(PROJECT_NAME "yaru")
project(${PROJECT_NAME} LANGUAGES CXX)

# This value is used when generating builds using this plugin, so it must
# not be changed.
set(PLUGIN_NAME "yaru_plugin")

# Define the plugin library target. Its name must not be changed (see comment
# on PLUGIN_NAME above).
#
# Any new source files that you add to the plugin should be added here.
add_library(${PLUGIN_NAME} SHARED
"yaru_plugin.cc"
)

# Apply a standard set of build settings that are configured in the
# application-level CMakeLists.txt. This can be removed for plugins that want
# full control over build settings.
apply_standard_settings(${PLUGIN_NAME})

# Symbols are hidden by default to reduce the chance of accidental conflicts
# between plugins. This should not be removed; any symbols that should be
# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro.
set_target_properties(${PLUGIN_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)

# Source include directories and library dependencies. Add any plugin-specific
# dependencies here.
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)

# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
set(yaru_bundled_libraries
""
PARENT_SCOPE
)
11 changes: 11 additions & 0 deletions linux/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//

// clang-format off

#include "generated_plugin_registrant.h"


void fl_register_plugins(FlPluginRegistry* registry) {
}
15 changes: 15 additions & 0 deletions linux/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
//
// Generated file. Do not edit.
//

// clang-format off

#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_

#include <flutter_linux/flutter_linux.h>

// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);

#endif // GENERATED_PLUGIN_REGISTRANT_
23 changes: 23 additions & 0 deletions linux/flutter/generated_plugins.cmake
@@ -0,0 +1,23 @@
#
# Generated file, do not edit.
#

list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
)

set(PLUGIN_BUNDLED_LIBRARIES)

foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)

foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
26 changes: 26 additions & 0 deletions linux/include/yaru/yaru_plugin.h
@@ -0,0 +1,26 @@
#ifndef FLUTTER_PLUGIN_YARU_PLUGIN_H_
#define FLUTTER_PLUGIN_YARU_PLUGIN_H_

#include <flutter_linux/flutter_linux.h>

G_BEGIN_DECLS

#ifdef FLUTTER_PLUGIN_IMPL
#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define FLUTTER_PLUGIN_EXPORT
#endif

typedef struct _YaruPlugin YaruPlugin;
typedef struct {
GObjectClass parent_class;
} YaruPluginClass;

FLUTTER_PLUGIN_EXPORT GType yaru_plugin_get_type();

FLUTTER_PLUGIN_EXPORT void yaru_plugin_register_with_registrar(
FlPluginRegistrar* registrar);

G_END_DECLS

#endif // FLUTTER_PLUGIN_YARU_PLUGIN_H_

0 comments on commit b84780b

Please sign in to comment.