diff --git a/LICENSE b/LICENSE index 03d8b0a..eea05ab 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 LiJianying +Copyright (c) 2022-2024 LiJianying Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/analysis_options.yaml b/analysis_options.yaml deleted file mode 100644 index a5744c1..0000000 --- a/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/dart_dependency_validator.yaml b/dart_dependency_validator.yaml deleted file mode 100644 index c69bdf1..0000000 --- a/dart_dependency_validator.yaml +++ /dev/null @@ -1,2 +0,0 @@ -exclude: - - "example/**" diff --git a/lib/screen_retriever.dart b/lib/screen_retriever.dart deleted file mode 100644 index 0247119..0000000 --- a/lib/screen_retriever.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'src/display.dart'; -export 'src/screen_listener.dart'; -export 'src/screen_retriever.dart'; diff --git a/lib/src/display.dart b/lib/src/display.dart deleted file mode 100644 index f8c5314..0000000 --- a/lib/src/display.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'dart:ui'; - -/// Description of a user display screen. -class Display { - // Unique identifier associated with the display. - final num id; - final String? name; - final Size size; - final Offset? visiblePosition; - final Size? visibleSize; - final num? scaleFactor; - - Display({ - required this.id, - this.name, - required this.size, - this.visiblePosition, - this.visibleSize, - this.scaleFactor, - }); - - factory Display.fromJson(Map json) { - Offset? visiblePosition; - Size? visibleSize; - - if (json['visiblePosition'] != null) { - visiblePosition = Offset( - json['visiblePosition']['x'], - json['visiblePosition']['y'], - ); - } - if (json['visibleSize'] != null) { - visibleSize = Size( - json['visibleSize']['width'], - json['visibleSize']['height'], - ); - } - - return Display( - id: json['id'], - name: json['name'], - size: Size( - json['size']['width'], - json['size']['height'], - ), - visiblePosition: visiblePosition, - visibleSize: visibleSize, - scaleFactor: json.containsKey('scaleFactor') ? json['scaleFactor'] : null, - ); - } - - Map toJson() { - return { - 'id': id, - 'name': name, - 'size': { - 'width': size.width, - 'height': size.height, - }, - 'visiblePosition': visiblePosition != null - ? { - 'x': visiblePosition!.dx, - 'y': visiblePosition!.dy, - } - : null, - 'visibleSize': visibleSize != null - ? { - 'width': visibleSize!.width, - 'height': visibleSize!.height, - } - : null, - 'scaleFactor': scaleFactor, - }; - } -} diff --git a/lib/src/screen_listener.dart b/lib/src/screen_listener.dart deleted file mode 100644 index bdc782c..0000000 --- a/lib/src/screen_listener.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class ScreenListener { - void onScreenEvent(String eventName) {} -} diff --git a/lib/src/screen_retriever.dart b/lib/src/screen_retriever.dart deleted file mode 100644 index 2897836..0000000 --- a/lib/src/screen_retriever.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:async'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:screen_retriever/screen_retriever.dart'; - -// import 'screen_listener.dart'; - -const kScreenEventDisplayAdded = 'display-added'; -const kScreenEventDisplayRemoved = 'display-removed'; - -class ScreenRetriever { - ScreenRetriever._() { - _channel.setMethodCallHandler(_methodCallHandler); - } - - /// The shared instance of [ScreenRetriever]. - static final ScreenRetriever instance = ScreenRetriever._(); - - // ignore: deprecated_member_use - double get devicePixelRatio => window.devicePixelRatio; - - final MethodChannel _channel = const MethodChannel('screen_retriever'); - - final ObserverList _listeners = - ObserverList(); - - @visibleForTesting - MethodChannel get channel => _channel; - - Future _methodCallHandler(MethodCall call) async { - final List localListeners = - List.from(_listeners); - for (final ScreenListener listener in localListeners) { - if (!_listeners.contains(listener)) { - return; - } - - if (call.method != 'onEvent') throw UnimplementedError(); - - String eventName = call.arguments['eventName']; - listener.onScreenEvent(eventName); - } - } - - bool get hasListeners { - return _listeners.isNotEmpty; - } - - void addListener(ScreenListener listener) { - _listeners.add(listener); - } - - void removeListener(ScreenListener listener) { - _listeners.remove(listener); - } - - Future getCursorScreenPoint() async { - final Map arguments = { - 'devicePixelRatio': devicePixelRatio, - }; - final Map resultData = - await _channel.invokeMethod('getCursorScreenPoint', arguments); - return Offset( - resultData['x'], - resultData['y'], - ); - } - - Future getPrimaryDisplay() async { - final Map arguments = { - 'devicePixelRatio': devicePixelRatio, - }; - final Map resultData = - await _channel.invokeMethod('getPrimaryDisplay', arguments); - return Display.fromJson(Map.from(resultData)); - } - - Future> getAllDisplays() async { - final Map arguments = { - 'devicePixelRatio': devicePixelRatio, - }; - final Map resultData = - await _channel.invokeMethod('getAllDisplays', arguments); - - List displayList = []; - - if (resultData['displays'] != null) { - displayList = (resultData['displays'] as List) - .map((item) => Display.fromJson(Map.from(item))) - .toList(); - } - - return displayList; - } -} - -final screenRetriever = ScreenRetriever.instance; diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt deleted file mode 100644 index 96ad33a..0000000 --- a/linux/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -set(PROJECT_NAME "screen_retriever") -project(${PROJECT_NAME} LANGUAGES CXX) - -# This value is used when generating builds using this plugin, so it must -# not be changed -set(PLUGIN_NAME "screen_retriever_plugin") - -add_library(${PLUGIN_NAME} SHARED - "screen_retriever_plugin.cc" -) -apply_standard_settings(${PLUGIN_NAME}) -set_target_properties(${PLUGIN_NAME} PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) -target_include_directories(${PLUGIN_NAME} INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) -target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) - -# List of absolute paths to libraries that should be bundled with the plugin -set(screen_retriever_bundled_libraries - "" - PARENT_SCOPE -) diff --git a/linux/include/screen_retriever/screen_retriever_plugin.h b/linux/include/screen_retriever/screen_retriever_plugin.h deleted file mode 100644 index 4b752c5..0000000 --- a/linux/include/screen_retriever/screen_retriever_plugin.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef FLUTTER_PLUGIN_SCREEN_RETRIEVER_PLUGIN_H_ -#define FLUTTER_PLUGIN_SCREEN_RETRIEVER_PLUGIN_H_ - -#include - -G_BEGIN_DECLS - -#ifdef FLUTTER_PLUGIN_IMPL -#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) -#else -#define FLUTTER_PLUGIN_EXPORT -#endif - -typedef struct _ScreenRetrieverPlugin ScreenRetrieverPlugin; -typedef struct { - GObjectClass parent_class; -} ScreenRetrieverPluginClass; - -FLUTTER_PLUGIN_EXPORT GType screen_retriever_plugin_get_type(); - -FLUTTER_PLUGIN_EXPORT void screen_retriever_plugin_register_with_registrar( - FlPluginRegistrar* registrar); - -G_END_DECLS - -#endif // FLUTTER_PLUGIN_SCREEN_RETRIEVER_PLUGIN_H_ diff --git a/linux/screen_retriever_plugin.cc b/linux/screen_retriever_plugin.cc deleted file mode 100644 index 0cd6a6f..0000000 --- a/linux/screen_retriever_plugin.cc +++ /dev/null @@ -1,200 +0,0 @@ -#include "include/screen_retriever/screen_retriever_plugin.h" - -#include -#include -#include - -#include - -#define SCREEN_RETRIEVER_PLUGIN(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), screen_retriever_plugin_get_type(), \ - ScreenRetrieverPlugin)) - -struct _ScreenRetrieverPlugin { - GObject parent_instance; - FlPluginRegistrar* registrar; -}; - -G_DEFINE_TYPE(ScreenRetrieverPlugin, - screen_retriever_plugin, - g_object_get_type()) - -// Gets the window being controlled. -GtkWindow* get_window(ScreenRetrieverPlugin* self) { - FlView* view = fl_plugin_registrar_get_view(self->registrar); - if (view == nullptr) - return nullptr; - - return GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))); -} - -FlValue* monitor_to_flvalue(GdkMonitor* monitor) { - GdkRectangle frame; - gdk_monitor_get_geometry(monitor, &frame); - - auto size = fl_value_new_map(); - fl_value_set_string_take(size, "width", fl_value_new_float(frame.width)); - fl_value_set_string_take(size, "height", fl_value_new_float(frame.height)); - - GdkRectangle workarea_rect; - gdk_monitor_get_workarea(monitor, &workarea_rect); - - // printf("x: %d y: %%d", workarea_rect.x, workarea_rect.y); - - auto visible_size = fl_value_new_map(); - fl_value_set_string_take(visible_size, "width", - fl_value_new_float(workarea_rect.width)); - fl_value_set_string_take(visible_size, "height", - fl_value_new_float(workarea_rect.height)); - - auto visible_position = fl_value_new_map(); - fl_value_set_string_take(visible_position, "x", - fl_value_new_float(workarea_rect.x)); - fl_value_set_string_take(visible_position, "y", - fl_value_new_float(workarea_rect.y)); - - const char* name = gdk_monitor_get_model(monitor); - gint scale_factor = gdk_monitor_get_scale_factor(monitor); - - auto value = fl_value_new_map(); - fl_value_set_string_take(value, "id", fl_value_new_float(0)); - fl_value_set_string_take(value, "name", fl_value_new_string(name == nullptr ? "" : name)); - fl_value_set_string_take(value, "size", size); - fl_value_set_string_take(value, "visibleSize", visible_size); - fl_value_set_string_take(value, "visiblePosition", visible_position); - fl_value_set_string_take(value, "scaleFactor", - fl_value_new_float(scale_factor)); - - return value; -} - -static FlMethodResponse* get_cursor_screen_point(ScreenRetrieverPlugin* self, - FlValue* args) { - GdkDisplay* display = gdk_display_get_default(); - GdkSeat* seat = gdk_display_get_default_seat(display); - GdkDevice* pointer = gdk_seat_get_pointer(seat); - - int x, y; - gdk_device_get_position(pointer, NULL, &x, &y); - - g_autoptr(FlValue) result_data = fl_value_new_map(); - fl_value_set_string_take(result_data, "x", fl_value_new_float(x)); - fl_value_set_string_take(result_data, "y", fl_value_new_float(y)); - - return FL_METHOD_RESPONSE(fl_method_success_response_new(result_data)); -} - -static FlMethodResponse* get_primary_display(ScreenRetrieverPlugin* self, - FlValue* args) { - GdkDisplay* display = gdk_display_get_default(); - GdkMonitor* monitor = gdk_display_get_primary_monitor(display); - - // opt: fallback if there's no primary monitor - if (monitor == nullptr) { - int monitor_count = gdk_display_get_n_monitors(display); - if (monitor_count == 0) { - return nullptr; - } else { - monitor = gdk_display_get_monitor(display, 0); - } - } - g_autoptr(FlValue) result_data = monitor_to_flvalue(monitor); - - return FL_METHOD_RESPONSE(fl_method_success_response_new(result_data)); -} - -static FlMethodResponse* get_all_displays(ScreenRetrieverPlugin* self, - FlValue* args) { - auto displays = fl_value_new_list(); - - GdkDisplay* display = gdk_display_get_default(); - gint n_monitors = gdk_display_get_n_monitors(display); - for (gint i = 0; i < n_monitors; i++) { - GdkMonitor* monitor = gdk_display_get_monitor(display, i); - fl_value_append_take(displays, monitor_to_flvalue(monitor)); - } - - g_autoptr(FlValue) result_data = fl_value_new_map(); - fl_value_set_string_take(result_data, "displays", displays); - - return FL_METHOD_RESPONSE(fl_method_success_response_new(result_data)); -} - -// Called when a method call is received from Flutter. -static void screen_retriever_plugin_handle_method_call( - ScreenRetrieverPlugin* self, - FlMethodCall* method_call) { - g_autoptr(FlMethodResponse) response = nullptr; - - const gchar* method = fl_method_call_get_name(method_call); - FlValue* args = fl_method_call_get_args(method_call); - if (strcmp(method, "getCursorScreenPoint") == 0) { - response = get_cursor_screen_point(self, args); - } else if (strcmp(method, "getPrimaryDisplay") == 0) { - response = get_primary_display(self, args); - } else if (strcmp(method, "getAllDisplays") == 0) { - response = get_all_displays(self, args); - } else { - response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); - } - - fl_method_call_respond(method_call, response, nullptr); -} - -static void screen_retriever_plugin_dispose(GObject* object) { - G_OBJECT_CLASS(screen_retriever_plugin_parent_class)->dispose(object); -} - -static void screen_retriever_plugin_class_init( - ScreenRetrieverPluginClass* klass) { - G_OBJECT_CLASS(klass)->dispose = screen_retriever_plugin_dispose; -} - -static void screen_retriever_plugin_init(ScreenRetrieverPlugin* self) {} - -static void method_call_cb(FlMethodChannel* channel, - FlMethodCall* method_call, - gpointer user_data) { - ScreenRetrieverPlugin* plugin = SCREEN_RETRIEVER_PLUGIN(user_data); - screen_retriever_plugin_handle_method_call(plugin, method_call); -} - -static void on_event(FlMethodChannel* channel, const gchar* name) { - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string_take(args, "eventName", fl_value_new_string(name)); - fl_method_channel_invoke_method(channel, "onEvent", args, nullptr, nullptr, - nullptr); -} - -static void monitor_added_cb(FlMethodChannel* channel) { - on_event(channel, "display-added"); -} - -static void monitor_removed_cb(FlMethodChannel* channel) { - on_event(channel, "display-removed"); -} - -void screen_retriever_plugin_register_with_registrar( - FlPluginRegistrar* registrar) { - ScreenRetrieverPlugin* plugin = SCREEN_RETRIEVER_PLUGIN( - g_object_new(screen_retriever_plugin_get_type(), nullptr)); - - plugin->registrar = FL_PLUGIN_REGISTRAR(g_object_ref(registrar)); - - g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); - g_autoptr(FlMethodChannel) channel = - fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), - "screen_retriever", FL_METHOD_CODEC(codec)); - fl_method_channel_set_method_call_handler( - channel, method_call_cb, g_object_ref(plugin), g_object_unref); - - GdkDisplay* display = gdk_display_get_default(); - g_signal_connect_object(display, "monitor-added", - G_CALLBACK(monitor_added_cb), channel, - G_CONNECT_SWAPPED); - g_signal_connect_object(display, "monitor-removed", - G_CALLBACK(monitor_removed_cb), channel, - G_CONNECT_SWAPPED); - - g_object_unref(plugin); -} diff --git a/macos/Classes/ScreenRetrieverPlugin.swift b/macos/Classes/ScreenRetrieverPlugin.swift deleted file mode 100644 index 1c1f86c..0000000 --- a/macos/Classes/ScreenRetrieverPlugin.swift +++ /dev/null @@ -1,116 +0,0 @@ -import Cocoa -import FlutterMacOS - -extension NSScreen { - var displayID: CGDirectDisplayID { - return deviceDescription[NSDeviceDescriptionKey(rawValue: "NSScreenNumber")] as? CGDirectDisplayID ?? 0 - } -} - -extension NSRect { - var topLeft: CGPoint { - set { - let screenFrameRect = NSScreen.screens[0].frame - origin.x = newValue.x - origin.y = screenFrameRect.height - newValue.y - size.height - } - get { - let screenFrameRect = NSScreen.screens[0].frame - return CGPoint(x: origin.x, y: screenFrameRect.height - origin.y - size.height) - } - } -} - -public class ScreenRetrieverPlugin: NSObject, FlutterPlugin { - var registrar: FlutterPluginRegistrar!; - var channel: FlutterMethodChannel! - - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "screen_retriever", binaryMessenger: registrar.messenger) - let instance = ScreenRetrieverPlugin() - instance.registrar = registrar - instance.channel = channel - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch (call.method) { - case "getCursorScreenPoint": - getCursorScreenPoint(call, result: result) - break - case "getPrimaryDisplay": - getPrimaryDisplay(call, result: result) - break - case "getAllDisplays": - getAllDisplays(call, result: result) - break - default: - result(FlutterMethodNotImplemented) - } - } - - public func _screenToDict(_ screen: NSScreen) -> NSDictionary { - var name: String = ""; - if #available(macOS 10.15, *) { - name = screen.localizedName - } - let size: NSDictionary = [ - "width": screen.frame.width, - "height": screen.frame.height, - ] - let visiblePosition: NSDictionary = [ - "x": screen.visibleFrame.topLeft.x, - "y": screen.visibleFrame.topLeft.y, - ] - let visibleSize: NSDictionary = [ - "width": screen.visibleFrame.width, - "height": screen.visibleFrame.height, - ] - let dict: NSDictionary = [ - "id": screen.displayID, - "name": name, - "size": size, - "visiblePosition": visiblePosition, - "visibleSize": visibleSize, - ] - return dict; - } - - public func getCursorScreenPoint(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - let currentScreen = NSScreen.main! - let mouseLocation: NSPoint = NSEvent.mouseLocation; - - var visibleHeight = currentScreen.frame.maxY - for screen in NSScreen.screens { - if (visibleHeight > screen.frame.maxY) { - visibleHeight = screen.frame.maxY - } - } - let resultData: NSDictionary = [ - "x": mouseLocation.x, - "y": visibleHeight - mouseLocation.y, - ] - result(resultData) - } - - public func getPrimaryDisplay(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - let resultData: NSDictionary = _screenToDict(NSScreen.screens[0]) - result(resultData) - } - - public func getAllDisplays(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - let resultData: NSDictionary = [ - "displays": NSScreen.screens.map({ screen in - return _screenToDict(screen) - }), - ] - result(resultData) - } - - public func _emitEvent(_ eventName: String) { - let args: NSDictionary = [ - "eventName": eventName, - ] - channel.invokeMethod("onEvent", arguments: args, result: nil) - } -} diff --git a/macos/screen_retriever.podspec b/macos/screen_retriever.podspec deleted file mode 100644 index a91f2ef..0000000 --- a/macos/screen_retriever.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint screen_retriever.podspec` to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'screen_retriever' - s.version = '0.0.1' - s.summary = 'A new flutter plugin project.' - s.description = <<-DESC -A new flutter plugin project. - DESC - s.homepage = 'https://leanflutter.org' - s.license = { :file => '../LICENSE' } - s.author = { 'LiJianying' => 'lijy91@foxmail.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.dependency 'FlutterMacOS' - - s.platform = :osx, '10.11' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } - s.swift_version = '5.0' -end diff --git a/melos.yaml b/melos.yaml index e951e6c..f933370 100644 --- a/melos.yaml +++ b/melos.yaml @@ -1,5 +1,5 @@ -name: shortcut_menu_extender -repository: https://github.com/leanflutter/shortcut_menu_extender +name: screen_retriever_workspace +repository: https://github.com/leanflutter/screen_retriever packages: - examples/** @@ -33,9 +33,3 @@ scripts: fix: exec: dart fix . --apply description: Run `dart fix` for all packages. - - dependency_validator: - exec: flutter pub run dependency_validator - packageFilters: - dependsOn: - - dependency_validator diff --git a/packages/screen_retriever/example/test/widget_test.dart b/packages/screen_retriever/example/test/widget_test.dart deleted file mode 100644 index 2afd585..0000000 --- a/packages/screen_retriever/example/test/widget_test.dart +++ /dev/null @@ -1,27 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:screen_retriever_example/main.dart'; - -void main() { - testWidgets('Verify Platform version', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that platform version is retrieved. - expect( - find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data!.startsWith('Running on:'), - ), - findsOneWidget, - ); - }); -} diff --git a/packages/screen_retriever/test/screen_retriever_test.dart b/packages/screen_retriever/test/screen_retriever_test.dart index d3c2959..437a2af 100644 --- a/packages/screen_retriever/test/screen_retriever_test.dart +++ b/packages/screen_retriever/test/screen_retriever_test.dart @@ -3,22 +3,38 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:screen_retriever/screen_retriever.dart'; +final _fakeDisplayJson = { + 'id': 0, + 'name': 'fakeDisplay', + 'size': {'width': 1920.0, 'height': 1080.0}, + 'visiblePosition': {'dx': 0.0, 'dy': 0.0}, + 'visibleSize': {'width': 1280.0, 'height': 720.0}, + 'scaleFactor': 1, +}; + class MockScreenRetrieverPlatform with MockPlatformInterfaceMixin implements ScreenRetrieverPlatform { @override Future getCursorScreenPoint() { - return Future(() => Offset.zero); + return Future(() => const Offset(10.0, 10.0)); } @override Future> getAllDisplays() { - throw UnimplementedError(); + return Future( + () => [ + Display.fromJson(_fakeDisplayJson), + Display.fromJson(_fakeDisplayJson), + ], + ); } @override Future getPrimaryDisplay() { - throw UnimplementedError(); + return Future( + () => Display.fromJson(_fakeDisplayJson), + ); } } @@ -37,6 +53,52 @@ void main() { MockScreenRetrieverPlatform fakePlatform = MockScreenRetrieverPlatform(); ScreenRetrieverPlatform.instance = fakePlatform; - expect(await screenRetriever.getCursorScreenPoint(), Offset.zero); + expect( + await screenRetriever.getCursorScreenPoint(), + const Offset(10.0, 10.0), + ); + }); + + group(ScreenRetriever, () { + MockScreenRetrieverPlatform fakePlatform = MockScreenRetrieverPlatform(); + ScreenRetrieverPlatform.instance = fakePlatform; + final screenRetriever = ScreenRetriever.instance; + + test('should correctly parse output when calling getCursorScreenPoint', + () async { + Offset resultData = await screenRetriever.getCursorScreenPoint(); + expect(resultData.dx, 10); + expect(resultData.dy, 10); + }); + + test('should correctly parse output when calling getPrimaryDisplay', + () async { + Display primaryDisplay = await screenRetriever.getPrimaryDisplay(); + + expect(primaryDisplay.id, 0); + expect(primaryDisplay.name, 'fakeDisplay'); + expect(primaryDisplay.size.width, 1920.0); + expect(primaryDisplay.size.height, 1080.0); + expect(primaryDisplay.visiblePosition!.dx, 0.0); + expect(primaryDisplay.visiblePosition!.dy, 0.0); + expect(primaryDisplay.visibleSize!.width, 1280.0); + expect(primaryDisplay.visibleSize!.height, 720.0); + expect(primaryDisplay.scaleFactor, 1); + }); + + test('should correctly parse output when calling getAllDisplays', () async { + List displayList = await screenRetriever.getAllDisplays(); + + expect(displayList.length, 2); + expect(displayList[0].id, 0); + expect(displayList[0].name, 'fakeDisplay'); + expect(displayList[0].size.width, 1920.0); + expect(displayList[0].size.height, 1080.0); + expect(displayList[0].visiblePosition!.dx, 0.0); + expect(displayList[0].visiblePosition!.dy, 0.0); + expect(displayList[0].visibleSize!.width, 1280.0); + expect(displayList[0].visibleSize!.height, 720.0); + expect(displayList[0].scaleFactor, 1); + }); }); } diff --git a/packages/screen_retriever_macos/pubspec.yaml b/packages/screen_retriever_macos/pubspec.yaml index 85af375..374df99 100644 --- a/packages/screen_retriever_macos/pubspec.yaml +++ b/packages/screen_retriever_macos/pubspec.yaml @@ -1,7 +1,7 @@ name: screen_retriever_macos description: macOS implementation of the screen_retriever plugin. version: 0.2.0 -repository: https://github.com/leanflutter/screen_retriever/tree/main/packages/screen_retriever/screen_retriever_macos +repository: https://github.com/leanflutter/screen_retriever/tree/main/packages/screen_retriever_macos environment: sdk: ">=3.0.0 <4.0.0" diff --git a/pubspec.lock b/pubspec.lock index 77ae44b..420c09e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,22 +33,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" charcode: dependency: transitive description: @@ -57,14 +41,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff - url: "https://pub.dev" - source: hosted - version: "2.0.3" cli_launcher: dependency: transitive description: @@ -81,14 +57,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.1" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" collection: dependency: transitive description: @@ -105,22 +73,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.0+1" - dependency_validator: - dependency: "direct dev" - description: - name: dependency_validator - sha256: "08349175533ed0bd06eb9b6043cde66c45b2bfc7ebc222a7542cdb1324f1bf03" - url: "https://pub.dev" - source: hosted - version: "3.2.2" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" file: dependency: transitive description: @@ -129,24 +81,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.4" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" glob: dependency: transitive description: @@ -195,22 +129,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" - lints: - dependency: transitive - description: - name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - logging: - dependency: transitive - description: - name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" - source: hosted - version: "1.2.0" matcher: dependency: transitive description: @@ -219,14 +137,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.12.16" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" - url: "https://pub.dev" - source: hosted - version: "0.5.0" melos: dependency: "direct dev" description: @@ -251,14 +161,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - package_config: - dependency: transitive - description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" path: dependency: transitive description: @@ -323,14 +225,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 - url: "https://pub.dev" - source: hosted - version: "1.2.3" quiver: dependency: transitive description: @@ -339,11 +233,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" source_span: dependency: transitive description: @@ -408,14 +297,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" web: dependency: transitive description: @@ -442,4 +323,3 @@ packages: version: "2.1.1" sdks: dart: ">=3.2.0 <4.0.0" - flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 46f8808..7854601 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,35 +1,9 @@ -name: screen_retriever -description: This plugin allows Flutter desktop apps to Retrieve information about screen size, displays, cursor position, etc. -version: 0.1.9 +name: screen_retriever_workspace homepage: https://github.com/leanflutter/screen_retriever - -platforms: - linux: - macos: - windows: +publish_to: none environment: - sdk: ">=2.18.0 <4.0.0" - flutter: ">=3.3.0" - -dependencies: - flutter: - sdk: flutter + sdk: ">=3.0.0 <4.0.0" dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^2.0.0 - - dependency_validator: ^3.0.0 melos: ^3.1.0 - -flutter: - plugin: - platforms: - linux: - pluginClass: ScreenRetrieverPlugin - macos: - pluginClass: ScreenRetrieverPlugin - windows: - pluginClass: ScreenRetrieverPlugin diff --git a/test/screen_retriever_test.dart b/test/screen_retriever_test.dart deleted file mode 100644 index 9d4920f..0000000 --- a/test/screen_retriever_test.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:screen_retriever/screen_retriever.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - final fakeDisplay = { - 'id': 0, - 'name': 'fakeDisplay', - 'size': {'width': 1920.0, 'height': 1080.0}, - 'visiblePosition': {'x': 0.0, 'y': 0.0}, - 'visibleSize': {'width': 1280.0, 'height': 720.0}, - 'scaleFactor': 1, - }; - final fakeCursorScreenPoint = {'x': 10.0, 'y': 10.0}; - - group(ScreenRetriever, () { - final screenRetriever = ScreenRetriever.instance; - - late MethodCall lastMethodCall; - dynamic mockMethodCallReturnValue; - - Future handleMockMethodCall(MethodCall methodCall) async { - lastMethodCall = methodCall; - return mockMethodCallReturnValue; - } - - setUp(() { - TestDefaultBinaryMessengerBinding - .instance // wrap - .defaultBinaryMessenger - .setMockMethodCallHandler( - screenRetriever.channel, handleMockMethodCall); - }); - - tearDown(() { - TestDefaultBinaryMessengerBinding - .instance // wrap - .defaultBinaryMessenger - .setMockMethodCallHandler(screenRetriever.channel, null); - }); - - test('should correctly parse output when calling getCursorScreenPoint', - () async { - mockMethodCallReturnValue = fakeCursorScreenPoint; - - Offset resultData = await screenRetriever.getCursorScreenPoint(); - - expect(lastMethodCall.method, 'getCursorScreenPoint'); - expect(resultData.dx, 10); - expect(resultData.dy, 10); - }); - - test('should correctly parse output when calling getPrimaryDisplay', - () async { - mockMethodCallReturnValue = fakeDisplay; - - Display resultData = await screenRetriever.getPrimaryDisplay(); - - expect(lastMethodCall.method, 'getPrimaryDisplay'); - expect(resultData.id, 0); - expect(resultData.name, 'fakeDisplay'); - expect(resultData.size.width, 1920.0); - expect(resultData.size.height, 1080.0); - expect(resultData.visiblePosition!.dx, 0.0); - expect(resultData.visiblePosition!.dy, 0.0); - expect(resultData.visibleSize!.width, 1280.0); - expect(resultData.visibleSize!.height, 720.0); - expect(resultData.scaleFactor, 1); - }); - - test('should correctly parse output when calling getAllDisplays', () async { - mockMethodCallReturnValue = { - 'displays': [fakeDisplay, fakeDisplay] - }; - - List resultData = await screenRetriever.getAllDisplays(); - - expect(lastMethodCall.method, 'getAllDisplays'); - expect(resultData.length, 2); - expect(resultData[0].id, 0); - expect(resultData[0].name, 'fakeDisplay'); - expect(resultData[0].size.width, 1920.0); - expect(resultData[0].size.height, 1080.0); - expect(resultData[0].visiblePosition!.dx, 0.0); - expect(resultData[0].visiblePosition!.dy, 0.0); - expect(resultData[0].visibleSize!.width, 1280.0); - expect(resultData[0].visibleSize!.height, 720.0); - expect(resultData[0].scaleFactor, 1); - }); - }); -} diff --git a/windows/.gitignore b/windows/.gitignore deleted file mode 100644 index 808064a..0000000 --- a/windows/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -flutter/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt deleted file mode 100644 index 7a5c329..0000000 --- a/windows/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required(VERSION 3.15) -set(PROJECT_NAME "screen_retriever") -project(${PROJECT_NAME} LANGUAGES CXX) - -# This value is used when generating builds using this plugin, so it must -# not be changed -set(PLUGIN_NAME "screen_retriever_plugin") - -add_library(${PLUGIN_NAME} SHARED - "screen_retriever_plugin.cpp" -) -apply_standard_settings(${PLUGIN_NAME}) -set_target_properties(${PLUGIN_NAME} PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) -target_compile_definitions(${PLUGIN_NAME} PRIVATE _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) -target_include_directories(${PLUGIN_NAME} INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) - -# List of absolute paths to libraries that should be bundled with the plugin -set(screen_retriever_bundled_libraries - "" - PARENT_SCOPE -) diff --git a/windows/include/screen_retriever/screen_retriever_plugin.h b/windows/include/screen_retriever/screen_retriever_plugin.h deleted file mode 100644 index 815e606..0000000 --- a/windows/include/screen_retriever/screen_retriever_plugin.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef FLUTTER_PLUGIN_SCREEN_RETRIEVER_PLUGIN_H_ -#define FLUTTER_PLUGIN_SCREEN_RETRIEVER_PLUGIN_H_ - -#include - -#ifdef FLUTTER_PLUGIN_IMPL -#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) -#else -#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -FLUTTER_PLUGIN_EXPORT void ScreenRetrieverPluginRegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar); - -#if defined(__cplusplus) -} // extern "C" -#endif - -#endif // FLUTTER_PLUGIN_SCREEN_RETRIEVER_PLUGIN_H_ diff --git a/windows/screen_retriever_plugin.cpp b/windows/screen_retriever_plugin.cpp deleted file mode 100644 index 616e3be..0000000 --- a/windows/screen_retriever_plugin.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include "include/screen_retriever/screen_retriever_plugin.h" - -// This must be included before many other Windows headers. -#include - -#include -#include -#include - -#include -#include -#include -#include - -const double kBaseDpi = 96.0; - -namespace { -std::unique_ptr< - flutter::MethodChannel, - std::default_delete>> - channel = nullptr; - -class ScreenRetrieverPlugin : public flutter::Plugin { - public: - static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); - - ScreenRetrieverPlugin(); - - virtual ~ScreenRetrieverPlugin(); - - private: - flutter::PluginRegistrarWindows* registrar; - - void ScreenRetrieverPlugin::_EmitEvent(std::string eventName); - - HWND ScreenRetrieverPlugin::GetMainWindow(); - void ScreenRetrieverPlugin::GetCursorScreenPoint( - const flutter::MethodCall& method_call, - std::unique_ptr> result); - void ScreenRetrieverPlugin::GetPrimaryDisplay( - const flutter::MethodCall& method_call, - std::unique_ptr> result); - void ScreenRetrieverPlugin::GetAllDisplays( - const flutter::MethodCall& method_call, - std::unique_ptr> result); - // Called when a method is called on this plugin's channel from Dart. - void HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result); -}; - -// static -void ScreenRetrieverPlugin::RegisterWithRegistrar( - flutter::PluginRegistrarWindows* registrar) { - channel = std::make_unique>( - registrar->messenger(), "screen_retriever", - &flutter::StandardMethodCodec::GetInstance()); - - auto plugin = std::make_unique(); - - channel->SetMethodCallHandler( - [plugin_pointer = plugin.get()](const auto& call, auto result) { - plugin_pointer->HandleMethodCall(call, std::move(result)); - }); - - registrar->AddPlugin(std::move(plugin)); -} - -ScreenRetrieverPlugin::ScreenRetrieverPlugin() {} - -ScreenRetrieverPlugin::~ScreenRetrieverPlugin() {} - -void ScreenRetrieverPlugin::_EmitEvent(std::string eventName) { - flutter::EncodableMap args = flutter::EncodableMap(); - args[flutter::EncodableValue("eventName")] = - flutter::EncodableValue(eventName); - channel->InvokeMethod("onEvent", - std::make_unique(args)); -} - -HWND ScreenRetrieverPlugin::GetMainWindow() { - return ::GetAncestor(registrar->GetView()->GetNativeWindow(), GA_ROOT); -} - -flutter::EncodableMap MonitorToEncodableMap(HMONITOR monitor) { - std::wstring_convert> converter; - - MONITORINFOEX info; - info.cbSize = sizeof(MONITORINFOEX); - ::GetMonitorInfo(monitor, &info); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - - wchar_t display_name[sizeof(info.szDevice) / sizeof(*info.szDevice) + 1]; - memset(display_name, 0, sizeof(display_name)); - memcpy(display_name, info.szDevice, sizeof(info.szDevice)); - - double scale_factor = dpi / kBaseDpi; - - double visibleWidth = - round((info.rcWork.right - info.rcWork.left) / scale_factor); - double visibleHeight = - round((info.rcWork.bottom - info.rcWork.top) / scale_factor); - - double visibleX = round((info.rcWork.left) / scale_factor); - double visibleY = round((info.rcWork.top) / scale_factor); - - flutter::EncodableMap size = flutter::EncodableMap(); - flutter::EncodableMap visibleSize = flutter::EncodableMap(); - flutter::EncodableMap visiblePosition = flutter::EncodableMap(); - - size[flutter::EncodableValue("width")] = - flutter::EncodableValue(static_cast( - round(info.rcMonitor.right / scale_factor - visibleX))); - size[flutter::EncodableValue("height")] = - flutter::EncodableValue(static_cast( - round(info.rcMonitor.bottom / scale_factor - visibleY))); - - visibleSize[flutter::EncodableValue("width")] = - flutter::EncodableValue(visibleWidth); - visibleSize[flutter::EncodableValue("height")] = - flutter::EncodableValue(visibleHeight); - - visiblePosition[flutter::EncodableValue("x")] = - flutter::EncodableValue(visibleX); - visiblePosition[flutter::EncodableValue("y")] = - flutter::EncodableValue(visibleY); - - flutter::EncodableMap display = flutter::EncodableMap(); - - display[flutter::EncodableValue("id")] = flutter::EncodableValue(0); - display[flutter::EncodableValue("name")] = - flutter::EncodableValue(converter.to_bytes(display_name).c_str()); - display[flutter::EncodableValue("size")] = flutter::EncodableValue(size); - display[flutter::EncodableValue("visibleSize")] = - flutter::EncodableValue(visibleSize); - display[flutter::EncodableValue("visiblePosition")] = - flutter::EncodableValue(visiblePosition); - display[flutter::EncodableValue("scaleFactor")] = - flutter::EncodableValue(scale_factor); - - return display; -} - -BOOL CALLBACK MonitorRepresentationEnumProc(HMONITOR monitor, - HDC hdc, - LPRECT clip, - LPARAM list_ref) { - flutter::EncodableValue* monitors = - reinterpret_cast(list_ref); - flutter::EncodableMap display = MonitorToEncodableMap(monitor); - std::get(*monitors).push_back( - flutter::EncodableValue(display)); - return TRUE; -} - -void ScreenRetrieverPlugin::GetCursorScreenPoint( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - - double device_pixel_ratio = - std::get(args.at(flutter::EncodableValue("devicePixelRatio"))); - - double x, y; - POINT cursorPos; - GetCursorPos(&cursorPos); - x = cursorPos.x / device_pixel_ratio * 1.0f; - y = cursorPos.y / device_pixel_ratio * 1.0f; - - flutter::EncodableMap result_data = flutter::EncodableMap(); - result_data[flutter::EncodableValue("x")] = flutter::EncodableValue(x); - result_data[flutter::EncodableValue("y")] = flutter::EncodableValue(y); - - result->Success(flutter::EncodableValue(result_data)); -} - -void ScreenRetrieverPlugin::GetPrimaryDisplay( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { - POINT ptZero = {0, 0}; - HMONITOR monitor = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY); - flutter::EncodableMap display = MonitorToEncodableMap(monitor); - result->Success(flutter::EncodableValue(display)); -} - -void ScreenRetrieverPlugin::GetAllDisplays( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { - flutter::EncodableValue displays(std::in_place_type); - - ::EnumDisplayMonitors(nullptr, nullptr, MonitorRepresentationEnumProc, - reinterpret_cast(&displays)); - - flutter::EncodableMap result_data = flutter::EncodableMap(); - result_data[flutter::EncodableValue("displays")] = displays; - - result->Success(flutter::EncodableValue(result_data)); -} - -void ScreenRetrieverPlugin::HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { - if (method_call.method_name().compare("getCursorScreenPoint") == 0) { - GetCursorScreenPoint(method_call, std::move(result)); - } else if (method_call.method_name().compare("getPrimaryDisplay") == 0) { - GetPrimaryDisplay(method_call, std::move(result)); - } else if (method_call.method_name().compare("getAllDisplays") == 0) { - GetAllDisplays(method_call, std::move(result)); - } else { - result->NotImplemented(); - } -} - -} // namespace - -void ScreenRetrieverPluginRegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar) { - ScreenRetrieverPlugin::RegisterWithRegistrar( - flutter::PluginRegistrarManager::GetInstance() - ->GetRegistrar(registrar)); -}