Skip to content

Commit 2c83f0d

Browse files
authored
Merge pull request #151 from leoafarias/feature/transparency
Window improvements
2 parents 7885c5e + 7be71df commit 2c83f0d

17 files changed

+231
-15
lines changed

lib/main.dart

+18-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import 'dart:io';
22

3+
import 'package:bitsdojo_window/bitsdojo_window.dart';
34
import 'package:flutter/material.dart';
5+
import 'package:flutter_acrylic/flutter_acrylic.dart';
46
import 'package:flutter_localizations/flutter_localizations.dart';
57
import 'package:flutter_riverpod/flutter_riverpod.dart';
68
import 'package:hive/hive.dart';
@@ -10,7 +12,6 @@ import 'package:oktoast/oktoast.dart';
1012
import 'package:path_provider/path_provider.dart';
1113
import 'package:sidekick/i18n/language_manager.dart';
1214
import 'package:sidekick/src/modules/common/utils/migrateFiles.dart';
13-
import 'package:window_size/window_size.dart';
1415

1516
import 'src/modules/common/app_shell.dart';
1617
import 'src/modules/common/constants.dart';
@@ -24,6 +25,11 @@ import 'src/theme.dart';
2425

2526
void main() async {
2627
WidgetsFlutterBinding.ensureInitialized();
28+
// Transparency compatibility for windows & linux
29+
if (!Platform.isMacOS) {
30+
await Window.initialize();
31+
}
32+
2733
Hive.registerAdapter(SidekickSettingsAdapter());
2834
Hive.registerAdapter(ProjectPathAdapter());
2935
final hiveDir = await getApplicationSupportDirectory();
@@ -40,13 +46,20 @@ void main() async {
4046
print('There was an issue opening the DB');
4147
}
4248

43-
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
44-
setWindowTitle(kAppTitle);
45-
setWindowMinSize(const Size(800, 500));
46-
setWindowMaxSize(Size.infinite);
49+
if (!(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
50+
print('Sidekick is not supported on your platform');
51+
exit(0);
4752
}
4853

4954
runApp(ProviderScope(child: FvmApp()));
55+
56+
doWhenWindowReady(() {
57+
final initialSize = Size(800, 500);
58+
appWindow.minSize = initialSize;
59+
appWindow.size = initialSize;
60+
appWindow.alignment = Alignment.center;
61+
appWindow.show();
62+
});
5063
}
5164

5265
/// Fvm App

lib/src/components/molecules/top_app_bar.dart

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:io';
22

3+
import 'package:bitsdojo_window/bitsdojo_window.dart';
34
import 'package:flutter/material.dart';
45
import 'package:hooks_riverpod/hooks_riverpod.dart';
56
import 'package:sidekick/src/components/atoms/typography.dart';
@@ -9,6 +10,7 @@ import 'package:sidekick/src/modules/settings/settings.screen.dart';
910
import 'package:sidekick/src/modules/updater/components/update_button.dart';
1011
import 'package:sidekick/src/theme.dart';
1112
import 'package:sidekick/src/version.dart';
13+
import 'package:sidekick/src/windowBorder.dart';
1214

1315
/// Sidekick top app bar
1416
class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
@@ -43,9 +45,12 @@ class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
4345
? const Caption(kAppTitle)
4446
: const SizedBox(height: 0, width: 0),
4547
centerTitle: true,
48+
leading: Platform.isMacOS ? WindowButtons() : SizedBox(),
4649
actions: [
4750
const SkUpdateButton(),
48-
const SizedBox(width: 10),
51+
const SizedBox(
52+
width: 10,
53+
),
4954
Center(child: Caption(packageVersion)),
5055
const SizedBox(width: 10),
5156
IconButton(
@@ -61,6 +66,7 @@ class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
6166
onPressed: openSettingsScreen,
6267
),
6368
const SizedBox(width: 10),
69+
if (Platform.isWindows || Platform.isLinux) WindowButtons(),
6470
],
6571
bottom: const PreferredSize(
6672
preferredSize: Size.fromHeight(1),
@@ -72,7 +78,7 @@ class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
7278
automaticallyImplyLeading: false,
7379
// shadowColor: Colors.transparent,
7480
// backgroundColor: Colors.transparent,
75-
// flexibleSpace: const BlurBackground(),
81+
flexibleSpace: MoveWindow(),
7682
);
7783
}
7884
}

lib/src/modules/fvm/fvm_queue.provider.dart

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
44
import 'package:flutter_riverpod/flutter_riverpod.dart';
55
import 'package:fvm/fvm.dart';
66
import 'package:i18next/i18next.dart';
7-
import 'package:state_notifier/state_notifier.dart';
87

98
import '../../modules/common/dto/release.dto.dart';
109
import '../../modules/common/utils/notify.dart';

lib/src/modules/navigation/navigation.provider.dart

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:hooks_riverpod/hooks_riverpod.dart';
2-
import 'package:state_notifier/state_notifier.dart';
32

43
enum NavigationRoutes {
54
homeScreen,

lib/src/modules/projects/projects.provider.dart

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import 'package:fvm/fvm.dart';
1414
import 'package:hooks_riverpod/hooks_riverpod.dart';
1515
import 'package:i18next/i18next.dart';
1616

17-
import 'package:state_notifier/state_notifier.dart';
1817

1918
import '../../modules/common/utils/notify.dart';
2019
import '../settings/settings.service.dart';

lib/src/theme.dart

+45-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:io';
22

33
import 'package:flutter/material.dart';
4+
import 'package:flutter_acrylic/flutter_acrylic.dart';
45
import 'package:google_fonts/google_fonts.dart';
56

67
ThemeData get darkPurpleTheme {
@@ -129,12 +130,54 @@ RoundedRectangleBorder get _roundedShape {
129130
);
130131
}
131132

133+
bool isNumeric(String s) {
134+
if (s == null) {
135+
return false;
136+
}
137+
return double.tryParse(s) != null;
138+
}
139+
140+
double getWindowsBuild() {
141+
final osVer =
142+
Platform.operatingSystemVersion.replaceAll(RegExp(r'[^\w\s\.]+'), '');
143+
144+
final splitOsVer = osVer.split(' ');
145+
146+
final nums = splitOsVer.where((element) => isNumeric(element)).toList();
147+
return double.parse(nums.last);
148+
}
149+
132150
Color platformBackgroundColor(BuildContext context) {
133151
final themeBrightness = Theme.of(context).brightness;
134152
final platformBrightness = MediaQuery.of(context).platformBrightness;
135153
final brightnessMatches = themeBrightness == platformBrightness;
136-
if (Platform.isMacOS && brightnessMatches) {
137-
return Colors.transparent;
154+
155+
// Brightness matches doesn't work on Windows 10
156+
if (brightnessMatches) {
157+
if (Platform.isMacOS) {
158+
return Colors.transparent;
159+
}
160+
if (Platform.isWindows) {
161+
if (getWindowsBuild() >= 22000) {
162+
print('Windows 11');
163+
Window.setEffect(
164+
effect: WindowEffect.acrylic,
165+
color: Theme.of(context).cardColor.withAlpha(0),
166+
dark: false);
167+
return Colors.transparent;
168+
} else if (getWindowsBuild() >= 10240) {
169+
// Acrylic causes issues on W10
170+
print('Windows 10');
171+
Window.setEffect(
172+
effect: WindowEffect.aero,
173+
color: Theme.of(context).cardColor.withAlpha(200),
174+
);
175+
return Colors.transparent;
176+
}
177+
return Theme.of(context).cardColor;
178+
} else {
179+
return Theme.of(context).cardColor;
180+
}
138181
} else {
139182
return Theme.of(context).cardColor;
140183
}

lib/src/windowBorder.dart

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import 'package:bitsdojo_window/bitsdojo_window.dart';
2+
import 'package:flutter/material.dart';
3+
4+
const sidebarColor = Color(0xFFF6A00C);
5+
6+
class LeftSide extends StatelessWidget {
7+
@override
8+
Widget build(BuildContext context) {
9+
return SizedBox(
10+
width: 200,
11+
child: Container(
12+
color: sidebarColor,
13+
child: Column(
14+
children: [
15+
WindowTitleBarBox(child: MoveWindow()),
16+
Expanded(child: Container())
17+
],
18+
)));
19+
}
20+
}
21+
22+
const backgroundStartColor = Color(0xFFFFD500);
23+
const backgroundEndColor = Color(0xFFF6A00C);
24+
25+
class RightSide extends StatelessWidget {
26+
@override
27+
Widget build(BuildContext context) {
28+
return Expanded(
29+
child: Container(
30+
decoration: BoxDecoration(
31+
gradient: LinearGradient(
32+
begin: Alignment.topCenter,
33+
end: Alignment.bottomCenter,
34+
colors: [backgroundStartColor, backgroundEndColor],
35+
stops: [0.0, 1.0]),
36+
),
37+
child: Column(children: [
38+
WindowTitleBarBox(
39+
child: Row(children: [
40+
Expanded(child: MoveWindow()),
41+
WindowButtons()
42+
])),
43+
])));
44+
}
45+
}
46+
47+
class WindowButtons extends StatelessWidget {
48+
@override
49+
Widget build(BuildContext context) {
50+
final buttonColors = WindowButtonColors(
51+
iconNormal: Theme.of(context).brightness == Brightness.dark
52+
? Colors.white
53+
: Colors.black,
54+
mouseOver: Theme.of(context).brightness == Brightness.dark
55+
? Colors.grey.shade600
56+
: Colors.grey.shade300,
57+
mouseDown: Theme.of(context).brightness == Brightness.dark
58+
? Colors.grey.shade700
59+
: Colors.grey.shade400,
60+
iconMouseOver: Theme.of(context).brightness == Brightness.dark
61+
? Colors.white
62+
: Colors.black,
63+
iconMouseDown: Theme.of(context).brightness == Brightness.dark
64+
? Colors.white
65+
: Colors.black);
66+
67+
final closeButtonColors = WindowButtonColors(
68+
mouseOver: Color(0xFFD32F2F),
69+
mouseDown: Color(0xFFB71C1C),
70+
iconNormal: Theme.of(context).brightness == Brightness.dark
71+
? Colors.white
72+
: Colors.black,
73+
iconMouseOver: Colors.white);
74+
return Row(
75+
children: [
76+
MinimizeWindowButton(colors: buttonColors),
77+
MaximizeWindowButton(colors: buttonColors),
78+
CloseWindowButton(colors: closeButtonColors),
79+
],
80+
);
81+
}
82+
}

linux/flutter/generated_plugin_registrant.cc

+8
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,22 @@
66

77
#include "generated_plugin_registrant.h"
88

9+
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
910
#include <file_selector_linux/file_selector_plugin.h>
11+
#include <flutter_acrylic/flutter_acrylic_plugin.h>
1012
#include <url_launcher_linux/url_launcher_plugin.h>
1113
#include <window_size/window_size_plugin.h>
1214

1315
void fl_register_plugins(FlPluginRegistry* registry) {
16+
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
17+
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
18+
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
1419
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
1520
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
1621
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
22+
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
23+
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterAcrylicPlugin");
24+
flutter_acrylic_plugin_register_with_registrar(flutter_acrylic_registrar);
1725
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
1826
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
1927
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

linux/flutter/generated_plugins.cmake

+2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#
44

55
list(APPEND FLUTTER_PLUGIN_LIST
6+
bitsdojo_window_linux
67
file_selector_linux
8+
flutter_acrylic
79
url_launcher_linux
810
window_size
911
)

linux/my_application.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
2+
13
#include "my_application.h"
24

35
#include <flutter_linux/flutter_linux.h>
@@ -21,7 +23,10 @@ static void my_application_activate(GApplication *application)
2123
gtk_header_bar_set_title(header_bar, "Sidekick");
2224
gtk_header_bar_set_show_close_button(header_bar, TRUE);
2325
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
24-
gtk_window_set_default_size(window, 1280, 720);
26+
27+
auto bdw = bitsdojo_window_from(window);
28+
bdw->setCustomFrame(true);
29+
//gtk_window_set_default_size(window, 1280, 720);
2530
gtk_widget_show(GTK_WIDGET(window));
2631

2732
g_autoptr(FlDartProject) project = fl_dart_project_new();

macos/Flutter/GeneratedPluginRegistrant.swift

+2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import FlutterMacOS
66
import Foundation
77

8+
import bitsdojo_window_macos
89
import file_selector_macos
910
import path_provider_macos
1011
import shared_preferences_macos
1112
import url_launcher_macos
1213
import window_size
1314

1415
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
16+
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
1517
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
1618
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
1719
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

macos/Runner/MainFlutterWindow.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import Cocoa
22
import FlutterMacOS
3+
import bitsdojo_window_macos
34

4-
class MainFlutterWindow: NSWindow {
5+
class MainFlutterWindow: BitsdojoWindow {
6+
override func bitsdojo_window_configure() -> UInt {
7+
return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP
8+
}
59
override func awakeFromNib() {
610
let flutterViewController = FlutterViewController.init()
711
let windowFrame = self.frame

0 commit comments

Comments
 (0)