Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions lib/src/legacy/window_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import 'dart:async';
import 'dart:io';
import 'dart:ui' show Brightness, Color, Offset, PlatformDispatcher, Rect, Size;

import 'package:flutter/foundation.dart' show ObserverList, VoidCallback;
import 'package:flutter/foundation.dart'
show ObserverList, VoidCallback, visibleForTesting;
import 'package:flutter/painting.dart' show Alignment;
import 'package:nativeapi/nativeapi.dart' as nativeapi;
import 'package:nativeapi_flutter/nativeapi_flutter.dart'
Expand Down Expand Up @@ -66,6 +67,15 @@ class WindowManager {
nativeapi.Window? _window;
nativeapi.ListenerId? _nativeListenerId;

/// Addresses [window] instead of the platform's current window, or goes
/// back to the current window with null. For tests of this bridge only.
@visibleForTesting
void debugBindWindow(nativeapi.Window? window) {
_unwireNativeEvents();
_window = window;
if (_listeners.isNotEmpty || _isPreventClose) _wireNativeEvents();
}

bool _isPreventClose = false;
bool _isDestroying = false;
bool _isMaximized = false;
Expand Down Expand Up @@ -791,10 +801,10 @@ class WindowManager {
case nativeapi.WindowMovedEvent():
_emit(kWindowEventMove);
_emit(kWindowEventMoved);
case nativeapi.WindowCreatedEvent():
case nativeapi.WindowClosedEvent():
case nativeapi.WindowPropertyChangedEvent():
case nativeapi.WindowOcclusionChangedEvent():
// Created, closed, property and occlusion changes have no 0.5.x
// counterpart. A default rather than a list keeps this switch compiling
// when a nativeapi 0.5.x release adds a WindowEvent subclass.
default:
break;
}
}
Expand Down
86 changes: 86 additions & 0 deletions test/legacy_event_compat_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// How package:window_manager/legacy.dart treats nativeapi window events that
// 0.5.x had no counterpart for.
// ignore_for_file: deprecated_member_use_from_same_package

import 'dart:async';

import 'package:flutter_test/flutter_test.dart';
import 'package:nativeapi/nativeapi.dart' as nativeapi;
import 'package:window_manager/legacy.dart';

class _Recorder with WindowListener {
final List<String> events = <String>[];

@override
void onWindowEvent(String eventName) => events.add(eventName);
}

// A nativeapi window simulated in Dart; no native window is created.
class _FakeNativeWindow extends nativeapi.Window {
_FakeNativeWindow() : super.borrowed(0);

FutureOr<void> Function(nativeapi.WindowEvent)? _callback;

@override
bool get isMinimized => false;

@override
bool get isMaximized => false;

@override
bool get isFullScreen => false;

@override
nativeapi.ListenerId addListener(
FutureOr<void> Function(nativeapi.WindowEvent) listener,
) {
_callback = listener;
return 1;
}

@override
bool removeListener(nativeapi.ListenerId id) {
_callback = null;
return true;
}

Future<void> fire(nativeapi.WindowEvent event) async {
await _callback?.call(event);
}
}

void main() {
late _FakeNativeWindow fake;
late _Recorder listener;

setUp(() {
fake = _FakeNativeWindow();
listener = _Recorder();
windowManager.debugBindWindow(fake);
windowManager.addListener(listener);
});

tearDown(() {
windowManager.removeListener(listener);
windowManager.debugBindWindow(null);
});

test('events without a 0.5.x counterpart are dropped', () async {
await fake.fire(const nativeapi.WindowCreatedEvent(windowId: 1));
await fake.fire(const nativeapi.WindowClosedEvent(windowId: 1));
await fake.fire(
const nativeapi.WindowOcclusionChangedEvent(
windowId: 1,
occlusionState: nativeapi.WindowOcclusionState.occluded,
),
);
expect(listener.events, isEmpty);
});

test('events with a 0.5.x counterpart still arrive', () async {
await fake.fire(const nativeapi.WindowFocusedEvent(windowId: 1));
await fake.fire(const nativeapi.WindowCreatedEvent(windowId: 1));
await fake.fire(const nativeapi.WindowBlurredEvent(windowId: 1));
expect(listener.events, [kWindowEventFocus, kWindowEventBlur]);
});
}