A Flutter plugin for Desktop that controls the window instance.
Modified for Windows support and other improvements.
- Add to your
pubspec.yaml
:
dependencies:
window_utils:
git: https://github.com/autumnlabs/window_utils
Nothing needed, already good to go!
Follow this guide on how to work with desktop plugins for linux:
https://github.com/google/flutter-desktop-embedding/tree/master/plugins
Follow this guide on how to work with desktop plugins for windows:
https://github.com/google/flutter-desktop-embedding/tree/master/plugins
These are the various api calls and are subject to change in the future.
When you do this you will loose drag window functionality. (But there is a solution for that below). On Windows you also loose default resize and tool bar buttons (see below)
WindowUtils.hideTitleBar();
// If used on app launch wrap it this way:
WidgetsBinding.instance.addPostFrameCallback(
(_) => WindowUtils.hideTitleBar(),
);
This will also give you options on customizing the default toolbar in the future
WindowUtils.showTitleBar();
Required to implement if you hide the title bar
This executes a close command to the window. It can still be restored by the OS if enabled.
WindowUtils.showTitleBar();
WINDOWS ONLY
Required to implement if you hide the title bar
This will minimize the window if you hide the title bar and/or have a custom minimize button.
WindowUtils.minWindow();
WINDOWS ONLY
Maximize the window.
WindowUtils.maxWindow();
WINDOWS ONLY
Unmaximize the window.
WindowUtils.unmaxWindow();
WINDOWS ONLY
Toggle window maximized state.
WindowUtils.toggleMaxWindow();
Center the window.
WindowUtils.centerWindow();
This will position the window in relation to the display it is rendered in.
You need to provide Offset
that is the top left corner of the screen. You can get the current offset by calling WindowUtils.getWindowOffset()
.
WindowUtils.setPosition(Offset offset);
This will size the window in relation to the display it is rendered in.
You need to provide Size
that is the width and height of the screen. You can get the current size by calling WindowUtils.getWindowSize()
.
WindowUtils.setSize(Size size);
Required to implement if you hide the title bar
This will drag the window. You can call this to move the window around the screen and pass the mouse event to the native platform.
WindowUtils.startDrag();
This will drag resize the window. You can call this to resize the window on the screen and pass the mouse event to the native platform.
You need to provide DragPosition
to tell the native platform where you are dragging from.
enum DragPosition {
top,
left,
right,
bottom,
topLeft,
bottomLeft,
topRight,
bottomRight
}
Included in the package is import 'package:window_utils/window_frame.dart';
a WindowsFrame
that includes the calls for you with a transparent border to handle the events. See the example for more details.
startResize(DragPosition position);
Required to implement if you hide the title bar
This will call the native platform command for when you double tap on a title bar.
WindowUtils.windowTitleDoubleTap();
This will return a int
count of all the children windows currently open.
WindowUtils.childWindowsCount();
This will return a Size
size of the display window that the application is running in.
WindowUtils.getScreenSize();
This will return a Size
size of the application window that is running.
WindowUtils.getWindowSize();
This will return a Offset
offset of the application window that is running.
WindowUtils.getWindowOffset();
MACOS ONLY
Update the system cursor.
You need to provide CursorType
type to set the cursor too. (You can also add the cursor to the stack)
Avaliable cursors:
enum CursorType {
arrow,
beamVertical,
crossHair,
closedHand,
openHand,
pointingHand,
resizeLeft,
resizeRight,
resizeDown,
resizeUp,
resizeLeftRight,
resizeUpDown,
beamHorizontial,
disappearingItem,
notAllowed,
dragLink,
dragCopy,
contextMenu,
}
WindowUtils.setCursor(CursorType cursor);
MACOS ONLY
Add a new cursor to the mouse cursor stack.
You need to provide CursorType
type to set the cursor too. (You can also add the cursor to the stack)
Avaliable cursors:
enum CursorType {
arrow,
beamVertical,
crossHair,
closedHand,
openHand,
pointingHand,
resizeLeft,
resizeRight,
resizeDown,
resizeUp,
resizeLeftRight,
resizeUpDown,
beamHorizontial,
disappearingItem,
notAllowed,
dragLink,
dragCopy,
contextMenu,
}
WindowUtils.addCursorToStack(CursorType cursor);
This will remove the top cursor from the stack.
WindowUtils.removeCursorFromStack();
This will hide the all the cursors in the stack.
WindowUtils.hideCursor();
This will reset the system cursor.
WindowUtils.resetCursor();
This will show all the cursors in the stack.
WindowUtils.showCursor();
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:window_utils/window_utils.dart';
import 'package:window_utils/window_frame.dart';
void main() {
if (!kIsWeb && debugDefaultTargetPlatformOverride == null) {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
}
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(
(_) => WindowUtils.hideTitleBar(),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: WindowsFrame(
active: Platform.isWindows,
border: Border.all(color: Colors.grey),
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Stack(
children: <Widget>[
Positioned.fill(
child: GestureDetector(
onTapDown: (_) {
WindowUtils.startDrag();
},
onDoubleTap: () {
WindowUtils.windowTitleDoubleTap().then((_) {
if (mounted) setState(() {});
});
},
child: Material(
elevation: 4.0,
color: Theme.of(context).primaryColor,
),
),
),
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Text(
'Window Utils Example',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
),
),
),
Positioned(
bottom: 0,
top: 0,
right: 0,
child: Center(
child: Row(
children: <Widget>[
IconButton(
color: Colors.white,
icon: Icon(Icons.info_outline),
onPressed: () {
WindowUtils.getWindowSize()
.then((val) => print('Window: $val'));
WindowUtils.getScreenSize()
.then((val) => print('Screen: $val'));
WindowUtils.getWindowOffset()
.then((val) => print('Offset: $val'));
},
),
],
),
),
),
],
),
),
floatingActionButton: InkWell(
child: Icon(Icons.drag_handle),
),
body: ListView(
children: <Widget>[
ListTile(
title: Text("Max Window Size"),
trailing: IconButton(
icon: Icon(Icons.desktop_windows),
onPressed: () {
WindowUtils.getScreenSize().then((val) async {
await WindowUtils.setSize(Size(val.width, val.height));
await WindowUtils.setPosition(Offset(0, 0));
});
},
),
),
ListTile(
title: Text("Increase Window Size"),
trailing: IconButton(
icon: Icon(Icons.desktop_windows),
onPressed: () {
WindowUtils.getWindowSize().then((val) {
WindowUtils.setSize(
Size(val.width + 20, val.height + 20),
);
});
},
),
),
ListTile(
title: Text("Move Window Position"),
trailing: IconButton(
icon: Icon(Icons.drag_handle),
onPressed: () {
WindowUtils.getWindowOffset().then((val) {
WindowUtils.setPosition(
Offset(val.dx + 20, val.dy + 20),
);
});
},
),
),
ListTile(
title: Text("Center Window"),
trailing: IconButton(
icon: Icon(Icons.vertical_align_center),
onPressed: () {
WindowUtils.centerWindow();
},
),
),
ListTile(
title: Text("Close Window"),
trailing: IconButton(
icon: Icon(Icons.close),
onPressed: () {
WindowUtils.closeWindow();
},
),
),
],
),
),
),
);
}
}