Skip to content

Commit

Permalink
πŸͺŸ windows mulit monitor support
Browse files Browse the repository at this point in the history
  • Loading branch information
mulaRahul committed Apr 19, 2024
1 parent 83ee5ff commit ca4e46b
Show file tree
Hide file tree
Showing 97 changed files with 159 additions and 42 deletions.
2 changes: 1 addition & 1 deletion lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'providers/key_style.dart';
import 'windows/error/error.dart';
import 'windows/settings/settings.dart';
import 'windows/key_visualizer/key_visualizer.dart';
import 'package:keyviz/windows/mouse_visualizer/mouse_visualizer.dart';
import 'windows/mouse_visualizer/mouse_visualizer.dart';

class KeyvizApp extends StatelessWidget {
const KeyvizApp({super.key});
Expand Down
1 change: 0 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ _initWindow() async {
windowManager.setIgnoreMouseEvents(true);
windowManager.setHasShadow(false);
windowManager.setAsFrameless();
windowManager.show();
},
);

Expand Down
66 changes: 63 additions & 3 deletions lib/providers/key_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' hide ModifierKey;
import 'package:hid_listener/hid_listener.dart';
import 'package:window_size/window_size.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart';

import 'package:keyviz/config/config.dart';
import 'package:keyviz/domain/services/raw_keyboard_mouse.dart';
import 'package:keyviz/domain/vault/vault.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart';

import 'key_event_data.dart';

Expand Down Expand Up @@ -79,6 +80,12 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {
_init();
}

// index of current screen in the screens list
int _screenIndex = 0;

// display/screens list
final List<Screen> _screens = [];

// errors
bool _hasError = false;

Expand Down Expand Up @@ -171,8 +178,11 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {
// show mouse events with keypress like, [Shift] + [Drag]
bool _showMouseEvents = _Defaults.showMouseEvents;

Map<String, Map<int, KeyEventData>> get keyboardEvents => _keyboardEvents;
Screen get _currentScreen => _screens[_screenIndex];

Map<String, Map<int, KeyEventData>> get keyboardEvents => _keyboardEvents;
int get screenIndex => _screenIndex;
List<Screen> get screens => _screens;
bool get styling => _styling;
bool get visualizeEvents => _visualizeEvents;
bool get hasError => _hasError;
Expand Down Expand Up @@ -208,6 +218,11 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {
bool get _ignoreHistory =>
_historyMode == VisualizationHistoryMode.none || _styling;

set screenIndex(int value) {
_screenIndex = value;
_changeDisplay();
}

set styling(bool value) {
if (_hasError) return;
_styling = value;
Expand Down Expand Up @@ -294,7 +309,14 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {
_onMouseEvent(MouseEvent event) {
// visualizer toggle
if (!_visualizeEvents) return;
// process mouse event
event.x -= _currentScreen.frame.left;
event.y -= _currentScreen.frame.top;

if (!Platform.isMacOS) {
event.x /= _currentScreen.scaleFactor;
event.y /= _currentScreen.scaleFactor;
}
// mouse moved
if (event is MouseMoveEvent) {
_onMouseMove(event);
Expand Down Expand Up @@ -836,6 +858,10 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {
}

Map<String, dynamic> get toJson => {
_JsonKeys.screenFrame: [
_screens[_screenIndex].frame.width,
_screens[_screenIndex].frame.height,
],
_JsonKeys.filterHotkeys: _filterHotkeys,
_JsonKeys.ignoreKeys: {
ModifierKey.control.name: _ignoreKeys[ModifierKey.control],
Expand Down Expand Up @@ -920,6 +946,39 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {

_showMouseEvents =
data[_JsonKeys.showMouseEvents] ?? _Defaults.showMouseEvents;

// set preferred display
_setDisplay(data[_JsonKeys.screenFrame]);
}

_setDisplay(List? frame) async {
_screens.addAll(await getScreenList());

if (frame != null) {
final index = _screens.indexWhere(
(screen) =>
screen.frame.width == frame[0] && screen.frame.height == frame[1],
);

if (index != -1) _screenIndex = index;
}

setWindowFrame(_currentScreen.frame);

windowManager.show();
}

_changeDisplay() async {
await windowManager.setFullScreen(false);
await windowManager.hide();

setWindowFrame(_currentScreen.frame);
// simulate delay for above
await Future.delayed(Durations.extralong2);
await windowManager.setFullScreen(true);
await windowManager.show();

notifyListeners();
}

revertToDefaults() {
Expand Down Expand Up @@ -949,6 +1008,7 @@ class KeyEventProvider extends ChangeNotifier with TrayListener {
}

class _JsonKeys {
static const screenFrame = "screen_frame";
static const filterHotkeys = "filter_hotkeys";
static const ignoreKeys = "ignore_keys";
static const historyMode = "history_mode";
Expand Down
17 changes: 3 additions & 14 deletions lib/windows/mouse_visualizer/mouse_visualizer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,13 @@ class MouseVisualizer extends StatelessWidget {
Widget build(BuildContext context) {
return Selector<KeyEventProvider, Tuple2<bool, Offset>>(
builder: (context, tuple, child) {
final devicePixelRatio = MediaQuery.of(context)
.devicePixelRatio; // Get the logical pixel ratio

return tuple.item1
? Positioned(
left: tuple.item2.dx /
devicePixelRatio, // Horizontal offset of the cursor divided by the logical pixel ratio

left: tuple.item2.dx,
top: Platform.isMacOS ? null : tuple.item2.dy,
// On macOS, the mouse offset is from the bottomLeft
// instead of the topLeft
top: Platform.isMacOS
? null
: tuple.item2.dy /
devicePixelRatio, // The vertical offset of the cursor divided by the logical pixel ratio
bottom: Platform.isMacOS
? tuple.item2.dy /
devicePixelRatio // The vertical offset of the cursor divided by the logical pixel ratio
: null,
bottom: Platform.isMacOS ? tuple.item2.dy : null,
child: const IgnorePointer(
child: FractionalTranslation(
translation: Offset(-.5, -.5),
Expand Down
21 changes: 21 additions & 0 deletions lib/windows/settings/views/appearance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:keyviz/config/config.dart';
import 'package:keyviz/providers/key_event.dart';
import 'package:keyviz/providers/key_style.dart';
import 'package:keyviz/windows/shared/shared.dart';
import 'package:window_size/window_size.dart';

import '../widgets/widgets.dart';

Expand All @@ -16,6 +17,26 @@ class AppearanceTabView extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
children: [
if (context.keyEvent.screens.length > 1) ...[
PanelItem(
title: "Display",
subtitle: "Change monitor/display for the visualisation. "
"A restart\nmay be required in case of unsual behaviour.",
action: Selector<KeyEventProvider, int>(
selector: (_, keyEvent) => keyEvent.screenIndex,
builder: (context, value, _) => XDropdown<int>(
value: value,
options: List.generate(
context.keyEvent.screens.length,
(i) => i,
),
labelBuilder: (option) => "Display ${option + 1}",
onChanged: (value) => context.keyEvent.screenIndex = value,
),
),
),
const Divider(),
],
PanelItem(
title: "Alignment",
subtitle: "Position of the key visualization on the screen.\nIf "
Expand Down
4 changes: 3 additions & 1 deletion lib/windows/settings/widgets/cross_dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ class XDropdown<T> extends StatelessWidget {
required this.options,
required this.onChanged,
this.decorated = true,
this.labelBuilder,
});

final T value;
final bool decorated;
final List<T> options;
final String Function(T option)? labelBuilder;
final ValueChanged<T> onChanged;

@override
Expand All @@ -24,7 +26,7 @@ class XDropdown<T> extends StatelessWidget {
for (final option in options)
DropdownMenuItem(
value: option,
child: Text(option.toString()),
child: Text(labelBuilder?.call(option) ?? option.toString()),
),
],
onChanged: (v) {
Expand Down
4 changes: 4 additions & 0 deletions linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h>
#include <window_size/window_size_plugin.h>

void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
Expand All @@ -32,4 +33,7 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) window_manager_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
window_manager_plugin_register_with_registrar(window_manager_registrar);
g_autoptr(FlPluginRegistrar) window_size_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowSizePlugin");
window_size_plugin_register_with_registrar(window_size_registrar);
}
1 change: 1 addition & 0 deletions linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
tray_manager
url_launcher_linux
window_manager
window_size
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import screen_retriever
import tray_manager
import url_launcher_macos
import window_manager
import window_size

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
HidListenerPlugin.register(with: registry.registrar(forPlugin: "HidListenerPlugin"))
Expand All @@ -21,4 +22,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
WindowSizePlugin.register(with: registry.registrar(forPlugin: "WindowSizePlugin"))
}
7 changes: 7 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.3.8"
window_size:
dependency: "direct main"
description:
path: window_size
relative: true
source: path
version: "0.1.0"
xdg_directories:
dependency: transitive
description:
Expand Down
3 changes: 3 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ dependencies:
# cross-platform HID (Human Input Device) listener
hid_listener: ^2.0.1

window_size:
path: window_size

tuple: ^2.0.2
provider: ^6.1.2
flutter_svg: ^2.0.9
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ void main() {
screenFrame.top + ((screenFrame.height - height) / 3).roundToDouble();
final frame = Rect.fromLTWH(left, top, width, height);
window_size.setWindowFrame(frame);
// window_size.setWindowMinSize(Size(0.8 * width, 0.8 * height));
// window_size.setWindowMaxSize(Size(1.5 * width, 1.5 * height));
window_size.setWindowMinSize(Size(0.8 * width, 0.8 * height));
window_size.setWindowMaxSize(Size(1.5 * width, 1.5 * height));
window_size
.setWindowTitle('window_size Example on ${Platform.operatingSystem}');
}
Expand Down Expand Up @@ -70,16 +70,21 @@ class MyHomePage extends StatefulWidget {
}

class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
final _screens = <window_size.Screen>[];

void _incrementCounter() {
window_size.setWindowFrame(Rect.fromLTWH(0, 0, 1500, 1500));
@override
void initState() {
super.initState();

setState(() {
_counter++;
});
window_size.getScreenList().then(
(screens) => setState(
() => _screens.addAll(screens),
),
);
}

void _incrementCounter() {}

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -90,19 +95,29 @@ class _MyHomePageState extends State<MyHomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter\n',
style: Theme.of(context).textTheme.headlineMedium,
),
FutureBuilder(
future: window_size.getCurrentScreen(),
builder: (context, snapshot) {
return Text("${snapshot.data}");
// return Text("${(snapshot.data as window_size.Screen).frame}");
},
SizedBox.square(
dimension: 500,
child: DecoratedBox(
decoration: BoxDecoration(border: Border.all()),
child: Stack(
clipBehavior: Clip.none,
children: [
for (final screen in _screens)
Positioned(
top: screen.frame.top / 10,
left: screen.frame.left / 10,
width: screen.frame.size.width / 10,
height: screen.frame.size.height / 10,
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.primaries[math.Random().nextInt(4)],
),
child: Text(screen.frame.size.toString()),
),
),
],
),
),
),
],
),
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
# https://github.com/flutter/flutter/issues/57146.
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")

# Set fallback configurations for older versions of the flutter tool.
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
set(FLUTTER_TARGET_PLATFORM "windows-x64")
endif()

# === Flutter Library ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")

Expand Down Expand Up @@ -92,7 +97,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
windows-x64 $<CONFIG>
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
Expand Down
Loading

0 comments on commit ca4e46b

Please sign in to comment.