From 36c33a48adec8c98702cc84bcfb8fd220800a2f2 Mon Sep 17 00:00:00 2001 From: Lraty <46740834+lraty-li@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:14:32 +0800 Subject: [PATCH] migrate form bitsdojo_window to window_manager && add windows always on Top --- autoSave-cli/autoSaverSet.dart | 6 +- autoSave-cli/util.dart | 2 +- lib/MainUi/side_list_view.dart | 12 +- lib/MainUi/window_title_bar.dart | 140 +++++++++++------ lib/Repository/NewRepo/new_repo.dart | 142 +++++++++++------- lib/main.dart | 42 +++--- lib/main_page.dart | 102 ++++++++----- lib/providers/main_status.dart | 7 + lib/util/models.dart | 2 + lib/util/shortcut.dart | 4 +- pubspec.lock | 56 +++---- pubspec.yaml | 4 +- .../flutter/generated_plugin_registrant.cc | 9 +- windows/flutter/generated_plugins.cmake | 3 +- windows/runner/main.cpp | 4 +- 15 files changed, 318 insertions(+), 217 deletions(-) diff --git a/autoSave-cli/autoSaverSet.dart b/autoSave-cli/autoSaverSet.dart index 57f83ae..40e8588 100644 --- a/autoSave-cli/autoSaverSet.dart +++ b/autoSave-cli/autoSaverSet.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -96,7 +98,7 @@ class AutoSaveInstance { //TODO 文件夹操作会触发UI端更新 //TODO 确定最老备份? //清理自动保存,删除第一个(autoSaveIdNames最小为0) - final String oldestIdName = "${autoSaveIdNames[0]}"; + final String oldestIdName = autoSaveIdNames[0]; autoSaveIdNames.removeAt(0); try { Directory( @@ -141,7 +143,7 @@ class AutoSaveInstance { //库被删除 showError(e.toString()); //TODO 保留错误信息 - showError("出错了!,取消 ${repoName} 的自动保存"); + showError("出错了!,取消 $repoName 的自动保存"); timer.cancel(); } } diff --git a/autoSave-cli/util.dart b/autoSave-cli/util.dart index ac5e88d..86d2f67 100644 --- a/autoSave-cli/util.dart +++ b/autoSave-cli/util.dart @@ -1,4 +1,4 @@ -// ignore_for_file: avoid_print +// ignore_for_file: avoid_print, unnecessary_brace_in_string_interps import 'dart:convert'; import 'dart:io'; diff --git a/lib/MainUi/side_list_view.dart b/lib/MainUi/side_list_view.dart index beb9d72..19cc5ce 100644 --- a/lib/MainUi/side_list_view.dart +++ b/lib/MainUi/side_list_view.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -8,20 +7,15 @@ import 'package:visual_branching/util/common.dart'; import 'package:visual_branching/util/models.dart'; List loadJsonLeafs(String jsonFilePath) { + //load the autoSaves.json final List autoLeafKeys = List.from(json.decode(File(jsonFilePath).readAsStringSync())); return autoLeafKeys.map((e) => Leaf(ValueKey(e), "自动保存")).toList(); } -//TODO turn to stles -class SideListView extends StatefulWidget { +class SideListView extends StatelessWidget { const SideListView({Key? key}) : super(key: key); - @override - State createState() => _SideListViewState(); -} - -class _SideListViewState extends State { @override Widget build(BuildContext context) { return Consumer(builder: (context, provider, child) { @@ -127,9 +121,7 @@ class _SideListViewState extends State { } } -// class SideListView extends StatelessWidget {} -//todo impl ontap Widget _buildListView(SideList tapFrom, List theList, void Function(int leafIndex) onTapfunc) { Offset tapPosition; diff --git a/lib/MainUi/window_title_bar.dart b/lib/MainUi/window_title_bar.dart index 7000103..0d9a984 100644 --- a/lib/MainUi/window_title_bar.dart +++ b/lib/MainUi/window_title_bar.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; +import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:visual_branching/Repository/repository_menu.dart'; +import 'package:visual_branching/providers/main_status.dart'; import 'package:visual_branching/util/funcs.dart'; +import 'package:window_manager/window_manager.dart'; class WindowTitleBar extends StatelessWidget { final BuildContext pContext; @@ -10,52 +12,100 @@ class WindowTitleBar extends StatelessWidget { @override Widget build(BuildContext context) { - return WindowTitleBarBox( - child: Row( - children: [ - repoMenuBuilder(pContext), - ElevatedButton( - onPressed: () => { - confirmDialog(context, "设置", - "这是未完成版本,你可以点击确认前往github页面寻找更新\nhttps://github.com/lraty-li/VisualBranching") - .then((confirmed) { - if (confirmed == true) { - launchUrl(Uri.parse( - "https://github.com/lraty-li/VisualBranching")); - } - }) - }, - child: const Text("软件设置")), - Expanded(child: MoveWindow()), - const WindowButtons() - ], - ), - ); - } -} - -final buttonColors = WindowButtonColors( - iconNormal: const Color(0xFF000000), - mouseOver: const Color(0xFF2196F3), - mouseDown: const Color(0xFF88C7F9), - iconMouseOver: const Color(0xFFFFFFFF), - iconMouseDown: const Color(0xFF007ACC)); - -final closeButtonColors = WindowButtonColors( - iconNormal: const Color(0xFF000000), - mouseOver: const Color(0xFFD32F2F), - mouseDown: const Color(0xFFB71C1C), - iconMouseOver: Colors.white); - -class WindowButtons extends StatelessWidget { - const WindowButtons({Key? key}) : super(key: key); - @override - Widget build(BuildContext context) { + bool nowOnTop = Provider.of(context, listen: false).alwaysOnTop; return Row( children: [ - MinimizeWindowButton(colors: buttonColors), - MaximizeWindowButton(colors: buttonColors), - CloseWindowButton(colors: closeButtonColors), + repoMenuBuilder(pContext), + ElevatedButton( + onPressed: () => { + confirmDialog(context, "设置", + "这是未完成版本,你可以点击确认前往github页面寻找更新\nhttps://github.com/lraty-li/VisualBranching") + .then((confirmed) { + if (confirmed == true) { + launchUrl(Uri.parse( + "https://github.com/lraty-li/VisualBranching")); + } + }) + }, + child: const Text("软件设置")), + Expanded( + child: DragToMoveArea( + child: Container( + height: double.infinity, + child: Row( + children: [ + Container( + padding: const EdgeInsets.only(left: 16), + // child: DefaultTextStyle( + // style: TextStyle( + // color: widget.brightness == Brightness.light + // ? Colors.black.withOpacity(0.8956) + // : Colors.white, + // fontSize: 14, + // ), + // child: widget.title ?? Container(), + // ), + ), + ], + ), + ), + ), + ), + Builder( + builder: (BuildContext context) { + // bool nowOnTop = + // Provider.of(context, listen: false).alwaysOnTop; + + return IconButton( + icon: RotatedBox( + quarterTurns: nowOnTop ? 0 : 1, + child: nowOnTop + ? const Icon(Icons.push_pin_rounded) + : const Icon(Icons.push_pin_outlined)), + onPressed: () { + nowOnTop = !nowOnTop; + Provider.of(context, listen: false) + .setAlwaysOnTop(!nowOnTop); + (context as Element).markNeedsBuild(); + }); + }, + ), + WindowCaptionButton.minimize( + // brightness: widget.brightness, + onPressed: () async { + bool isMinimized = await windowManager.isMinimized(); + if (isMinimized) { + windowManager.restore(); + } else { + windowManager.minimize(); + } + }, + ), + FutureBuilder( + future: windowManager.isMaximized(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.data == true) { + return WindowCaptionButton.unmaximize( + // brightness: widget.brightness, + onPressed: () { + windowManager.unmaximize(); + }, + ); + } + return WindowCaptionButton.maximize( + // brightness: widget.brightness, + onPressed: () { + windowManager.maximize(); + }, + ); + }, + ), + WindowCaptionButton.close( + // brightness: widget.brightness, + onPressed: () { + windowManager.close(); + }, + ), ], ); } diff --git a/lib/Repository/NewRepo/new_repo.dart b/lib/Repository/NewRepo/new_repo.dart index db4cd39..cfb6f6e 100644 --- a/lib/Repository/NewRepo/new_repo.dart +++ b/lib/Repository/NewRepo/new_repo.dart @@ -3,77 +3,105 @@ import 'package:provider/provider.dart'; import 'package:visual_branching/Repository/NewRepo/file_chosing.dart'; import 'package:visual_branching/Repository/NewRepo/repo_config_model.dart'; import 'package:visual_branching/Repository/NewRepo/repo_options.dart'; +import 'package:visual_branching/providers/main_status.dart'; import 'package:visual_branching/util/common.dart'; import 'package:visual_branching/util/models.dart'; +import 'package:window_manager/window_manager.dart'; void newRepoDialog(BuildContext context) { // RepoConfig repoConfig = RepoConfig(); + bool oldOnTop = Provider.of(context, listen: false).alwaysOnTop; + windowManager.setAlwaysOnTop(true); showDialog( context: context, builder: (context) { - return ChangeNotifierProvider( - create: (context) => RepoConfig(targetFilePaths: []), - child: AlertDialog( - title: const Text("新建库"), - actions: [ - Consumer( - builder: (context, repoConfig, child) { - return ElevatedButton( - onPressed: repoConfig.validated - ? () async { - // Navigator.of(context).pop(); + return WillPopScope( + onWillPop: () { + windowManager.setAlwaysOnTop(oldOnTop); + Navigator.of(context).pop(); + return Future.value(false); + }, + child: ChangeNotifierProvider( + create: (context) => RepoConfig(targetFilePaths: []), + child: AlertDialog( + title: Row(children: [ + const Text("新建库"), + Expanded( + child: DragToMoveArea( + child: Container( + height: 27, + color: const Color(0xFFD8D6D6), + child: const Center( + child: Text("已自动置顶窗口,此处可拖动窗口"), + ), + ), + )) + ]), + actions: [ + Consumer( + builder: (context, repoConfig, child) { + return ElevatedButton( + onPressed: repoConfig.validated + ? () async { + // Navigator.of(context).pop(); + //创建repo对象 + Repo theCreatorRepo = await Repo.newRepo( + repoConfig.repoName, + repoConfig.autoSave, + repoConfig.targetFilePaths, + repoConfig.autoSaveInterval, + repoConfig.autoSavesNums, + ); - //创建repo对象 - Repo theCreatorRepo = await Repo.newRepo( - repoConfig.repoName, - repoConfig.autoSave, - repoConfig.targetFilePaths, - repoConfig.autoSaveInterval, - repoConfig.autoSavesNums, - ); + //创建一个手动备份作为新树根节点,并将会被设置为标头 + await theCreatorRepo.newLeaf( + NodeType.manually, + "这是一个自动创建的手动备份", + false); - //创建一个手动备份作为新树根节点,并将会被设置为标头 - await theCreatorRepo.newLeaf( - NodeType.manually, "这是一个自动创建的手动备份",false); + if (repoConfig.autoSave) { + //创建第一个自动备份 - if (repoConfig.autoSave) { - //创建第一个自动备份 + } + windowManager.setAlwaysOnTop(oldOnTop); + Navigator.of(context).pop(); } - - Navigator.of(context).pop(); - } - : null, - child: const Text("确认"), - ); - }, - ), - ElevatedButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: const Text("取消"), - ), - ], - content: SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - height: MediaQuery.of(context).size.height * 0.5, - child: Flex( - direction: Axis.horizontal, - children: [ - Consumer( - builder: (context, repoConfig, child) => Expanded( - flex: 1, - child: RepoOptions(configHandle: repoConfig), - )), - Consumer( - builder: (context, repoConfig, child) => Expanded( - flex: 2, - child: FileChosing(configHandle: repoConfig), - )), - ], - )))); + : null, + child: const Text("确认"), + ); + }, + ), + ElevatedButton( + onPressed: () { + windowManager.setAlwaysOnTop(oldOnTop); + Navigator.of(context).pop(); + }, + child: const Text("取消"), + ), + ], + content: SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + height: MediaQuery.of(context).size.height * 0.5, + child: Flex( + direction: Axis.horizontal, + children: [ + Consumer( + builder: (context, repoConfig, child) => Expanded( + flex: 1, + child: + RepoOptions(configHandle: repoConfig), + )), + Consumer( + builder: (context, repoConfig, child) => Expanded( + flex: 2, + child: + FileChosing(configHandle: repoConfig), + )), + ], + )))), + ); }); } diff --git a/lib/main.dart b/lib/main.dart index 143cf30..e215a9e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,18 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; -import 'package:flutter/services.dart'; -import 'package:provider/provider.dart'; -import 'package:visual_branching/providers/main_status.dart'; -import 'package:visual_branching/util/shortcut.dart'; +// import 'package:flutter/services.dart'; +import 'package:window_manager/window_manager.dart'; +// import 'package:visual_branching/util/shortcut.dart'; import 'main_page.dart'; -void main() { - runApp(MultiProvider( - providers: [ - ListenableProvider(create: (context) => MainStatus()) - ], - child: /*Shortcuts( +Future main() async { + /*Shortcuts( //avoid “show desktop" event //取消,与切换输入法冲突 , 无法先于系统收起. shortcuts: { @@ -24,14 +18,22 @@ void main() { ShowDesktopIntent: HideAction(), }, child: const MyApp()))));*/ - const MyApp())); - doWhenWindowReady(() { - final win = appWindow; - const initialSize = Size(1280, 720); - win.minSize = const Size(640, 640); - win.size = initialSize; - win.alignment = Alignment.center; - win.title = "Visual Branching"; - win.show(); + + WidgetsFlutterBinding.ensureInitialized(); + // 必须加上这一行。 + await windowManager.ensureInitialized(); + + WindowOptions windowOptions = const WindowOptions( + size: Size(800, 600), + center: true, + backgroundColor: Colors.transparent, + skipTaskbar: false, + titleBarStyle: TitleBarStyle.hidden, + ); + windowManager.waitUntilReadyToShow(windowOptions, () async { + await windowManager.show(); + await windowManager.focus(); }); + + runApp(const MyApp()); } diff --git a/lib/main_page.dart b/lib/main_page.dart index 651672e..2e292b5 100644 --- a/lib/main_page.dart +++ b/lib/main_page.dart @@ -1,24 +1,44 @@ +import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:visual_branching/MainUi/side_list_view.dart'; import 'package:visual_branching/TreeViewer/view.dart'; import 'package:visual_branching/providers/main_status.dart'; +import 'package:window_manager/window_manager.dart'; import 'MainUi/ctl_btn.dart'; import 'MainUi/window_title_bar.dart'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; - -class MyApp extends StatelessWidget { +class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { - return const MaterialApp( - debugShowCheckedModeBanner: false, - home: Scaffold( - body: HomePage(), - ), - ); + final virtualWindowFrameBuilder = VirtualWindowFrameInit(); + final botToastBuilder = BotToastInit(); + + return MultiProvider( + providers: [ + ListenableProvider(create: (context) => MainStatus()) + ], + child: MaterialApp( + debugShowCheckedModeBanner: false, + builder: (context, child) { + child = virtualWindowFrameBuilder(context, child); + child = botToastBuilder(context, child); + return child; + }, + navigatorObservers: [BotToastNavigatorObserver()], + home: const HomePage())); } } @@ -27,37 +47,43 @@ class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( - children: [ - WindowTitleBar( + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(kToolbarHeight), + child: WindowTitleBar( pContext: context, ), - SizedBox( - height: MediaQuery.of(context).size.height - appWindow.titleBarHeight, - width: MediaQuery.of(context).size.width, - child: Consumer( - builder: (context, provider, child) => - provider.openedRepoList.isEmpty - //未开启任何repo时 - ? _fakeTreeWindow() - : Flex( - direction: Axis.horizontal, - children: [ - const Expanded(flex: 5, child: TreeView()), - Expanded( - flex: 1, - child: Flex( - direction: Axis.vertical, - children: const [ - Expanded(child: SideListView()), - CtlBtn() - ], - )) - ], - ), - ), - ) - ], + ), + body: Column( + children: [ + SizedBox( + height: MediaQuery.of(context).size.height - + kToolbarHeight /* - windowManager.getTitleBarHeight()*/, + width: MediaQuery.of(context).size.width, + child: Consumer( + builder: (context, provider, child) => + provider.openedRepoList.isEmpty + //未开启任何repo时 + ? _fakeTreeWindow() + : Flex( + direction: Axis.horizontal, + children: [ + const Expanded(flex: 5, child: TreeView()), + Expanded( + flex: 1, + child: Flex( + direction: Axis.vertical, + children: const [ + Expanded(child: SideListView()), + CtlBtn() + ], + )) + ], + ), + ), + ) + ], + ), ); } } diff --git a/lib/providers/main_status.dart b/lib/providers/main_status.dart index a3f8062..8e20232 100644 --- a/lib/providers/main_status.dart +++ b/lib/providers/main_status.dart @@ -3,12 +3,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:graphview/GraphView.dart'; import 'package:visual_branching/util/models.dart'; +import 'package:window_manager/window_manager.dart'; class MainStatus extends ChangeNotifier { //opened repo, but only one repo supported now , maybe muti repo will be support List openedRepoList = []; List graphs = []; List focusedNode = []; + bool alwaysOnTop = false; updateVoidCall() { //TODO 单个repo调用时导致全部更新(虽然目前不支持打开多个repo) @@ -44,4 +46,9 @@ class MainStatus extends ChangeNotifier { focusedNode.first = key; notifyListeners(); } + + setAlwaysOnTop(bool value) { + alwaysOnTop = value; + windowManager.setAlwaysOnTop(value); + } } diff --git a/lib/util/models.dart b/lib/util/models.dart index c5d99e3..38bfb4a 100644 --- a/lib/util/models.dart +++ b/lib/util/models.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:convert'; import 'dart:io'; import 'dart:math'; diff --git a/lib/util/shortcut.dart b/lib/util/shortcut.dart index e167215..35fbe1d 100644 --- a/lib/util/shortcut.dart +++ b/lib/util/shortcut.dart @@ -1,4 +1,4 @@ -import 'package:bitsdojo_window/bitsdojo_window.dart'; +// import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:flutter/widgets.dart'; class ShowDesktopIntent extends Intent { @@ -9,7 +9,7 @@ class HideAction extends Action { HideAction(); @override Object? invoke(covariant ShowDesktopIntent intent) { - appWindow.minimize(); + // appWindow.minimize(); return null; } } diff --git a/pubspec.lock b/pubspec.lock index 6ce65a2..5de6dad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -8,41 +8,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.8.2" - bitsdojo_window: - dependency: "direct main" - description: - name: bitsdojo_window - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.2" - bitsdojo_window_linux: - dependency: transitive - description: - name: bitsdojo_window_linux - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.2" - bitsdojo_window_macos: - dependency: transitive - description: - name: bitsdojo_window_macos - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.2" - bitsdojo_window_platform_interface: - dependency: transitive - description: - name: bitsdojo_window_platform_interface - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.2" - bitsdojo_window_windows: - dependency: transitive - description: - name: bitsdojo_window_windows - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.2" boolean_selector: dependency: transitive description: @@ -50,6 +15,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0" + bot_toast: + dependency: "direct main" + description: + name: bot_toast + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.2" characters: dependency: transitive description: @@ -219,6 +191,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.0.3" + screen_retriever: + dependency: transitive + description: + name: screen_retriever + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.2" sky_engine: dependency: transitive description: flutter @@ -336,6 +315,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.6.1" + window_manager: + dependency: "direct main" + description: + name: window_manager + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.5" sdks: dart: ">=2.17.0 <3.0.0" flutter: ">=2.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index 91cc302..162187a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,7 +30,9 @@ dependencies: flutter: sdk: flutter - bitsdojo_window: ^0.1.1+1 + # bitsdojo_window: ^0.1.1+1 + bot_toast: ^4.0.0 #null safety + window_manager: ^0.2.5 provider: ^6.0.2 file_picker: ^4.5.1 cupertino_icons: ^1.0.2 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index cf09cb8..d35fb0a 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,15 +6,18 @@ #include "generated_plugin_registrant.h" -#include #include +#include #include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { - BitsdojoWindowPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); DesktopDropPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("DesktopDropPlugin")); + ScreenRetrieverPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); + WindowManagerPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("WindowManagerPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 4186aeb..0d6d49e 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,9 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST - bitsdojo_window_windows desktop_drop + screen_retriever url_launcher_windows + window_manager ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index 2b81462..b1db2f5 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -1,5 +1,5 @@ -#include -auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); +// #include +// auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); #include #include