aaassseee / screen_brightness

A Plugin for controlling screen brightness with application life cycle set and reset brightness implemented
https://pub.dev/packages/screen_brightness
MIT License
25 stars 22 forks source link

[bug] System brightness doesn't update when app is focused #20

Closed kensho42 closed 1 year ago

kensho42 commented 1 year ago

Description (bug summary)

I was playing around with screen_brightness to see if I can have real-time data on system brightness. My use case is to have app change to light/dark theme based on system's brightness (for instance, have dark mode activated automatically when system brightness dips below 0.30 — and activate light theme when the opposite is true). It works, for so long as the app is not in the foreground/not focused — the moment the app window is focused, it doesn't update anymore (gets stuck with the last result) — put app in background, and now works fine again.

Tried both ScreenBrightness().current and ScreenBrightness().system to no avail.

The following is the code I played with:

FutureBuilder<double>(
  future: ScreenBrightness().current,
  //future: ScreenBrightness().system,
  builder: (context, snapshot) {
    double currentBrightness = 0;
    if (snapshot.hasData) {
      currentBrightness = snapshot.data!;
    }

    return StreamBuilder<double>(
      stream: ScreenBrightness()
          .onCurrentBrightnessChanged,
      builder: (context, snapshot) {
        double changedBrightness =
            currentBrightness;
        if (snapshot.hasData) {
          changedBrightness = snapshot.data!;
        }

        return Text('Current brightness: $changedBrightness');
      },
    );
  },
),

Also, with the following:

double _brightness = 0;

@override
void initState() {
  super.initState();
  _getBrightness();
  _onCurrentBrightnessChanged();
}

Future<void> _getBrightness() async {
  final brightness = await ScreenBrightness().system;
  setState(() {
    _brightness = brightness;
  });
}

void _onCurrentBrightnessChanged() {
  ScreenBrightness().onCurrentBrightnessChanged.listen((brightness) {
    setState(() {
      _brightness = brightness;
    });
    //print(_brightness);
  });
}

but the result is the same.

Step to reproduce (how to reproduce the bug)

  1. Run example/lib/main.dart
  2. While the app is focused, change system brightness (doesn't work in my case)
  3. While the app is not focused, change system brightness (works great)

Platform (only tested on iOS and macOS)

The above steps apply to macOS (testing hardware: MBP 13' 2017, using macOS Ventura 13.0).

For iOS (testing hardware: iPhone X, using iOS 16.5), I was turning room lights on and off — and it was not updating, even though the screen's brightness was changing. Sidenote: While the app is running, if we open the control center and change system's brightness manually — it works, but it doesn't count because the app is losing focus this way. And the desired outcome is to follow system's brightness in real-time, while using the app.

aaassseee commented 1 year ago

Hi @kensho42 can you share a runnable example? For the system brightness not changing. Due to iOS is a close source environment, we cannot access system brightness without Apple provide any function. So, what I mean is, the system brightness is just a value when the library is first initialize and after user resume the app. With system brightness value stored, we can resume the brightness when user leave, move to background, or pause the app, which is not the usecase you are trying to achieve. System brightness could not change in real time.

kensho42 commented 1 year ago

Hi @aaassseee,

System brightness could not change in real time.

Do you mean that we cannot access the current value (as it updates in real-time) of system brightness on iOS and macOS?

That would be interesting because it can access it while it is in background. On macOS, it's more obvious, if you run the code below, you can see it changing in real-time — so long as the app is not focused.

I've seen other apps on iOS that react to system brightness changing. Pocket used to be one such example, that automatically activated dark theme the moment the brightness value dipped below a certain point.

Below I'll post the full code so you can simply run it to get a better idea of what I mean:

import 'package:flutter/material.dart';
import 'package:screen_brightness/screen_brightness.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  double _brightness = 0;

  @override
  void initState() {
    super.initState();
    _getBrightness();
    _listenForBrightnessChanges();
  }

  Future<void> _getBrightness() async {
    final brightness = await ScreenBrightness().system;
    setState(() => _brightness = brightness);
  }

  void _listenForBrightnessChanges() {
    ScreenBrightness().onCurrentBrightnessChanged.listen((brightness) {
      setState(() => _brightness = brightness);
      print(_brightness);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screen Brightness'),
        ),
        body: Center(
          child: Text(
            'Brightness: ${_brightness.toStringAsFixed(2)}',
            style: TextStyle(fontSize: 24),
          ),
        ),
      ),
    );
  }
}

Steps to reproduce (how to reproduce the bug)

Run the code above While the app is focused, change system brightness manually with keyboard (doesn't work in my case) While the app is not focused, change system brightness manually with keyboard (works great)

aaassseee commented 1 year ago

@kensho42 Thanks for the examples. I will check in Monday, due to lack of iOS device.

aaassseee commented 1 year ago

Hi @kensho42, I saw Pocket didn't have the function that you mentioned. Am I doing something wrong?

kensho42 commented 1 year ago

Hi @kensho42, I saw Pocket didn't have the function that you mentioned. Am I doing something wrong?

Sadly, they just recently released a major version of the App, that removed that functionality.

aaassseee commented 1 year ago

Hi @kensho42. Are you currently using M Chip devices? And are you using external monitor? Oh no. I saw what devices you are testing with now.

aaassseee commented 1 year ago

OK, I understand your question now. As I said, there isn't any way to monitor system brightness due to Apple didn't provide any method to get system brightness, if so please provide any reference. Moreover, this plugin in currently not support external display with macOS M Chip devices.

The way that this plugin works is, we kept system brightness on plugin start, system brightness will change only when user unfocused the app which will provide a way get the correct the changed system brightness. For other case, all changes should be changing the current brightness to sync up the behaviour with mobile.

kensho42 commented 1 year ago

Hi @kensho42, I saw Pocket didn't have the function that you mentioned. Am I doing something wrong?

Sadly, they just recently released a major version of the App, that removed that functionality.

This post shows Pocket how it used to be, automatically switched to dark theme when screen brightness dipped below a certain threshold (something like 0.3) — and it did react in real-time @ https://www.hardreset.info/devices/apps/apps-pocket/enable-auto-theme/

kensho42 commented 1 year ago

OK, I understand your question now. As I said, there isn't any way to monitor system brightness due to Apple didn't provide any method to get system brightness, if so please provide any reference. Moreover, this plugin in currently not support external display with macOS M Chip devices.

The way that this plugin works is, we kept system brightness on plugin start, system brightness will change only when user unfocused the app which will provide a way get the correct the changed system brightness. For other case, all changes should be changing the current brightness to sync up the behaviour with mobile.

Just found out this app called DarkModeBuddy, that activates the dark-mode for whole macOS system in real-time.

kensho42 commented 1 year ago

Just found out this app called DarkModeBuddy, that activates the dark-mode for whole macOS system in real-time.

but I guess it relies on ambient light sensor and not on screen brightness

aaassseee commented 1 year ago

Just found out this app called DarkModeBuddy, that activates the dark-mode for whole macOS system in real-time.

but I guess it relies on ambient light sensor and not on screen brightness

Yes, thats what I am thinking. I don't think application can read system screen brightness in real time because Apple didn't provide any method to monitor the system brightness changes. Maybe you can achieve your goal by using the ambient light sensor data. But, reminded that ambient light sensor may not be install in desktop or Mac monitor.

kensho42 commented 1 year ago

Yes, I think I'm going to rely on the ambient light sensor to achieve that — thanks for pointing that out.