Skip to content
Open
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
101 changes: 66 additions & 35 deletions lib/widgets/fluffy_chat_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ class FluffyChatApp extends StatefulWidget {

class _FluffyChatAppState extends State<FluffyChatApp> {
final _androidSystemFontPlugin = AndroidSystemFont();
static const _platform = MethodChannel('xyz.extera.next/window');

// Keeps track of the last Brightness applied to the native window frame
// (title bar) so we don't spam the platform channel with redundant calls
// on every rebuild.
Brightness? _lastWindowBrightness;

@override
void initState() {
Expand Down Expand Up @@ -88,6 +94,25 @@ class _FluffyChatAppState extends State<FluffyChatApp> {
});
}

void _syncWindowBrightness(BuildContext context, ThemeMode themeMode) {
if (!Platform.isWindows) return;

final resolvedBrightness = switch (themeMode) {
ThemeMode.dark => Brightness.dark,
ThemeMode.light => Brightness.light,
ThemeMode.system => MediaQuery.platformBrightnessOf(context),
};

if (resolvedBrightness == _lastWindowBrightness) return;
_lastWindowBrightness = resolvedBrightness;

_platform.invokeMethod('setTitleBarDarkMode', {
'isDark': resolvedBrightness == Brightness.dark,
}).catchError((e) {
debugPrint('Failed to set title bar color: $e');
});
}

@override
Widget build(BuildContext context) {
return ThemeBuilder(
Expand All @@ -99,45 +124,51 @@ class _FluffyChatAppState extends State<FluffyChatApp> {
schemeVariant,
pureBlack,
twemoji,
) => MaterialApp.router(
title: AppConfig.applicationName,
themeMode: themeMode,
theme: FluffyThemes.buildTheme(
context,
Brightness.light,
primaryColor,
schemeVariant,
pureBlack,
twemoji,
),
darkTheme: FluffyThemes.buildTheme(
context,
Brightness.dark,
primaryColor,
schemeVariant,
pureBlack,
twemoji,
),
scrollBehavior: CustomScrollBehavior(),
localizationsDelegates: L10n.localizationsDelegates,
supportedLocales: L10n.supportedLocales,
routerConfig: FluffyChatApp.router,
builder: (context, child) => AppLockWidget(
pincode: widget.pincode,
clients: widget.clients,
) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_syncWindowBrightness(context, themeMode);
});

return MaterialApp.router(
title: AppConfig.applicationName,
themeMode: themeMode,
theme: FluffyThemes.buildTheme(
context,
Brightness.light,
primaryColor,
schemeVariant,
pureBlack,
twemoji,
),
darkTheme: FluffyThemes.buildTheme(
context,
Brightness.dark,
primaryColor,
schemeVariant,
pureBlack,
twemoji,
),
scrollBehavior: CustomScrollBehavior(),
localizationsDelegates: L10n.localizationsDelegates,
supportedLocales: L10n.supportedLocales,
routerConfig: FluffyChatApp.router,
builder: (context, child) => AppLockWidget(
pincode: widget.pincode,
clients: widget.clients,
// Need a navigator above the Matrix widget for

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

эти 2 комента тоже надо бы, пропустила сначала

// displaying dialogs
child: DownloadManager(
child: BackgroundAudioPlayer(
child: Matrix(
clients: widget.clients,
store: widget.store,
child: widget.testWidget ?? child,
child: DownloadManager(
child: BackgroundAudioPlayer(
child: Matrix(
clients: widget.clients,
store: widget.store,
child: widget.testWidget ?? child,
),
),
),
),
),
),
);
},
);
}
}
}
33 changes: 33 additions & 0 deletions windows/runner/flutter_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,42 @@ bool FlutterWindow::OnCreate() {
}
RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow());

SetupChannelHandlers();
return true;
}

void FlutterWindow::SetupChannelHandlers() {
auto channel =
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
flutter_controller_->engine()->messenger(), "xyz.extera.next/window",
&flutter::StandardMethodCodec::GetInstance());

channel->SetMethodCallHandler(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

мне кажется тут чтото странное/неэффективное начинает происходить, но я цпп не знаю так что норм.

[this](const flutter::MethodCall<flutter::EncodableValue>& call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>
result) {
if (call.method_name() == "setTitleBarDarkMode") {
const auto* arguments = std::get_if<flutter::EncodableMap>(call.arguments());
if (arguments) {
auto isDark_variant = arguments->find(flutter::EncodableValue("isDark"));
if (isDark_variant != arguments->end()) {
if (const auto* isDark = std::get_if<bool>(&isDark_variant->second)) {
SetTitleBarColor(*isDark);
result->Success();
return;
}
}
}
result->Error("INVALID_ARGUMENT", "isDark parameter is required");
} else {
result->NotImplemented();
}
});

method_channel_ = std::move(channel);
}

void FlutterWindow::OnDestroy() {
if (flutter_controller_) {
flutter_controller_ = nullptr;
Expand Down
6 changes: 6 additions & 0 deletions windows/runner/flutter_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>

#include <memory>

Expand All @@ -28,6 +30,10 @@ class FlutterWindow : public Win32Window {

// The Flutter instance hosted by this window.
std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>>
method_channel_;

void SetupChannelHandlers();
};

#endif // RUNNER_FLUTTER_WINDOW_H_
12 changes: 12 additions & 0 deletions windows/runner/win32_window.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "win32_window.h"

#include <flutter_windows.h>
#include <dwmapi.h>

#include "resource.h"

#pragma comment(lib, "dwmapi.lib")

namespace {

constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
Expand Down Expand Up @@ -235,6 +238,15 @@ void Win32Window::SetQuitOnClose(bool quit_on_close) {
quit_on_close_ = quit_on_close;
}

void Win32Window::SetTitleBarColor(bool isDark) {
if (!window_handle_) return;

// Use DwmSetWindowAttribute to set the title bar color
// DWMWA_USE_IMMERSIVE_DARK_MODE = 20 for Windows 11
BOOL value = isDark ? TRUE : FALSE;
DwmSetWindowAttribute(window_handle_, 20, &value, sizeof(value));
}

bool Win32Window::OnCreate() {
// No-op; provided for subclasses.
return true;
Expand Down
4 changes: 4 additions & 0 deletions windows/runner/win32_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class Win32Window {
// Return a RECT representing the bounds of the current client area.
RECT GetClientArea();

// Sets the title bar color based on brightness (dark/light mode).
// isDark: true for dark mode (dark title bar), false for light mode (light title bar)
void SetTitleBarColor(bool isDark);

protected:
// Processes and route salient window messages for mouse handling,
// size change and DPI. Delegates handling of these to member overloads that
Expand Down