screen_retriever is built on nativeapi, a Flutter binding of one C++ core library (libnativeapi/nativeapi) shared by macOS, Windows and Linux. Coming from 0.2.x? See Upgrading from 0.2.x.
screen_retriever
This package lets Flutter desktop apps read the displays — their size, work area and scale factor — and the cursor position, and hear when displays are added, removed or changed.
English | 简体中文
Platform Support
| Linux | macOS | Windows |
|---|---|---|
| ✔️ | ✔️ | ✔️ |
Quick Start
Installation
Add this to your package's pubspec.yaml file:
dependencies:
screen_retriever: ^0.3.0
Or
dependencies:
screen_retriever:
git:
url: https://github.com/leanflutter/screen_retriever.git
ref: main
Requirements
- Flutter 3.47 / Dart 3.13 or later, macOS 10.15 or later.
- Linux build machines need GTK 3, X11 and Xi development files.
sudo apt-get install libgtk-3-dev libx11-dev libxi-dev
Usage
import 'package:screen_retriever/screen_retriever.dart';
final displayManager = DisplayManager.instance;
final primary = displayManager.getPrimary()!;
print('${primary.name}: ${primary.size.toSize()} at ${primary.scaleFactor}x');
print('work area: ${primary.workArea.toRect()}');
for (final display in displayManager.getAll()) {
print('${display.id} ${display.name} at ${display.position.toOffset()}');
}
print('cursor: ${displayManager.getCursorPosition().toOffset()}');
final listenerId = displayManager.addListener((event) {
switch (event) {
case DisplayAddedEvent(:final display):
print('added ${display.name}');
case DisplayRemovedEvent(:final display):
print('removed ${display.name}');
case DisplayChangedEvent(:final display):
print('changed ${display.name}');
}
});
// Later: displayManager.removeListener(listenerId);
Positions and sizes are logical pixels, with the origin at the top left of the primary
display. nativeapi's Point, Size and Rectangle are not exported, because Flutter
has its own Size: toOffset(), toSize() and toRect() turn them into Flutter's.
The example app of this plugin covers the 0.2.x compatible API.
Upgrading from 0.2.x
Code written for screen_retriever 0.2.x keeps working by importing
package:screen_retriever/legacy.dart instead of
package:screen_retriever/screen_retriever.dart. It provides the old screenRetriever,
ScreenListener, Display and ScreenRetrieverPlatform on top of the native API.
The import has to change on purpose: legacy.dart is a bridge, not the future of this
package. Its classes are marked @Deprecated and will be removed in a later
release — move to the native API above when you can.
import 'package:screen_retriever/legacy.dart';
final primaryDisplay = await screenRetriever.getPrimaryDisplay();
final displays = await screenRetriever.getAllDisplays();
final cursor = await screenRetriever.getCursorScreenPoint();
What differs from 0.2.x:
- Builds need Flutter 3.47 / Dart 3.13 and macOS 10.15 (0.2.x: Flutter 3.3). The
screen_retriever_platform_interface,_macos,_linuxand_windowspackages are no longer used. Display.idis nativeapi's display ID as text. It stays the same while the display is connected, but not across launches or reconnects; 0.2.x used the platform's own ID on macOS and Windows and an empty string on Linux.nameon Windows is the monitor's name ("DELL U2720Q", or "Generic PnP Monitor" where Windows has none) instead of\\.\DISPLAY1.visiblePositionandvisibleSizeare the work area — the display minus the menu bar, taskbar or panels — on every platform.- Sizes are no longer rounded on Windows, so a 150 % display can report
1706.67logical pixels. ScreenListeneralso hearsdisplay-changed, besidesdisplay-addedanddisplay-removed.MethodChannelScreenRetrieverkeeps its name and is still the defaultScreenRetrieverPlatform, but no method channel is left: itsmethodChannelandeventChannelfields are gone. Tests that replaceScreenRetrieverPlatform.instancework as before.
Moving to the native API
0.2.x (legacy.dart) |
Native API (screen_retriever.dart) |
|---|---|
await screenRetriever.getPrimaryDisplay() |
DisplayManager.instance.getPrimary() — synchronous, null when there is none |
await screenRetriever.getAllDisplays() |
DisplayManager.instance.getAll() |
await screenRetriever.getCursorScreenPoint() |
DisplayManager.instance.getCursorPosition().toOffset() |
display.id (String) |
display.id (DisplayId, an int) |
display.size |
display.size.toSize() |
display.visiblePosition, display.visibleSize |
display.workArea.toRect() |
display.name, display.scaleFactor |
the same, read live |
| — | display.position, isPrimary, orientation, refreshRate, bitDepth |
ScreenListener with screenRetriever.addListener |
DisplayManager.instance.addListener((event) { ... }), which returns the ID for removeListener |
onScreenEvent('display-added'), 'display-removed' |
DisplayAddedEvent, DisplayRemovedEvent, DisplayChangedEvent, each with its display |
display.toJson() |
— a native Display reads its values live; copy the ones you need |
A native Display is a handle to the system's display: call dispose() when you are
done with one you got from getAll() or getPrimary(), or let it be garbage-collected.
Who's using it?
- Biyi (比译) - A convenient translation and dictionary app.
- FastForge - An efficient tool for rapid application development and prototyping.
API
Native API
screen_retriever re-exports the display APIs from nativeapi: DisplayManager,
Display, DisplayEvent and its subclasses, DisplayId and DisplayOrientation,
with the toOffset(), toSize() and toRect() conversions from nativeapi_flutter.
Import package:screen_retriever/legacy.dart only for code that still uses the 0.2.x
API.
Contributors ✨
Thanks goes to these wonderful people (emoji key):
LiJianying 💻 |
Christian Padilla 💻 |
J-P Nurmi 💻 |
Kingtous 💻 |
fufesou 💻 |
lukasz-lukasz-lukasz 💻 |
|
|
|
||||||
This project follows the all-contributors specification. Contributions of any kind welcome!
License
Libraries
- legacy
- The
screen_retrieverAPI as it was before the move to nativeapi. - screen_retriever
- Displays and the cursor position, from nativeapi's
DisplayManager.