Skip to content

Commit 0170146

Browse files
Merge pull request #7 from Adrian-Samoticha/issue_5
Issue #5
2 parents 49ff02f + 9424ac1 commit 0170146

File tree

7 files changed

+281
-1
lines changed

7 files changed

+281
-1
lines changed

example/lib/main_area/command_list_provider.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:async';
22

3+
import 'package:macos_window_utils/macos/ns_window_level.dart';
34
import 'package:macos_window_utils/macos/ns_window_toolbar_style.dart';
45
import 'package:macos_window_utils/macos/ns_visual_effect_view_material.dart';
56
import 'package:macos_window_utils/macos/ns_visual_effect_view_state.dart';
@@ -332,6 +333,49 @@ class CommandListProvider {
332333
'subtitle.',
333334
function: () => WindowManipulator.setSubtitle(''),
334335
),
336+
Command(
337+
name: 'setLevel(NSWindowLevel.floating)',
338+
description: 'Sets the window to appear in front of all normal-level '
339+
'windows.',
340+
function: () => WindowManipulator.setLevel(NSWindowLevel.floating),
341+
),
342+
Command(
343+
name: 'setLevel(NSWindowLevel.normal.withOffset(-1))',
344+
description: 'Sets the window to appear in behind all normal-level '
345+
'windows.',
346+
function: () =>
347+
WindowManipulator.setLevel(NSWindowLevel.normal.withOffset(-1)),
348+
),
349+
Command(
350+
name: 'setLevel(NSWindowLevel.normal)',
351+
description: 'Resets the window\'s level to the default value.',
352+
function: () => WindowManipulator.setLevel(NSWindowLevel.normal),
353+
),
354+
Command(
355+
name: 'orderOut()',
356+
description: 'Removes the window from the screen list, which hides the '
357+
'window.',
358+
function: () => WindowManipulator.orderOut(),
359+
),
360+
Command(
361+
name: 'orderBack()',
362+
description: 'Moves the window to the back of its level in the screen '
363+
'list, without changing either the key window or the main window.',
364+
function: () => WindowManipulator.orderBack(),
365+
),
366+
Command(
367+
name: 'orderFront()',
368+
description: 'Moves the window to the front of its level in the screen '
369+
'list, without changing either the key window or the main window.',
370+
function: () => WindowManipulator.orderFront(),
371+
),
372+
Command(
373+
name: 'orderFrontRegardless()',
374+
description: 'Moves the window to the front of its level, even if its '
375+
'application isn\'t active, without changing either the key window '
376+
'or the main window.',
377+
function: () => WindowManipulator.orderFrontRegardless(),
378+
),
335379
];
336380
}
337381
}

lib/macos/ns_visual_effect_view_state.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// Available `NSVisualEffectViewState` states.
1+
/// Available `NSVisualEffectViewState` values.
22
enum NSVisualEffectViewState {
33
/// The backdrop should always appear active.
44
active,

lib/macos/ns_window_level.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/// This enum maps to the `NSWindow.Level` structure in Swift.
2+
enum _Base {
3+
floating,
4+
mainMenu,
5+
modalPanel,
6+
normal,
7+
popUpMenu,
8+
screenSaver,
9+
statusBar,
10+
submenu,
11+
tornOffMenu,
12+
}
13+
14+
/// A class that represents the level of an `NSWindow`.
15+
class NSWindowLevel {
16+
final _Base _base;
17+
final int offset;
18+
19+
String get baseName => _base.name;
20+
21+
const NSWindowLevel._withValues(this._base, this.offset);
22+
23+
/// Useful for floating palettes.
24+
static NSWindowLevel floating =
25+
const NSWindowLevel._withValues(_Base.floating, 0);
26+
27+
/// Reserved for the application’s main menu.
28+
static NSWindowLevel mainMenu =
29+
const NSWindowLevel._withValues(_Base.mainMenu, 0);
30+
31+
/// The level for a modal panel.
32+
static NSWindowLevel modalPanel =
33+
const NSWindowLevel._withValues(_Base.modalPanel, 0);
34+
35+
/// The default level for NSWindow objects.
36+
static NSWindowLevel normal =
37+
const NSWindowLevel._withValues(_Base.normal, 0);
38+
39+
/// The level for a pop-up menu.
40+
static NSWindowLevel popUpMenu =
41+
const NSWindowLevel._withValues(_Base.popUpMenu, 0);
42+
43+
/// The level for a screen saver.
44+
static NSWindowLevel screenSaver =
45+
const NSWindowLevel._withValues(_Base.screenSaver, 0);
46+
47+
/// The level for a status window.
48+
static NSWindowLevel statusBar =
49+
const NSWindowLevel._withValues(_Base.statusBar, 0);
50+
51+
/// Reserved for submenus. Synonymous with `NSTornOffMenuWindowLevel`, which
52+
/// is preferred.
53+
static NSWindowLevel submenu =
54+
const NSWindowLevel._withValues(_Base.submenu, 0);
55+
56+
/// The level for a torn-off menu. Synonymous with `NSSubmenuWindowLevel`.
57+
static NSWindowLevel tornOffMenu =
58+
const NSWindowLevel._withValues(_Base.tornOffMenu, 0);
59+
60+
/// Returns a new instance of [NSWindowLevel] with a given offset.
61+
NSWindowLevel withOffset(int offset) {
62+
return NSWindowLevel._withValues(_base, offset);
63+
}
64+
}

lib/window_manipulator.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:async';
22

33
import 'package:flutter/services.dart';
44
import 'package:macos_window_utils/macos/ns_visual_effect_view_state.dart';
5+
import 'package:macos_window_utils/macos/ns_window_level.dart';
56
import 'package:macos_window_utils/macos/ns_window_toolbar_style.dart';
67
import 'package:macos_window_utils/macos/visual_effect_view_properties.dart';
78
import 'package:macos_window_utils/macos/ns_visual_effect_view_material.dart';
@@ -458,4 +459,58 @@ class WindowManipulator {
458459
'subtitle': subtitle,
459460
});
460461
}
462+
463+
/// Sets the level of the window.
464+
///
465+
/// Each level in the list groups windows within it in front of those in all
466+
/// preceding groups. Floating windows, for example, appear in front of all
467+
/// normal-level windows. When a window enters a new level, it’s ordered in
468+
/// front of all its peers in that level.
469+
///
470+
/// Usage examples:
471+
///
472+
/// ```dart
473+
/// // Set the window to appear in front of all normal-level windows:
474+
/// WindowManipulator.setLevel(NSWindowLevel.floating);
475+
///
476+
/// // Set the window to appear behind all normal-level windows:
477+
/// WindowManipulator.setLevel(NSWindowLevel.normal.withOffset(-1));
478+
///
479+
/// // Reset the window's level to the default value:
480+
/// WindowManipulator.setLevel(NSWindowLevel.normal);
481+
/// ```
482+
static Future<void> setLevel(NSWindowLevel level) async {
483+
await _completer.future;
484+
await _methodChannel.invokeMethod('setLevel', {
485+
'base': level.baseName,
486+
'offset': level.offset,
487+
});
488+
}
489+
490+
/// Removes the window from the screen list, which hides the window.
491+
static Future<void> orderOut() async {
492+
await _completer.future;
493+
await _methodChannel.invokeMethod('orderOut');
494+
}
495+
496+
/// Moves the window to the back of its level in the screen list, without
497+
/// changing either the key window or the main window.
498+
static Future<void> orderBack() async {
499+
await _completer.future;
500+
await _methodChannel.invokeMethod('orderBack');
501+
}
502+
503+
/// Moves the window to the front of its level in the screen list, without
504+
/// changing either the key window or the main window.
505+
static Future<void> orderFront() async {
506+
await _completer.future;
507+
await _methodChannel.invokeMethod('orderFront');
508+
}
509+
510+
/// Moves the window to the front of its level, even if its application isn't
511+
/// active, without changing either the key window or the main window.
512+
static Future<void> orderFrontRegardless() async {
513+
await _completer.future;
514+
await _methodChannel.invokeMethod('orderFrontRegardless');
515+
}
461516
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// LevelNameToLevelConverter.swift
3+
// macos_window_utils
4+
//
5+
// Created by Adrian Samoticha on 11.01.23.
6+
//
7+
8+
import Foundation
9+
10+
class LevelNameToLevelConverter {
11+
public static func getLevelFromName(_ name: String) -> NSWindow.Level {
12+
switch (name) {
13+
case "floating":
14+
return .floating
15+
16+
case "mainMenu":
17+
return .mainMenu
18+
19+
case "modalPanel":
20+
return .modalPanel
21+
22+
case "normal":
23+
return .normal
24+
25+
case "popUpMenu":
26+
return .popUpMenu
27+
28+
case "screenSaver":
29+
return .screenSaver
30+
31+
case "statusBar":
32+
return .statusBar
33+
34+
case "submenu":
35+
return .submenu
36+
37+
case "tornOffMenu":
38+
return .tornOffMenu
39+
40+
default:
41+
return .normal
42+
}
43+
}
44+
}

macos/Classes/MacOSWindowUtilsPlugin.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,33 @@ public class MacOSWindowUtilsPlugin: NSObject, FlutterPlugin {
356356
result(true)
357357
break
358358

359+
case "setLevel":
360+
let baseName = args["base"] as! String
361+
let offset = args["offset"] as! Int
362+
363+
let baseLevel = LevelNameToLevelConverter.getLevelFromName(baseName)
364+
let level = NSWindow.Level(baseLevel.rawValue + offset)
365+
366+
MainFlutterWindowManipulator.setLevel(level)
367+
368+
result(true)
369+
370+
case "orderOut":
371+
MainFlutterWindowManipulator.orderOut()
372+
result(true)
373+
374+
case "orderBack":
375+
MainFlutterWindowManipulator.orderBack()
376+
result(true)
377+
378+
case "orderFront":
379+
MainFlutterWindowManipulator.orderFront()
380+
result(true)
381+
382+
case "orderFrontRegardless":
383+
MainFlutterWindowManipulator.orderFrontRegardless()
384+
result(true)
385+
359386
default:
360387
result(FlutterMethodNotImplemented)
361388
break

macos/Classes/MainFlutterWindowManipulator.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,50 @@ public class MainFlutterWindowManipulator {
488488

489489
self.mainFlutterWindow!.subtitle = subtitle
490490
}
491+
492+
public static func setLevel(_ level: NSWindow.Level) {
493+
if (self.mainFlutterWindow == nil) {
494+
printNotStartedWarning()
495+
return
496+
}
497+
498+
self.mainFlutterWindow!.level = level
499+
}
500+
501+
public static func orderOut() {
502+
if (self.mainFlutterWindow == nil) {
503+
printNotStartedWarning()
504+
return
505+
}
506+
507+
self.mainFlutterWindow!.orderOut(nil)
508+
}
509+
510+
public static func orderBack() {
511+
if (self.mainFlutterWindow == nil) {
512+
printNotStartedWarning()
513+
return
514+
}
515+
516+
self.mainFlutterWindow!.orderBack(nil)
517+
}
518+
519+
520+
public static func orderFront() {
521+
if (self.mainFlutterWindow == nil) {
522+
printNotStartedWarning()
523+
return
524+
}
525+
526+
self.mainFlutterWindow!.orderFront(nil)
527+
}
528+
529+
public static func orderFrontRegardless() {
530+
if (self.mainFlutterWindow == nil) {
531+
printNotStartedWarning()
532+
return
533+
}
534+
535+
self.mainFlutterWindow!.orderFrontRegardless()
536+
}
491537
}

0 commit comments

Comments
 (0)