window_utils 1.0.2

  • Readme
  • Changelog
  • Example
  • Installing
  • new72

window_utils #

A Flutter plugin for Desktop that controls the window instance.

Installing #

dependencies:
  window_utils: any

or the latest from git

dependencies:
  window_utils:
    git: https://github.com/rive-app/window_utils

MacOS #

Nothing needed, already good to go!

Linux #

Follow this guide on how to work with desktop plugins for linux:

https://github.com/google/flutter-desktop-embedding/tree/master/plugins

Windows #

Follow this guide on how to work with desktop plugins for windows:

https://github.com/google/flutter-desktop-embedding/tree/master/plugins

Usage #

These are the various api calls and are subject to change in the future.

Hide the desktop title bar #

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(),
);

no_title

Show the default title bar #

This will also give you options on customizing the default toolbar in the future

WindowUtils.showTitleBar();

Close the window #

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();

Minimize the window #

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();

Maximize the window #

WINDOWS ONLY

Required to implement if you hide the title bar

This will maximize the window if you hide the title bar and/or have a custom maximize button.

WindowUtils.maxWindow();

Center the window #

This will center the window.

WindowUtils.maxWindow();

Set the window position #

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);

Set the window size #

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);

Drag the window #

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();

Drag to resize the window #

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);

Double tap title bar command #

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();

Child window count #

This will return a int count of all the children windows currently open.

WindowUtils.childWindowsCount();

Get display screen size #

This will return a Size size of the display window that the application is running in.

WindowUtils.getScreenSize();

Get application screen size #

This will return a Size size of the application window that is running.

WindowUtils.getWindowSize();

Get application position #

This will return a Offset offset of the application window that is running.

WindowUtils.getWindowOffset();

Set Mouse Cursor #

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);

Add Mouse Cursor To Stack #

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);

Remove Cursor From Stack #

This will remove the top cursor from the stack.

WindowUtils.removeCursorFromStack();

Hide Cursor(s) #

This will hide the all the cursors in the stack.

WindowUtils.hideCursor();

Reset Cursor #

This will reset the system cursor.

WindowUtils.resetCursor();

Show Cursor(s) #

This will show all the cursors in the stack.

WindowUtils.showCursor();

Example #

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();
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Changes #

1.0.2 #

  • Added: hideCursor (MacOS)
  • Added: showCursor (MacOS)
  • Added: setCursor (MacOS)
  • Added: addCursorToStack (MacOS)
  • Added: removeCursorFromStack (MacOS)
  • Added: mouseStackCount (MacOS)
  • Added: resetCursor (MacOS)

1.0.1 #

  • Removed: setCanMove
  • Added: minWindow (Windows)
  • Added: maxWindow (Windows)
  • Added: getScreenSize (MacOS, Windows)
  • Added: setPosition (MacOS, Windows)
  • Added: setSize (MacOS, Windows)
  • Added: closeWindow (MacOS, Windows)
  • Added: centerWindow (MacOS, Windows)
  • Updated: getWindowSize (Windows)
  • Updated: getWindowOffset (Windows)
  • Added: windowTitleDoubleTap (MacOS, Windows)

1.0.0 #

  • Added: showTitleBar (MacOS)
  • Added: hideTitleBar (MacOS)
  • Added: setCanMove (MacOS)
  • Added: startDrag (MacOS)
  • Added: childWindowsCount (MacOS)
  • Added: getWindowSize (MacOS)
  • Added: getWindowOffset (MacOS)

example/README.md

window_utils_example #

Demonstrates how to use the window_utils plugin.

Example #

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();
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  window_utils: ^1.0.2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:window_utils/window_utils.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
48
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
88
Overall:
Weighted score of the above. [more]
72
Learn more about scoring.

We analyzed this package on Jan 19, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.4
  • Flutter: 1.12.13+hotfix.5

Maintenance suggestions

The package description is too short. (-12 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.28.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8