Skip to content

Commit

Permalink
Merge pull request #98 from tomaszpolanski/enable-full-screen-on-desktop
Browse files Browse the repository at this point in the history
feat: enable full screen on desktop
  • Loading branch information
mkobuolys authored Aug 27, 2024
2 parents 5e79559 + 8a587b2 commit 9a78ac3
Show file tree
Hide file tree
Showing 20 changed files with 351 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@

#include "generated_plugin_registrant.h"

#include <screen_retriever/screen_retriever_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h>

void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
g_autoptr(FlPluginRegistrar) window_manager_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
window_manager_plugin_register_with_registrar(window_manager_registrar);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
screen_retriever
url_launcher_linux
window_manager
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
import FlutterMacOS
import Foundation

import screen_retriever
import url_launcher_macos
import window_manager

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
}
14 changes: 13 additions & 1 deletion packages/flutter_deck/example/macos/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
PODS:
- FlutterMacOS (1.0.0)
- screen_retriever (0.0.1):
- FlutterMacOS
- url_launcher_macos (0.0.1):
- FlutterMacOS
- window_manager (0.2.0):
- FlutterMacOS

DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)

EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
screen_retriever:
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
window_manager:
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos

SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8

PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Cocoa
import FlutterMacOS

@NSApplicationMain
@main
class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@

#include "generated_plugin_registrant.h"

#include <screen_retriever/screen_retriever_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
#include <window_manager/window_manager_plugin.h>

void RegisterPlugins(flutter::PluginRegistry* registry) {
ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
WindowManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
screen_retriever
url_launcher_windows
window_manager
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down
40 changes: 24 additions & 16 deletions packages/flutter_deck/lib/src/controls/flutter_deck_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -468,22 +468,30 @@ class _FullscreenButton extends StatelessWidget {
final controlsNotifier = flutterDeck.controlsNotifier;
final markerNotifier = flutterDeck.markerNotifier;

final isInFullscreen = controlsNotifier.isInFullscreen();
final onPressed = isInFullscreen
? controlsNotifier.leaveFullscreen
: controlsNotifier.enterFullscreen;

return ListenableBuilder(
listenable: markerNotifier,
builder: (context, _) => MenuItemButton(
leadingIcon: Icon(
isInFullscreen
? Icons.fullscreen_exit_rounded
: Icons.fullscreen_rounded,
),
onPressed: !markerNotifier.enabled ? onPressed : null,
child: Text(isInFullscreen ? 'Leave full screen' : 'Enter full screen'),
),
return FutureBuilder(
future: controlsNotifier.isInFullscreen(),
initialData: false,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
final isInFullscreen = snapshot.data ?? false;
final onPressed = isInFullscreen
? controlsNotifier.leaveFullscreen
: controlsNotifier.enterFullscreen;

return ListenableBuilder(
listenable: markerNotifier,
builder: (context, _) => MenuItemButton(
leadingIcon: Icon(
isInFullscreen
? Icons.fullscreen_exit_rounded
: Icons.fullscreen_rounded,
),
onPressed: !markerNotifier.enabled ? onPressed : null,
child: Text(
isInFullscreen ? 'Leave full screen' : 'Enter full screen',
),
),
);
},
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import 'package:flutter_deck/src/widgets/internal/marker/marker.dart';
/// deck controls visibility.
class FlutterDeckControlsNotifier
with ChangeNotifier
implements FlutterDeckFullscreenManagerBase {
implements FlutterDeckFullscreenManager {
/// Creates a [FlutterDeckControlsNotifier].
FlutterDeckControlsNotifier({
required FlutterDeckAutoplayNotifier autoplayNotifier,
required FlutterDeckDrawerNotifier drawerNotifier,
required FlutterDeckMarkerNotifier markerNotifier,
required FlutterDeckFullscreenManagerBase fullscreenManager,
required FlutterDeckFullscreenManager fullscreenManager,
required FlutterDeckRouter router,
}) : _autoplayNotifier = autoplayNotifier,
_drawerNotifier = drawerNotifier,
Expand All @@ -29,7 +29,7 @@ class FlutterDeckControlsNotifier
final FlutterDeckAutoplayNotifier _autoplayNotifier;
final FlutterDeckDrawerNotifier _drawerNotifier;
final FlutterDeckMarkerNotifier _markerNotifier;
final FlutterDeckFullscreenManagerBase _fullscreenManager;
final FlutterDeckFullscreenManager _fullscreenManager;
final FlutterDeckRouter _router;

var _controlsVisible = false;
Expand Down Expand Up @@ -101,13 +101,13 @@ class FlutterDeckControlsNotifier
bool canFullscreen() => _fullscreenManager.canFullscreen();

@override
bool isInFullscreen() => _fullscreenManager.isInFullscreen();
Future<bool> isInFullscreen() => _fullscreenManager.isInFullscreen();

@override
void enterFullscreen() => _fullscreenManager.enterFullscreen();
Future<void> enterFullscreen() => _fullscreenManager.enterFullscreen();

@override
void leaveFullscreen() => _fullscreenManager.leaveFullscreen();
Future<void> leaveFullscreen() => _fullscreenManager.leaveFullscreen();

/// Show the cursor and controls.
///
Expand Down
47 changes: 33 additions & 14 deletions packages/flutter_deck/lib/src/controls/fullscreen/fullscreen.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,44 @@
export 'stub.dart'
if (dart.library.io) 'io.dart'
if (dart.library.html) 'web.dart';
import 'package:flutter_deck/src/controls/fullscreen/window_proxy/window_proxy.dart';

/// Describes a collection of functions that can mutate and retrieve
/// the application's fullscreen state.
abstract class FlutterDeckFullscreenManagerBase {
class FlutterDeckFullscreenManager {
/// Default constructor for [FlutterDeckFullscreenManager].
///
/// The [windowProxy] is required for getting and setting window properties
/// from underlying platform.
FlutterDeckFullscreenManager(WindowProxyBase windowProxy)
: _windowProxy = windowProxy;

final WindowProxyBase _windowProxy;
bool _initialized = false;

Future<WindowProxyBase> get _instance async {
if (!_initialized) {
await _windowProxy.initialize();
_initialized = true;
}
return _windowProxy;
}

/// Returns whether or not this platform has support to enter/leave fullscreen
bool canFullscreen() => false;
bool canFullscreen() => _windowProxy.canFullscreen();

/// Returns whether or not the application is currently fullscreen
bool isInFullscreen() => throw UnsupportedError(
'isInFullscreen cannot be called on this platform',
);
Future<bool> isInFullscreen() async {
final windowProxy = await _instance;
return windowProxy.isInFullscreen();
}

/// Application enters fullscreen
void enterFullscreen() => throw UnsupportedError(
'enterFullscreen cannot be called on this platform',
);
Future<void> enterFullscreen() async {
final windowProxy = await _instance;
await windowProxy.enterFullscreen();
}

/// Application leaves fullscreen
void leaveFullscreen() => throw UnsupportedError(
'leaveFullscreen cannot be called on this platform',
);
Future<void> leaveFullscreen() async {
final windowProxy = await _instance;
await windowProxy.leaveFullscreen();
}
}
4 changes: 0 additions & 4 deletions packages/flutter_deck/lib/src/controls/fullscreen/io.dart

This file was deleted.

4 changes: 0 additions & 4 deletions packages/flutter_deck/lib/src/controls/fullscreen/stub.dart

This file was deleted.

21 changes: 0 additions & 21 deletions packages/flutter_deck/lib/src/controls/fullscreen/web.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'dart:io';

import 'package:flutter_deck/src/controls/fullscreen/window_proxy/window_proxy.dart';
import 'package:window_manager/window_manager.dart';

/// The dart:io implementation of [WindowProxyBase].
class WindowProxy implements WindowProxyBase {
@override
Future<void> initialize() => windowManager.ensureInitialized();

@override
bool canFullscreen() =>
Platform.isLinux || Platform.isWindows || Platform.isMacOS;

@override
Future<bool> isInFullscreen() => windowManager.isFullScreen();

@override
Future<void> enterFullscreen() => windowManager.setFullScreen(true);

@override
Future<void> leaveFullscreen() => windowManager.setFullScreen(false);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter_deck/src/controls/fullscreen/window_proxy/window_proxy.dart';

/// The stub implementation of [WindowProxyBase].
class WindowProxy implements WindowProxyBase {
@override
Future<void> initialize() => throw UnsupportedError(
'initialize cannot be called on this platform',
);

/// Returns whether or not this platform has support to enter/leave fullscreen
@override
bool canFullscreen() => false;

/// Returns whether or not the application is currently fullscreen
@override
Future<bool> isInFullscreen() => throw UnsupportedError(
'isInFullscreen cannot be called on this platform',
);

/// Application enters fullscreen
@override
Future<void> enterFullscreen() => throw UnsupportedError(
'enterFullscreen cannot be called on this platform',
);

/// Application leaves fullscreen
@override
Future<void> leaveFullscreen() => throw UnsupportedError(
'leaveFullscreen cannot be called on this platform',
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is conditionally included when compiling to web.
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;

import 'package:flutter_deck/src/controls/fullscreen/window_proxy/window_proxy.dart';

/// The web implementation of [WindowProxyBase].
class WindowProxy implements WindowProxyBase {
@override
Future<void> initialize() async {
// No need for initialization
}

@override
bool canFullscreen() => true;

@override
Future<bool> isInFullscreen() async =>
html.window.document.fullscreenElement != null;

@override
Future<void> enterFullscreen() async =>
html.window.document.documentElement?.requestFullscreen();

@override
Future<void> leaveFullscreen() async => html.window.document.exitFullscreen();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export '_stub.dart'
if (dart.library.io) '_io.dart'
if (dart.library.html) '_web.dart';

/// Thin proxy/wrapper around platform specific window API implementation
abstract class WindowProxyBase {
/// Initializes window API
Future<void> initialize();

/// Returns whether or not this platform has support to enter/leave fullscreen
bool canFullscreen();

/// Application enters fullscreen
Future<void> enterFullscreen();

/// Returns whether or not the application is currently fullscreen
Future<bool> isInFullscreen();

/// Application leaves fullscreen
Future<void> leaveFullscreen();
}
Loading

0 comments on commit 9a78ac3

Please sign in to comment.