Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion system_theme/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## [3.2.0] - [30/12/2025]
## [3.2.0] - [31/12/2025]

* feat: Reactive theming for macOS ([#45](https://github.com/bdlukaa/system_theme/pull/45))
* chore: Migrate iOS and macOS to Swift Package Manager. ([#46](https://github.com/bdlukaa/system_theme/pull/46), [#45](https://github.com/bdlukaa/system_theme/pull/45))
* feat: Automatically adjust lightness if the platform doesn't support it natively. ([#46](https://github.com/bdlukaa/system_theme/pull/46))
This is enabled by default. You can disable it by setting `SystemTheme.autoAdjustLightness` to `false`.

## [3.1.2] - [04/10/2024]

Expand Down
59 changes: 20 additions & 39 deletions system_theme/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
<div>
<h1 align="center">system_theme</h1>
<h3 align="center">system_theme</h3>
<p align="center" >
<a title="Discord" href="https://discord.gg/674gpDQUVq">
<img src="https://img.shields.io/discord/809528329337962516?label=discord&logo=discord" />
</a>
<a title="Pub" href="https://pub.dartlang.org/packages/system_theme" >
<img src="https://img.shields.io/pub/v/system_theme.svg?style=popout&include_prereleases" />
</a>
<a title="Github License">
<img src="https://img.shields.io/github/license/bdlukaa/system_theme" />
</a>
</p>
<p align="center">
<a title="Patreon" href="https://patreon.com/bdlukaa">
<img src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dbdlukaa%26type%3Dpatrons&style=for-the-badge">
</a>
</p>
<p align="center">
A flutter plugin to get the current system theme information
A flutter plugin to retrieve the current system theme information
</p>
</div>

- [Supported platforms](#supported-platforms)
- [Usage](#usage)
- [Get system accent color](#get-system-accent-color)
- [Contribution](#contribution)
- [Acknowlegments](#acknowlegments)

### Supported platforms

| Feature | Android 10+ | iOS | Web | MacOs 10.14+ | Windows 10+ and XBox | Linux GTK 3+ |
| ----------------- | :---------: | :-: | :-: | :---------: | :------------------: | :----------: |
| Get accent color | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Listen to changes | | | | ✔️ | ✔️ | |
| Platform | Accent Color | Listen to Changes | Minimum Version |
| :--- | :---: | :---: | :--- |
| **Android** | ✔️ | | Android 10+ |
| **iOS** | ✔️ | | iOS 14+ |
| **Windows** | ✔️ | ✔️ | Windows 10+ |
| **macOS** | ✔️ | ✔️ | Mojave 10.14+ |
| **Linux** | ✔️ | | GTK 3+ |
| **Web** | ✔️ | | All modern browsers |

## Usage

Expand Down Expand Up @@ -94,25 +84,16 @@ SystemTheme.onChange.listen((event) {
Alteratively, you can the `SystemThemeBuilder` widget to listen to changes on the system accent color:

```dart
SystemThemeBuilder(builder: (context, accent) {
return ColoredBox(color: accent.accentColor);
});
```

### Checking if accent color is supported

The `flutter/foundation` package provides a `defaultTargetPlatform` getter, which can be used to check what platform the current app is running on.

You can check if the current platform supports accent colors using this extension method:

```dart
import 'package:flutter/foundation.dart' show defaultTargetPlatform;

void main() {
final supported = defaultTargetPlatform.supportsAccentColor;

print('Accent color is: ${supported ? 'supported' : 'not supported'} on the current platform');
}
SystemThemeBuilder(
builder: (context, color) {
return ColoredBox(
color: color.accent, // Automatically updates when system theme changes
child: const Center(
child: Text('System Accent Color'),
),
);
},
);
```

## Contribution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,19 @@ class SystemThemePlugin: FlutterPlugin, ActivityAware, MethodCallHandler {
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
when (call.method) {
"SystemTheme.accentColor" -> {
val accentColor = getDeviceAccentColor(activity)
val hexColor = java.lang.String.format("#%06X", 0xFFFFFF and accentColor)
val rgb = getRGB(hexColor)
val color = getDeviceAccentColor(activity)
val r = (color shr 16) and 0xFF
val g = (color shr 8) and 0xFF
val b = color and 0xFF
// val a = (color shr 24) and 0xFF

result.success(hashMapOf<String, Any?>(
"accent" to hashMapOf<String, Any?>(
"R" to rgb[0],
"G" to rgb[1],
"B" to rgb[2],
"A" to 1
)
"accent" to hashMapOf<String, Any?>(
"R" to r,
"G" to g,
"B" to b,
"A" to 255
)
))
}
else -> {
Expand All @@ -51,15 +54,6 @@ class SystemThemePlugin: FlutterPlugin, ActivityAware, MethodCallHandler {
return value.data
}

private fun getRGB(rgb: String): IntArray {
var color = rgb;
if (rgb.startsWith("#")) color = rgb.replace("#", "");
val r = color.substring(0, 2).toInt(16) // 16 for hex
val g = color.substring(2, 4).toInt(16) // 16 for hex
val b = color.substring(4, 6).toInt(16) // 16 for hex
return intArrayOf(r, g, b)
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
Expand Down
1 change: 0 additions & 1 deletion system_theme/example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols
Expand Down
12 changes: 6 additions & 6 deletions system_theme/example/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "a14f74ff3a1cbd521163c5f03d68113d50af93d3"
revision: "f6ff1529fd6d8af5f706051d9251ac9231c83407"
channel: "stable"

project_type: app
Expand All @@ -13,11 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
- platform: web
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407
base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407
- platform: android
create_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407
base_revision: f6ff1529fd6d8af5f706051d9251ac9231c83407

# User provided section

Expand Down
3 changes: 2 additions & 1 deletion system_theme/example/android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ gradle-wrapper.jar
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/

# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
71 changes: 0 additions & 71 deletions system_theme/example/android/app/build.gradle

This file was deleted.

44 changes: 44 additions & 0 deletions system_theme/example/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}

android {
namespace = "com.bruno.system_theme_example"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.bruno.system_theme_example"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}

flutter {
source = "../.."
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bruno.system_theme_example">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
Expand Down
17 changes: 14 additions & 3 deletions system_theme/example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bruno.system_theme_example">
<application
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="system_theme_example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
Expand All @@ -31,4 +31,15 @@
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ package com.bruno.system_theme_example

import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
}
class MainActivity : FlutterActivity()
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bruno.system_theme_example">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
Expand Down
31 changes: 0 additions & 31 deletions system_theme/example/android/build.gradle

This file was deleted.

Loading