diff --git a/.gitignore b/.gitignore index 8041fae..ba7e82d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store .dart_tool/ +.idea/ .packages .pub/ diff --git a/bitsdojo_window/lib/src/widgets/window_button.dart b/bitsdojo_window/lib/src/widgets/window_button.dart index 11cc43f..977d19e 100644 --- a/bitsdojo_window/lib/src/widgets/window_button.dart +++ b/bitsdojo_window/lib/src/widgets/window_button.dart @@ -1,26 +1,21 @@ +import 'dart:io' show Platform; + +import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; -import './mouse_state_builder.dart'; -import '../icons/icons.dart'; import '../app_window.dart'; -import 'package:flutter/foundation.dart' show kIsWeb; -import 'dart:io' show Platform; +import '../icons/icons.dart'; +import './mouse_state_builder.dart'; -typedef WindowButtonIconBuilder = Widget Function( - WindowButtonContext buttonContext); -typedef WindowButtonBuilder = Widget Function( - WindowButtonContext buttonContext, Widget icon); +typedef WindowButtonIconBuilder = Widget Function(WindowButtonContext buttonContext); +typedef WindowButtonBuilder = Widget Function(WindowButtonContext buttonContext, Widget icon); class WindowButtonContext { BuildContext context; MouseState mouseState; Color? backgroundColor; Color iconColor; - WindowButtonContext( - {required this.context, - required this.mouseState, - this.backgroundColor, - required this.iconColor}); + WindowButtonContext({required this.context, required this.mouseState, this.backgroundColor, required this.iconColor}); } class WindowButtonColors { @@ -66,7 +61,7 @@ class WindowButton extends StatelessWidget { {Key? key, WindowButtonColors? colors, this.builder, - @required this.iconBuilder, + required this.iconBuilder, this.padding, this.onPressed, this.animate = false}) @@ -105,29 +100,21 @@ class WindowButton extends StatelessWidget { backgroundColor: getBackgroundColor(mouseState), iconColor: getIconColor(mouseState)); - var icon = (this.iconBuilder != null) - ? this.iconBuilder!(buttonContext) - : Container(); + var icon = (this.iconBuilder != null) ? this.iconBuilder!(buttonContext) : Container(); double borderSize = appWindow.borderSize; - double defaultPadding = - (appWindow.titleBarHeight - borderSize) / 3 - (borderSize / 2); + double defaultPadding = (appWindow.titleBarHeight - borderSize) / 3 - (borderSize / 2); // Used when buttonContext.backgroundColor is null, allowing the AnimatedContainer to fade-out smoothly. - var fadeOutColor = - getBackgroundColor(MouseState()..isMouseOver = true).withOpacity(0); + var fadeOutColor = getBackgroundColor(MouseState()..isMouseOver = true).withValues(alpha: 0); var padding = this.padding ?? EdgeInsets.all(defaultPadding); - var animationMs = - mouseState.isMouseOver ? (animate ? 100 : 0) : (animate ? 200 : 0); + var animationMs = mouseState.isMouseOver ? (animate ? 100 : 0) : (animate ? 200 : 0); Widget iconWithPadding = Padding(padding: padding, child: icon); iconWithPadding = AnimatedContainer( curve: Curves.easeOut, duration: Duration(milliseconds: animationMs), color: buttonContext.backgroundColor ?? fadeOutColor, child: iconWithPadding); - var button = (this.builder != null) - ? this.builder!(buttonContext, icon) - : iconWithPadding; - return SizedBox( - width: buttonSize.width, height: buttonSize.height, child: button); + var button = (this.builder != null) ? this.builder!(buttonContext, icon) : iconWithPadding; + return SizedBox(width: buttonSize.width, height: buttonSize.height, child: button); }, onPressed: () { if (this.onPressed != null) this.onPressed!(); @@ -137,47 +124,32 @@ class WindowButton extends StatelessWidget { } class MinimizeWindowButton extends WindowButton { - MinimizeWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) + MinimizeWindowButton({Key? key, WindowButtonColors? colors, VoidCallback? onPressed, bool? animate}) : super( key: key, colors: colors, animate: animate ?? false, - iconBuilder: (buttonContext) => - MinimizeIcon(color: buttonContext.iconColor), + iconBuilder: (buttonContext) => MinimizeIcon(color: buttonContext.iconColor), onPressed: onPressed ?? () => appWindow.minimize()); } class MaximizeWindowButton extends WindowButton { - MaximizeWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) + MaximizeWindowButton({Key? key, WindowButtonColors? colors, VoidCallback? onPressed, bool? animate}) : super( key: key, colors: colors, animate: animate ?? false, - iconBuilder: (buttonContext) => - MaximizeIcon(color: buttonContext.iconColor), + iconBuilder: (buttonContext) => MaximizeIcon(color: buttonContext.iconColor), onPressed: onPressed ?? () => appWindow.maximizeOrRestore()); } class RestoreWindowButton extends WindowButton { - RestoreWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) + RestoreWindowButton({Key? key, WindowButtonColors? colors, VoidCallback? onPressed, bool? animate}) : super( key: key, colors: colors, animate: animate ?? false, - iconBuilder: (buttonContext) => - RestoreIcon(color: buttonContext.iconColor), + iconBuilder: (buttonContext) => RestoreIcon(color: buttonContext.iconColor), onPressed: onPressed ?? () => appWindow.maximizeOrRestore()); } @@ -188,16 +160,11 @@ final _defaultCloseButtonColors = WindowButtonColors( iconMouseOver: Color(0xFFFFFFFF)); class CloseWindowButton extends WindowButton { - CloseWindowButton( - {Key? key, - WindowButtonColors? colors, - VoidCallback? onPressed, - bool? animate}) + CloseWindowButton({Key? key, WindowButtonColors? colors, VoidCallback? onPressed, bool? animate}) : super( key: key, colors: colors ?? _defaultCloseButtonColors, animate: animate ?? false, - iconBuilder: (buttonContext) => - CloseIcon(color: buttonContext.iconColor), + iconBuilder: (buttonContext) => CloseIcon(color: buttonContext.iconColor), onPressed: onPressed ?? () => appWindow.close()); } diff --git a/bitsdojo_window/pubspec.yaml b/bitsdojo_window/pubspec.yaml index 656675f..ce1d040 100644 --- a/bitsdojo_window/pubspec.yaml +++ b/bitsdojo_window/pubspec.yaml @@ -1,12 +1,12 @@ name: bitsdojo_window description: A package to help with creating custom windows with Flutter desktop (custom border, titlebar and minimize/maximize/close buttons) and common desktop window operations (show/hide/position on screen) for Windows and macOS -version: 0.1.6 +version: 1.0.0 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=1.20.0" + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.41.0" flutter: plugin: diff --git a/bitsdojo_window_linux/lib/src/native_api.dart b/bitsdojo_window_linux/lib/src/native_api.dart index fde6db9..0bbdb2c 100644 --- a/bitsdojo_window_linux/lib/src/native_api.dart +++ b/bitsdojo_window_linux/lib/src/native_api.dart @@ -1,6 +1,7 @@ library bitsdojo_window_linux; import 'dart:ffi'; + import 'package:ffi/ffi.dart'; final DynamicLibrary _appExecutable = DynamicLibrary.executable(); @@ -8,14 +9,13 @@ final DynamicLibrary _appExecutable = DynamicLibrary.executable(); // getAppWindowHandle typedef IntPtr TGetAppWindowHandle(); typedef DGetAppWindowHandle = int Function(); -final DGetAppWindowHandle getAppWindowHandle = - _theAPI.ref.getAppWindowHandle.asFunction(); +final DGetAppWindowHandle getAppWindowHandle = _theAPI.ref.getAppWindowHandle.asFunction(); // getScreenRect -typedef Void TGetScreenRect(IntPtr window, Pointer x, Pointer y, - Pointer width, Pointer height); -typedef DGetScreenRect = void Function(int window, Pointer x, - Pointer y, Pointer width, Pointer height); +typedef Void TGetScreenRect( + IntPtr window, Pointer x, Pointer y, Pointer width, Pointer height); +typedef DGetScreenRect = void Function( + int window, Pointer x, Pointer y, Pointer width, Pointer height); final DGetScreenRect getScreenRect = _theAPI.ref.getScreenRect.asFunction(); // getScaleFactor @@ -25,8 +25,7 @@ final DGetScaleFactor getScaleFactor = _theAPI.ref.getScaleFactor.asFunction(); // getPosition typedef Void TGetPosition(IntPtr window, Pointer x, Pointer y); -typedef DGetPosition = void Function( - int window, Pointer x, Pointer y); +typedef DGetPosition = void Function(int window, Pointer x, Pointer y); final DGetPosition getPosition = _theAPI.ref.getPosition.asFunction(); // setPosition @@ -35,10 +34,8 @@ typedef DSetPosition = void Function(int window, int x, int y); final DSetPosition setPosition = _theAPI.ref.setPosition.asFunction(); // getSize -typedef Void TGetSize( - IntPtr window, Pointer width, Pointer height); -typedef DGetSize = void Function( - int window, Pointer width, Pointer height); +typedef Void TGetSize(IntPtr window, Pointer width, Pointer height); +typedef DGetSize = void Function(int window, Pointer width, Pointer height); final DGetSize getSize = _theAPI.ref.getSize.asFunction(); // setSize @@ -46,10 +43,8 @@ typedef Void TSetSize(IntPtr window, Int32 width, Int32 height); typedef DSetSize = void Function(int window, int width, int height); final DSetSize setSize = _theAPI.ref.setSize.asFunction(); // setRect -typedef Void TSetRect( - IntPtr window, Int32 x, Int32 y, Int32 width, Int32 height); -typedef DSetRect = void Function( - int window, int x, int y, int width, int height); +typedef Void TSetRect(IntPtr window, Int32 x, Int32 y, Int32 width, Int32 height); +typedef DSetRect = void Function(int window, int x, int y, int width, int height); final DSetRect setRect = _theAPI.ref.setRect.asFunction(); // setMinSize @@ -85,15 +80,14 @@ final DMaximizeWindow maximizeWindow = _theAPI.ref.maximizeWindow.asFunction(); // unmaximizeWindow typedef Void TUnmaximizeWindow(IntPtr window); typedef DUnmaximizeWindow = void Function(int window); -final DMaximizeWindow unmaximizeWindow = - _theAPI.ref.unmaximizeWindow.asFunction(); +final DMaximizeWindow unmaximizeWindow = _theAPI.ref.unmaximizeWindow.asFunction(); // setWindowTitle typedef Void TSetWindowTitle(IntPtr window, Pointer title); typedef DSetWindowTitle = void Function(int window, Pointer title); final DSetWindowTitle setWindowTitle = _theAPI.ref.setWindowTitle.asFunction(); -class BDWAPI extends Struct { +base class BDWAPI extends Struct { external Pointer> getAppWindowHandle; external Pointer> getScreenRect; external Pointer> getScaleFactor; @@ -114,8 +108,7 @@ class BDWAPI extends Struct { typedef Pointer TBitsdojoWindowAPI(); -final TBitsdojoWindowAPI bitsdojoWindowAPI = _appExecutable - .lookup>("bitsdojo_window_api") - .asFunction(); +final TBitsdojoWindowAPI bitsdojoWindowAPI = + _appExecutable.lookup>("bitsdojo_window_api").asFunction(); final Pointer _theAPI = bitsdojoWindowAPI(); diff --git a/bitsdojo_window_linux/lib/src/window.dart b/bitsdojo_window_linux/lib/src/window.dart index 7d5c63d..fc08375 100644 --- a/bitsdojo_window_linux/lib/src/window.dart +++ b/bitsdojo_window_linux/lib/src/window.dart @@ -1,11 +1,11 @@ import 'dart:ffi' hide Size; -import 'package:flutter/painting.dart'; +import 'package:bitsdojo_window_platform_interface/bitsdojo_window_platform_interface.dart'; import 'package:ffi/ffi.dart'; +import 'package:flutter/painting.dart'; -import './native_api.dart' as native; import './gtk.dart'; -import 'package:bitsdojo_window_platform_interface/bitsdojo_window_platform_interface.dart'; +import './native_api.dart' as native; var isInsideDoWhenWindowReady = false; @@ -23,10 +23,9 @@ class CachedWindowInfo { Rect getScreenRectForWindow(int handle) { Pointer gtkRect = malloc.allocate(sizeOf() * 4); - native.getScreenRect(handle, gtkRect.elementAt(0), gtkRect.elementAt(1), - gtkRect.elementAt(2), gtkRect.elementAt(3)); - Rect result = Rect.fromLTWH(gtkRect[0].toDouble(), gtkRect[1].toDouble(), - gtkRect[2].toDouble(), gtkRect[3].toDouble()); + native.getScreenRect(handle, gtkRect + 0, gtkRect + 1, gtkRect + 2, gtkRect + 3); + Rect result = + Rect.fromLTWH(gtkRect[0].toDouble(), gtkRect[1].toDouble(), gtkRect[2].toDouble(), gtkRect[3].toDouble()); malloc.free(gtkRect); return result; @@ -70,10 +69,10 @@ class GtkWindow extends DesktopWindow { } Pointer gtkRect = malloc.allocate(sizeOf() * 4); - native.getPosition(handle!, gtkRect.elementAt(0), gtkRect.elementAt(1)); - native.getSize(handle!, gtkRect.elementAt(2), gtkRect.elementAt(3)); - Rect result = Rect.fromLTWH(gtkRect[0].toDouble(), gtkRect[1].toDouble(), - gtkRect[2].toDouble(), gtkRect[3].toDouble()); + native.getPosition(handle!, gtkRect + 0, gtkRect + 1); + native.getSize(handle!, gtkRect + 2, gtkRect + 3); + Rect result = + Rect.fromLTWH(gtkRect[0].toDouble(), gtkRect[1].toDouble(), gtkRect[2].toDouble(), gtkRect[3].toDouble()); malloc.free(gtkRect); return result; @@ -83,8 +82,7 @@ class GtkWindow extends DesktopWindow { set rect(Rect newRect) { if (!isValidHandle(handle, "set rectangle")) return; _cached.rect = newRect; - native.setRect(handle!, newRect.left.toInt(), newRect.top.toInt(), - newRect.width.toInt(), newRect.height.toInt()); + native.setRect(handle!, newRect.left.toInt(), newRect.top.toInt(), newRect.width.toInt(), newRect.height.toInt()); } @override @@ -96,8 +94,7 @@ class GtkWindow extends DesktopWindow { } Pointer nativeResult = malloc.allocate(sizeOf() * 2); - native.getSize( - handle!, nativeResult.elementAt(0), nativeResult.elementAt(1)); + native.getSize(handle!, nativeResult + 0, nativeResult + 1); Size result = Size(nativeResult[0].toDouble(), nativeResult[1].toDouble()); malloc.free(nativeResult); final gotSize = getLogicalSize(result); @@ -126,7 +123,7 @@ class GtkWindow extends DesktopWindow { double get scaleFactor { if (!isValidHandle(handle, "get scaleFactor")) return 1; Pointer scaleFactorPtr = malloc.allocate(sizeOf()); - native.getScaleFactor(handle!, scaleFactorPtr.elementAt(0)); + native.getScaleFactor(handle!, scaleFactorPtr + 1); double result = scaleFactorPtr[0].toDouble(); malloc.free(scaleFactorPtr); return result; @@ -183,8 +180,7 @@ class GtkWindow extends DesktopWindow { //TODO - add handling for setting minSize to null return; } - native.setMinSize( - handle!, _minSize!.width.toInt(), _minSize!.height.toInt()); + native.setMinSize(handle!, _minSize!.width.toInt(), _minSize!.height.toInt()); } @override @@ -196,8 +192,7 @@ class GtkWindow extends DesktopWindow { //TODO - add handling for setting maxSize to null return; } - native.setMaxSize( - handle!, _maxSize!.width.toInt(), _maxSize!.height.toInt()); + native.setMaxSize(handle!, _maxSize!.width.toInt(), _maxSize!.height.toInt()); } @override @@ -232,8 +227,7 @@ class GtkWindow extends DesktopWindow { _cached.rect = Rect.fromLTWH(left, top, width, height); if (_alignment == null) { - native.setSize( - handle!, sizeToSet.width.toInt(), sizeToSet.height.toInt()); + native.setSize(handle!, sizeToSet.width.toInt(), sizeToSet.height.toInt()); //native.setWindowSize(handle!, sizeToSet); } else { final sizeOnScreen = getSizeOnScreen((sizeToSet)); diff --git a/bitsdojo_window_linux/pubspec.yaml b/bitsdojo_window_linux/pubspec.yaml index d9bcf55..b984878 100644 --- a/bitsdojo_window_linux/pubspec.yaml +++ b/bitsdojo_window_linux/pubspec.yaml @@ -1,12 +1,12 @@ name: bitsdojo_window_linux description: Linux implementation of the bitsdojo_window plugin. -version: 0.1.4 +version: 1.0.0 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=1.20.0" + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.41.0" dependencies: flutter: @@ -14,7 +14,7 @@ dependencies: bitsdojo_window_platform_interface: ^0.1.2 #path: ../bitsdojo_window_platform_interface - ffi: ^2.0.0 + ffi: ^2.2.0 dev_dependencies: flutter_test: diff --git a/bitsdojo_window_macos/lib/src/native_api.dart b/bitsdojo_window_macos/lib/src/native_api.dart index fcde13b..430638b 100644 --- a/bitsdojo_window_macos/lib/src/native_api.dart +++ b/bitsdojo_window_macos/lib/src/native_api.dart @@ -2,7 +2,9 @@ library bitsdojo_window_macos; import 'dart:ffi'; import 'dart:ui'; + import 'package:ffi/ffi.dart'; + import './native_struct.dart'; final DynamicLibrary _appExecutable = DynamicLibrary.executable(); @@ -23,17 +25,14 @@ final DGetAppWindow getAppWindow = _publicAPI.ref.getAppWindow.asFunction(); // setWindowCanBeShown typedef Void TSetWindowCanBeShown(Int8 value); typedef DSetWindowCanBeShown = void Function(int value); -final DSetWindowCanBeShown _setWindowCanBeShown = - _publicAPI.ref.setWindowCanBeShown.asFunction(); +final DSetWindowCanBeShown _setWindowCanBeShown = _publicAPI.ref.setWindowCanBeShown.asFunction(); void setWindowCanBeShown(bool value) => _setWindowCanBeShown(value ? 1 : 0); // setInsideDoWhenWindowReady typedef Void TSetInsideDoWhenWindowReady(Int8 value); typedef DSetInsideDoWhenWindowReady = void Function(int value); -final DSetInsideDoWhenWindowReady _setInsideDoWhenWindowReady = - _publicAPI.ref.setInsideDoWhenWindowReady.asFunction(); -void setInsideDoWhenWindowReady(bool value) => - _setInsideDoWhenWindowReady(value ? 1 : 0); +final DSetInsideDoWhenWindowReady _setInsideDoWhenWindowReady = _publicAPI.ref.setInsideDoWhenWindowReady.asFunction(); +void setInsideDoWhenWindowReady(bool value) => _setInsideDoWhenWindowReady(value ? 1 : 0); // showWindow typedef Void TShowWindow(IntPtr window); @@ -66,12 +65,9 @@ typedef DSetMaxSize = void Function(int window, int first, int second); final DSetMinSize setMaxSize = _publicAPI.ref.setMaxSize.asFunction(); // getScreenInfoForWindow -typedef Int8 TGetScreenInfoForWindow( - IntPtr window, Pointer screenInfo); -typedef DGetScreenInfoForWindow = int Function( - int window, Pointer screenInfo); -final DGetScreenInfoForWindow _getScreenInfoForWindow = - _publicAPI.ref.getScreenInfoForWindow.asFunction(); +typedef Int8 TGetScreenInfoForWindow(IntPtr window, Pointer screenInfo); +typedef DGetScreenInfoForWindow = int Function(int window, Pointer screenInfo); +final DGetScreenInfoForWindow _getScreenInfoForWindow = _publicAPI.ref.getScreenInfoForWindow.asFunction(); bool getScreenInfoNative(int window, Pointer screenInfo) { int result = _getScreenInfoForWindow(window, screenInfo); @@ -80,10 +76,8 @@ bool getScreenInfoNative(int window, Pointer screenInfo) { // setPositionForWindow typedef Int8 TSetPositionForWindow(IntPtr window, Pointer rect); -typedef DSetPositionForWindow = int Function( - int window, Pointer rect); -final DSetPositionForWindow setPositionForWindowNative = - _publicAPI.ref.setPositionForWindow.asFunction(); +typedef DSetPositionForWindow = int Function(int window, Pointer rect); +final DSetPositionForWindow setPositionForWindowNative = _publicAPI.ref.setPositionForWindow.asFunction(); bool setPositionForWindow(int window, Offset offset) { final Pointer offsetPointer = newBDWOffset(); @@ -97,48 +91,39 @@ bool setPositionForWindow(int window, Offset offset) { // setRectForWindow typedef Int8 TSetRectForWindow(IntPtr window, Pointer rect); typedef DSetRectForWindow = int Function(int window, Pointer rect); -final DSetRectForWindow setRectForWindowNative = - _publicAPI.ref.setRectForWindow.asFunction(); +final DSetRectForWindow setRectForWindowNative = _publicAPI.ref.setRectForWindow.asFunction(); // getRectForWindow typedef Int8 TGetRectForWindow(IntPtr window, Pointer rect); typedef DGetRectForWindow = int Function(int window, Pointer rect); -final DGetRectForWindow getRectForWindowNative = - _publicAPI.ref.getRectForWindow.asFunction(); +final DGetRectForWindow getRectForWindowNative = _publicAPI.ref.getRectForWindow.asFunction(); // isWindowVisibleπ typedef Int8 TIsWindowVisible(IntPtr window); typedef DIsWindowVisible = int Function(int window); -final DIsWindowVisible _isWindowVisible = - _publicAPI.ref.isWindowVisible.asFunction(); -bool isWindowVisible(int window) => - _isWindowVisible(window) == 1 ? true : false; +final DIsWindowVisible _isWindowVisible = _publicAPI.ref.isWindowVisible.asFunction(); +bool isWindowVisible(int window) => _isWindowVisible(window) == 1 ? true : false; // isWindowMaximized typedef Int8 TIsWindowMaximized(IntPtr window); typedef DIsWindowMaximized = int Function(int window); -final DIsWindowMaximized _isWindowMaximized = - _publicAPI.ref.isWindowMaximized.asFunction(); -bool isWindowMaximized(int window) => - _isWindowMaximized(window) == 1 ? true : false; +final DIsWindowMaximized _isWindowMaximized = _publicAPI.ref.isWindowMaximized.asFunction(); +bool isWindowMaximized(int window) => _isWindowMaximized(window) == 1 ? true : false; // maximizeWindow typedef Void TMaximizeOrRestoreWindow(IntPtr window); typedef DMaximizeOrRestoreWindow = void Function(int window); -final DMaximizeOrRestoreWindow maximizeOrRestoreWindow = - _publicAPI.ref.maximizeOrRestoreWindow.asFunction(); +final DMaximizeOrRestoreWindow maximizeOrRestoreWindow = _publicAPI.ref.maximizeOrRestoreWindow.asFunction(); // maximizeWindow typedef Void TMaximizeWindow(IntPtr window); typedef DMaximizeWindow = void Function(int window); -final DMaximizeWindow maximizeWindow = - _publicAPI.ref.maximizeWindow.asFunction(); +final DMaximizeWindow maximizeWindow = _publicAPI.ref.maximizeWindow.asFunction(); // maximizeWindow typedef Void TMinimizeWindow(IntPtr window); typedef DMinimizeWindow = void Function(int window); -final DMinimizeWindow minimizeWindow = - _publicAPI.ref.minimizeWindow.asFunction(); +final DMinimizeWindow minimizeWindow = _publicAPI.ref.minimizeWindow.asFunction(); // closeWindow typedef Void TCloseWindow(IntPtr window); @@ -148,8 +133,7 @@ final DMinimizeWindow closeWindow = _publicAPI.ref.closeWindow.asFunction(); // setWindowTitle typedef Void TSetWindowTitle(IntPtr window, Pointer title); typedef DSetWindowTitle = void Function(int window, Pointer title); -final DSetWindowTitle _setWindowTitle = - _publicAPI.ref.setWindowTitle.asFunction(); +final DSetWindowTitle _setWindowTitle = _publicAPI.ref.setWindowTitle.asFunction(); void setWindowTitle(int window, String title) { final _title = title.toNativeUtf8(); @@ -160,22 +144,19 @@ void setWindowTitle(int window, String title) { // getTitleBarHeight typedef Double TGetTitleBarHeight(IntPtr window); typedef DGetTitleBarHeight = double Function(int window); -final DGetTitleBarHeight getTitleBarHeight = - _publicAPI.ref.getTitleBarHeight.asFunction(); +final DGetTitleBarHeight getTitleBarHeight = _publicAPI.ref.getTitleBarHeight.asFunction(); -class BDWPublicAPI extends Struct { +base class BDWPublicAPI extends Struct { external Pointer> getAppWindow; external Pointer> setWindowCanBeShown; - external Pointer> - setInsideDoWhenWindowReady; + external Pointer> setInsideDoWhenWindowReady; external Pointer> showWindow; external Pointer> hideWindow; external Pointer> moveWindow; external Pointer> setSize; external Pointer> setMinSize; external Pointer> setMaxSize; - external Pointer> - getScreenInfoForWindow; + external Pointer> getScreenInfoForWindow; external Pointer> setPositionForWindow; external Pointer> setRectForWindow; external Pointer> getRectForWindow; @@ -189,14 +170,13 @@ class BDWPublicAPI extends Struct { external Pointer> getTitleBarHeight; } -class BDWAPI extends Struct { +base class BDWAPI extends Struct { external Pointer publicAPI; } typedef Pointer TBitsdojoWindowAPI(); -final TBitsdojoWindowAPI bitsdojoWindowAPI = _appExecutable - .lookup>("bitsdojo_window_api") - .asFunction(); +final TBitsdojoWindowAPI bitsdojoWindowAPI = + _appExecutable.lookup>("bitsdojo_window_api").asFunction(); final Pointer _publicAPI = bitsdojoWindowAPI().ref.publicAPI; diff --git a/bitsdojo_window_macos/lib/src/native_struct.dart b/bitsdojo_window_macos/lib/src/native_struct.dart index a3f47bf..a7c5184 100644 --- a/bitsdojo_window_macos/lib/src/native_struct.dart +++ b/bitsdojo_window_macos/lib/src/native_struct.dart @@ -1,7 +1,8 @@ import 'dart:ffi'; + import 'package:ffi/ffi.dart'; -class BDWRect extends Struct { +base class BDWRect extends Struct { @Double() external double left, top, right, bottom; } @@ -16,7 +17,7 @@ Pointer newBDWRect() { return result; } -class BDWScreenInfo extends Struct { +base class BDWScreenInfo extends Struct { external Pointer workingRect; external Pointer fullRect; } @@ -37,7 +38,7 @@ extension FreeBDWScreenInfo on Pointer { } } -class BDWOffset extends Struct { +base class BDWOffset extends Struct { @Double() external double x, y; } diff --git a/bitsdojo_window_macos/pubspec.yaml b/bitsdojo_window_macos/pubspec.yaml index 183b6b4..36c4c9d 100644 --- a/bitsdojo_window_macos/pubspec.yaml +++ b/bitsdojo_window_macos/pubspec.yaml @@ -1,12 +1,12 @@ name: bitsdojo_window_macos description: macOS implementation of the bitsdojo_window plugin. -version: 0.1.4 +version: 1.0.0 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=1.20.0" + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.41.0" dependencies: flutter: @@ -14,7 +14,7 @@ dependencies: bitsdojo_window_platform_interface: ^0.1.2 #path: ../bitsdojo_window_platform_interface - ffi: ^2.0.0 + ffi: ^2.2.0 dev_dependencies: flutter_test: diff --git a/bitsdojo_window_platform_interface/lib/window.dart b/bitsdojo_window_platform_interface/lib/window.dart index 4e8d501..6604d6e 100644 --- a/bitsdojo_window_platform_interface/lib/window.dart +++ b/bitsdojo_window_platform_interface/lib/window.dart @@ -1,8 +1,9 @@ import 'package:flutter/painting.dart'; +import 'package:win32/win32.dart'; abstract class DesktopWindow { DesktopWindow(); - int? get handle; + HWND? get handle; double get scaleFactor; Rect get rect; diff --git a/bitsdojo_window_platform_interface/lib/window_not_implemented.dart b/bitsdojo_window_platform_interface/lib/window_not_implemented.dart index e7b749d..eaeff19 100644 --- a/bitsdojo_window_platform_interface/lib/window_not_implemented.dart +++ b/bitsdojo_window_platform_interface/lib/window_not_implemented.dart @@ -1,8 +1,10 @@ -import './window.dart'; import 'package:flutter/rendering.dart'; +import 'package:win32/win32.dart'; + +import './window.dart'; class NotImplementedWindow extends DesktopWindow { - int get handle { + HWND get handle { throw UnimplementedError('handle getter has not been implemented'); } @@ -73,8 +75,7 @@ class NotImplementedWindow extends DesktopWindow { } Size get titleBarButtonSize { - throw UnimplementedError( - 'titleBarButtonSize getter has not been implemented.'); + throw UnimplementedError('titleBarButtonSize getter has not been implemented.'); } double get titleBarHeight { diff --git a/bitsdojo_window_platform_interface/pubspec.yaml b/bitsdojo_window_platform_interface/pubspec.yaml index 28fa4d4..f218b2b 100644 --- a/bitsdojo_window_platform_interface/pubspec.yaml +++ b/bitsdojo_window_platform_interface/pubspec.yaml @@ -3,20 +3,21 @@ description: A common platform interface for the bitsdojo_window plugin. homepage: https://github.com/bitsdojo/bitsdojo_window/bitsdojo_window_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 0.1.2 +version: 1.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0 - plugin_platform_interface: ^2.0.0 + meta: ^1.17.0 + plugin_platform_interface: ^2.1.8 + win32: ^6.0.1 dev_dependencies: flutter_test: sdk: flutter - mockito: ^5.0.2 - pedantic: ^1.11.0 + mockito: ^5.6.4 + pedantic: ^1.11.1 environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=1.22.0" + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.41.0" diff --git a/bitsdojo_window_windows/lib/src/app_window.dart b/bitsdojo_window_windows/lib/src/app_window.dart index cfbbedd..e4328e8 100644 --- a/bitsdojo_window_windows/lib/src/app_window.dart +++ b/bitsdojo_window_windows/lib/src/app_window.dart @@ -1,5 +1,7 @@ library bitsdojo_window_windows; +import 'package:win32/win32.dart'; + import './native_api.dart'; import './window.dart'; @@ -13,7 +15,7 @@ class BitsDojoNotInitializedException implements Exception { class WinAppWindow extends WinWindow { WinAppWindow._() { - super.handle = getAppWindow(); + super.handle = HWND(getAppWindow); final isLoaded = isBitsdojoWindowLoaded(); if (!isLoaded) { print(notInitializedMessage); diff --git a/bitsdojo_window_windows/lib/src/native_api.dart b/bitsdojo_window_windows/lib/src/native_api.dart index d6e6b05..4298538 100644 --- a/bitsdojo_window_windows/lib/src/native_api.dart +++ b/bitsdojo_window_windows/lib/src/native_api.dart @@ -7,8 +7,7 @@ final DynamicLibrary _appExecutable = DynamicLibrary.executable(); // isBitsdojoWindowLoaded typedef Int8 TIsBitsdojoWindowLoaded(); typedef DTIsBitsdojoWindowLoaded = int Function(); -final DTIsBitsdojoWindowLoaded? _isBitsdojoWindowLoaded = - _publicAPI.ref.isBitsdojoWindowLoaded.asFunction(); +final DTIsBitsdojoWindowLoaded? _isBitsdojoWindowLoaded = _publicAPI.ref.isBitsdojoWindowLoaded.asFunction(); bool isBitsdojoWindowLoaded() { if (_isBitsdojoWindowLoaded == null) { @@ -20,7 +19,7 @@ bool isBitsdojoWindowLoaded() { // getAppWindow typedef IntPtr TGetAppWindow(); typedef DGetAppWindow = int Function(); -final DGetAppWindow getAppWindow = _publicAPI.ref.getAppWindow.asFunction(); +final Pointer> getAppWindow = _publicAPI.ref.getAppWindow; // isDPIAware typedef Int8 TIsDPIAware(); @@ -31,8 +30,7 @@ bool isDPIAware() => _isDPIAware() != 0; // setWindowCanBeShown typedef Void TSetWindowCanBeShown(Int8 value); typedef DSetWindowCanBeShown = void Function(int value); -final DSetWindowCanBeShown _setWindowCanBeShown = - _publicAPI.ref.setWindowCanBeShown.asFunction(); +final DSetWindowCanBeShown _setWindowCanBeShown = _publicAPI.ref.setWindowCanBeShown.asFunction(); void setWindowCanBeShown(bool value) => _setWindowCanBeShown(value ? 1 : 0); // setMinSize @@ -48,29 +46,25 @@ final DSetMinSize setMaxSize = _publicAPI.ref.setMaxSize.asFunction(); // setWindowCutOnMaximize typedef Void TSetWindowCutOnMaximize(Int32 width); typedef DSetWindowCutOnMaximize = void Function(int width); -final DSetWindowCutOnMaximize setWindowCutOnMaximize = - _publicAPI.ref.setWindowCutOnMaximize.asFunction(); +final DSetWindowCutOnMaximize setWindowCutOnMaximize = _publicAPI.ref.setWindowCutOnMaximize.asFunction(); -class BDWPublicAPI extends Struct { - external Pointer> - isBitsdojoWindowLoaded; +base class BDWPublicAPI extends Struct { + external Pointer> isBitsdojoWindowLoaded; external Pointer> getAppWindow; external Pointer> setWindowCanBeShown; external Pointer> setMinSize; external Pointer> setMaxSize; - external Pointer> - setWindowCutOnMaximize; + external Pointer> setWindowCutOnMaximize; external Pointer> isDPIAware; } -class BDWAPI extends Struct { +base class BDWAPI extends Struct { external Pointer publicAPI; } typedef Pointer TBitsdojoWindowAPI(); -final TBitsdojoWindowAPI bitsdojoWindowAPI = _appExecutable - .lookup>("bitsdojo_window_api") - .asFunction(); +final TBitsdojoWindowAPI bitsdojoWindowAPI = + _appExecutable.lookup>("bitsdojo_window_api").asFunction(); final Pointer _publicAPI = bitsdojoWindowAPI().ref.publicAPI; diff --git a/bitsdojo_window_windows/lib/src/window.dart b/bitsdojo_window_windows/lib/src/window.dart index cdec859..a354040 100644 --- a/bitsdojo_window_windows/lib/src/window.dart +++ b/bitsdojo_window_windows/lib/src/window.dart @@ -1,18 +1,18 @@ import 'dart:ffi' hide Size; -import 'package:flutter/painting.dart'; +import 'package:bitsdojo_window_platform_interface/bitsdojo_window_platform_interface.dart'; import 'package:ffi/ffi.dart'; +import 'package:flutter/painting.dart'; import 'package:win32/win32.dart'; -import './win32_plus.dart'; import './native_api.dart' as native; -import 'package:bitsdojo_window_platform_interface/bitsdojo_window_platform_interface.dart'; -import './window_util.dart'; +import './win32_plus.dart'; import './window_interface.dart'; +import './window_util.dart'; var isInsideDoWhenWindowReady = false; -bool isValidHandle(int? handle, String operation) { +bool isValidHandle(HWND? handle, String operation) { if (handle == null) { print("Could not $operation - handle is null"); return false; @@ -20,23 +20,20 @@ bool isValidHandle(int? handle, String operation) { return true; } -Rect getScreenRectForWindow(int handle) { - int monitor = MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST); +Rect getScreenRectForWindow(HWND handle) { + HMONITOR monitor = MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST); final monitorInfo = calloc()..ref.cbSize = sizeOf(); final result = GetMonitorInfo(monitor, monitorInfo); if (result == TRUE) { - return Rect.fromLTRB( - monitorInfo.ref.rcWork.left.toDouble(), - monitorInfo.ref.rcWork.top.toDouble(), - monitorInfo.ref.rcWork.right.toDouble(), - monitorInfo.ref.rcWork.bottom.toDouble()); + return Rect.fromLTRB(monitorInfo.ref.rcWork.left.toDouble(), monitorInfo.ref.rcWork.top.toDouble(), + monitorInfo.ref.rcWork.right.toDouble(), monitorInfo.ref.rcWork.bottom.toDouble()); } return Rect.zero; } class WinWindow extends WinDesktopWindow { static final dpiAware = native.isDPIAware(); - int? handle; + HWND? handle; Size? _minSize; Size? _maxSize; // We use this for reporting size inside doWhenWindowReady @@ -63,8 +60,8 @@ class WinWindow extends WinDesktopWindow { set rect(Rect newRect) { if (!isValidHandle(handle, "set rectangle")) return; - setWindowPos(handle!, 0, newRect.left.toInt(), newRect.top.toInt(), - newRect.width.toInt(), newRect.height.toInt(), 0); + setWindowPos( + handle!, 0, newRect.left.toInt(), newRect.top.toInt(), newRect.width.toInt(), newRect.height.toInt(), 0); } Size get size { @@ -84,16 +81,14 @@ class WinWindow extends WinDesktopWindow { return Size(winRect.width, winRect.height); } - double systemMetric(int metric, {int dpiToUse = 0}) { + int systemMetric(SYSTEM_METRICS_INDEX metric, {int dpiToUse = 0}) { final windowDpi = dpiToUse != 0 ? dpiToUse : this.dpi; - double result = dpiAware - ? GetSystemMetricsForDpi(metric, windowDpi).toDouble() - : GetSystemMetrics(metric).toDouble(); + int result = dpiAware ? GetSystemMetricsForDpi(metric, windowDpi).value : GetSystemMetrics(metric); return result; } double get borderSize { - return this.systemMetric(SM_CXBORDER); + return this.systemMetric(SM_CXBORDER).toDouble(); } int get dpi { @@ -109,11 +104,11 @@ class WinWindow extends WinDesktopWindow { double get titleBarHeight { double scaleFactor = this.scaleFactor; int dpiToUse = this.dpi; - double cyCaption = systemMetric(SM_CYCAPTION, dpiToUse: dpiToUse); + double cyCaption = systemMetric(SM_CYCAPTION, dpiToUse: dpiToUse).toDouble(); cyCaption = (cyCaption / scaleFactor); - double cySizeFrame = systemMetric(SM_CYSIZEFRAME, dpiToUse: dpiToUse); + double cySizeFrame = systemMetric(SM_CYSIZEFRAME, dpiToUse: dpiToUse).toDouble(); cySizeFrame = (cySizeFrame / scaleFactor); - double cxPaddedBorder = systemMetric(SM_CXPADDEDBORDER, dpiToUse: dpiToUse); + double cxPaddedBorder = systemMetric(SM_CXPADDEDBORDER, dpiToUse: dpiToUse).toDouble(); cxPaddedBorder = (cxPaddedBorder / scaleFactor).ceilToDouble(); double result = cySizeFrame + cyCaption + cxPaddedBorder; return result; @@ -122,7 +117,7 @@ class WinWindow extends WinDesktopWindow { Size get titleBarButtonSize { double height = this.titleBarHeight - this.borderSize; double scaleFactor = this.scaleFactor; - double cyCaption = systemMetric(SM_CYCAPTION); + double cyCaption = systemMetric(SM_CYCAPTION).toDouble(); cyCaption /= scaleFactor; double width = cyCaption * 2; return Size(width, height); @@ -151,8 +146,7 @@ class WinWindow extends WinDesktopWindow { if (_alignment != null) { if (!isValidHandle(handle, "set alignment")) return; final screenRect = getScreenRectForWindow(handle!); - final rectOnScreen = - getRectOnScreen(sizeOnScreen, _alignment!, screenRect); + final rectOnScreen = getRectOnScreen(sizeOnScreen, _alignment!, screenRect); this.rect = rectOnScreen; } } @@ -201,8 +195,7 @@ class WinWindow extends WinDesktopWindow { Size sizeToSet = Size(width, height); _sizeSetFromDart = sizeToSet; if (_alignment == null) { - SetWindowPos(handle!, 0, 0, 0, sizeToSet.width.toInt(), - sizeToSet.height.toInt(), SWP_NOMOVE); + SetWindowPos(handle!, null, 0, 0, sizeToSet.width.toInt(), sizeToSet.height.toInt(), SWP_NOMOVE); } else { final sizeOnScreen = getSizeOnScreen((sizeToSet)); final screenRect = getScreenRectForWindow(handle!); @@ -231,21 +224,18 @@ class WinWindow extends WinDesktopWindow { set position(Offset newPosition) { if (!isValidHandle(handle, "set position")) return; - SetWindowPos(handle!, 0, newPosition.dx.toInt(), newPosition.dy.toInt(), 0, - 0, SWP_NOSIZE); + SetWindowPos(handle!, null, newPosition.dx.toInt(), newPosition.dy.toInt(), 0, 0, SWP_NOSIZE); } void show() { if (!isValidHandle(handle, "show")) return; - setWindowPos( - handle!, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + setWindowPos(handle!, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); forceChildRefresh(handle!); } void hide() { if (!isValidHandle(handle, "hide")) return; - SetWindowPos( - handle!, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_HIDEWINDOW); + SetWindowPos(handle!, null, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_HIDEWINDOW); } @Deprecated("use show()/hide() instead") @@ -259,23 +249,23 @@ class WinWindow extends WinDesktopWindow { void close() { if (!isValidHandle(handle, "close")) return; - PostMessage(handle!, WM_SYSCOMMAND, SC_CLOSE, 0); + PostMessage(handle!, WM_SYSCOMMAND, WPARAM(SC_CLOSE), LPARAM(0)); } void maximize() { if (!isValidHandle(handle, "maximize")) return; - PostMessage(handle!, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + PostMessage(handle!, WM_SYSCOMMAND, WPARAM(SC_MAXIMIZE), LPARAM(0)); } void minimize() { if (!isValidHandle(handle, "minimize")) return; - PostMessage(handle!, WM_SYSCOMMAND, SC_MINIMIZE, 0); + PostMessage(handle!, WM_SYSCOMMAND, WPARAM(SC_MINIMIZE), LPARAM(0)); } void restore() { if (!isValidHandle(handle, "restore")) return; - PostMessage(handle!, WM_SYSCOMMAND, SC_RESTORE, 0); + PostMessage(handle!, WM_SYSCOMMAND, WPARAM(SC_RESTORE), LPARAM(0)); } void maximizeOrRestore() { diff --git a/bitsdojo_window_windows/lib/src/window_util.dart b/bitsdojo_window_windows/lib/src/window_util.dart index 569da89..e0d6127 100644 --- a/bitsdojo_window_windows/lib/src/window_util.dart +++ b/bitsdojo_window_windows/lib/src/window_util.dart @@ -1,20 +1,20 @@ import 'dart:ffi'; -import 'package:win32/win32.dart'; + import 'package:ffi/ffi.dart'; +import 'package:win32/win32.dart'; const WM_BDW_ACTION = 0x7FFE; -const BDW_SETWINDOWPOS = 1; -const BDW_SETWINDOWTEXT = 2; -const BDW_FORCECHILDREFRESH = 3; +const WPARAM BDW_SETWINDOWPOS = WPARAM(1); +const WPARAM BDW_SETWINDOWTEXT = WPARAM(2); +const WPARAM BDW_FORCECHILDREFRESH = WPARAM(3); -class SWPParam extends Struct { +base class SWPParam extends Struct { @Int32() external int x, y, cx, cy, uFlags; } -void setWindowPos( - int hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int uFlags) { +void setWindowPos(HWND hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int uFlags) { final param = calloc(); param.ref ..x = x @@ -22,19 +22,19 @@ void setWindowPos( ..cx = cx ..cy = cy ..uFlags = uFlags; - PostMessage(hWnd, WM_BDW_ACTION, BDW_SETWINDOWPOS, param.address); + PostMessage(hWnd, WM_BDW_ACTION, BDW_SETWINDOWPOS, LPARAM(param.address)); } -class SWTParam extends Struct { +base class SWTParam extends Struct { external Pointer text; } -void setWindowText(int hWnd, String text) { +void setWindowText(HWND hWnd, String text) { final param = calloc(); param.ref.text = text.toNativeUtf16(); - PostMessage(hWnd, WM_BDW_ACTION, BDW_SETWINDOWTEXT, param.address); + PostMessage(hWnd, WM_BDW_ACTION, BDW_SETWINDOWTEXT, LPARAM(param.address)); } -void forceChildRefresh(int hWnd) { - PostMessage(hWnd, WM_BDW_ACTION, BDW_FORCECHILDREFRESH, 0); +void forceChildRefresh(HWND hWnd) { + PostMessage(hWnd, WM_BDW_ACTION, BDW_FORCECHILDREFRESH, LPARAM(0)); } diff --git a/bitsdojo_window_windows/pubspec.yaml b/bitsdojo_window_windows/pubspec.yaml index e1e525d..22eddbf 100644 --- a/bitsdojo_window_windows/pubspec.yaml +++ b/bitsdojo_window_windows/pubspec.yaml @@ -1,21 +1,20 @@ name: bitsdojo_window_windows description: Windows implementation of the bitsdojo_window plugin. -version: 0.1.6 +version: 1.0.0 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=1.20.0" + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.41.0" dependencies: flutter: sdk: flutter bitsdojo_window_platform_interface: - ^0.1.2 - #path: ../bitsdojo_window_platform_interface - win32: ^5.1.1 - ffi: ^2.0.0 + path: ../bitsdojo_window_platform_interface + win32: ^6.0.1 + ffi: ^2.2.0 dev_dependencies: flutter_test: