Revert "macOS: Set correct fullscreen window level"
[vlc.git] / modules / gui / macosx / VLCVoutWindowController.m
1 /*****************************************************************************
2  * VLCVoutWindowController.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2012-2014 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Felix Paul K├╝hne <fkuehne -at- videolan -dot- org>
8  *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include <vlc_vout_display.h>
26
27 #import "CompatibilityFixes.h"
28 #import "VLCVoutWindowController.h"
29 #import "VLCMain.h"
30 #import "VLCMainWindow.h"
31 #import "VLCVoutView.h"
32
33 #import "VLCVideoEffectsWindowController.h"
34 #import "VLCAudioEffectsWindowController.h"
35 #import "VLCPlaylistInfo.h"
36 #import "VLCBookmarksWindowController.h"
37 #import "VLCTrackSynchronizationWindowController.h"
38 #import "VLCResumeDialogController.h"
39 #import "VLCPlaylist.h"
40 #import "NSScreen+VLCAdditions.h"
41
42 static atomic_bool b_intf_starting = ATOMIC_VAR_INIT(false);
43
44 static int WindowControl(vout_window_t *, int i_query, va_list);
45
46 int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
47 {
48     @autoreleasepool {
49         if (cfg->type != VOUT_WINDOW_TYPE_INVALID
50             && cfg->type != VOUT_WINDOW_TYPE_NSOBJECT)
51             return VLC_EGENERIC;
52
53         msg_Dbg(p_wnd, "Opening video window");
54
55         if (!atomic_load(&b_intf_starting)) {
56             msg_Err(p_wnd, "Cannot create vout as Mac OS X interface was not found");
57             return VLC_EGENERIC;
58         }
59
60         NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
61
62         VLCVoutWindowController *voutController = [[VLCMain sharedInstance] voutController];
63         if (!voutController) {
64             return VLC_EGENERIC;
65         }
66         [voutController.lock lock];
67
68         SEL sel = @selector(setupVoutForWindow:withProposedVideoViewPosition:);
69         NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
70         [inv setTarget:voutController];
71         [inv setSelector:sel];
72         [inv setArgument:&p_wnd atIndex:2]; // starting at 2!
73         [inv setArgument:&proposedVideoViewPosition atIndex:3];
74
75         [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
76                            waitUntilDone:YES];
77
78         VLCVoutView *videoView = nil;
79         [inv getReturnValue:&videoView];
80
81         // this method is not supposed to fail
82         assert(videoView != nil);
83
84         msg_Dbg(getIntf(), "returning videoview with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height);
85         p_wnd->handle.nsobject = (void *)CFBridgingRetain(videoView);
86
87         [voutController.lock unlock];
88
89         p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT;
90         p_wnd->control = WindowControl;
91     }
92     vout_window_SetFullScreen(p_wnd, cfg->is_fullscreen);
93     return VLC_SUCCESS;
94 }
95
96 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
97 {
98     @autoreleasepool {
99         VLCVoutWindowController *voutController = [[VLCMain sharedInstance] voutController];
100         if (!voutController) {
101             return VLC_EGENERIC;
102         }
103         [voutController.lock lock];
104
105         switch(i_query) {
106             case VOUT_WINDOW_SET_STATE:
107             {
108                 unsigned i_state = va_arg(args, unsigned);
109
110                 if (i_state & VOUT_WINDOW_STATE_BELOW)
111                 {
112                     msg_Dbg(p_wnd, "Ignore change to VOUT_WINDOW_STATE_BELOW");
113                     goto out;
114                 }
115
116                 NSInteger i_cooca_level = NSNormalWindowLevel;
117                 if (i_state & VOUT_WINDOW_STATE_ABOVE)
118                     i_cooca_level = NSStatusWindowLevel;
119
120                 SEL sel = @selector(setWindowLevel:forWindow:);
121                 NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
122                 [inv setTarget:voutController];
123                 [inv setSelector:sel];
124                 [inv setArgument:&i_cooca_level atIndex:2]; // starting at 2!
125                 [inv setArgument:&p_wnd atIndex:3];
126                 [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
127                                    waitUntilDone:NO];
128
129                 break;
130             }
131             case VOUT_WINDOW_SET_SIZE:
132             {
133                 unsigned int i_width  = va_arg(args, unsigned int);
134                 unsigned int i_height = va_arg(args, unsigned int);
135
136                 NSSize newSize = NSMakeSize(i_width, i_height);
137                 SEL sel = @selector(setNativeVideoSize:forWindow:);
138                 NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
139                 [inv setTarget:voutController];
140                 [inv setSelector:sel];
141                 [inv setArgument:&newSize atIndex:2]; // starting at 2!
142                 [inv setArgument:&p_wnd atIndex:3];
143                 [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
144                                    waitUntilDone:NO];
145
146                 break;
147             }
148             case VOUT_WINDOW_SET_FULLSCREEN:
149             {
150                 if (var_InheritBool(getIntf(), "video-wallpaper")) {
151                     msg_Dbg(p_wnd, "Ignore fullscreen event as video-wallpaper is on");
152                     goto out;
153                 }
154
155                 int i_full = va_arg(args, int);
156                 BOOL b_animation = YES;
157
158                 SEL sel = @selector(setFullscreen:forWindow:withAnimation:);
159                 NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
160                 [inv setTarget:voutController];
161                 [inv setSelector:sel];
162                 [inv setArgument:&i_full atIndex:2]; // starting at 2!
163                 [inv setArgument:&p_wnd atIndex:3];
164                 [inv setArgument:&b_animation atIndex:4];
165                 [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
166                                    waitUntilDone:NO];
167
168                 break;
169             }
170             default:
171             {
172                 msg_Warn(p_wnd, "unsupported control query");
173                 [voutController.lock unlock];
174                 return VLC_EGENERIC;
175             }
176         }
177
178         out:
179         [voutController.lock unlock];
180         return VLC_SUCCESS;
181     }
182 }
183
184 void WindowClose(vout_window_t *p_wnd)
185 {
186     @autoreleasepool {
187         VLCVoutWindowController *voutController = [[VLCMain sharedInstance] voutController];
188         if (!voutController) {
189             return;
190         }
191
192         [voutController.lock lock];
193         [voutController performSelectorOnMainThread:@selector(removeVoutforDisplay:) withObject:[NSValue valueWithPointer:p_wnd] waitUntilDone:NO];
194         [voutController.lock unlock];
195     }
196 }
197
198 @interface VLCVoutWindowController ()
199 {
200     NSMutableDictionary *o_vout_dict;
201     VLCKeyboardBacklightControl *o_keyboard_backlight;
202
203     NSPoint top_left_point;
204
205     // save the status level if at least one video window is on status level
206     NSUInteger i_statusLevelWindowCounter;
207     NSInteger i_currentWindowLevel;
208
209     BOOL b_mainwindow_has_video;
210 }
211 @end
212
213 @implementation VLCVoutWindowController
214
215 - (id)init
216 {
217     self = [super init];
218     if (self) {
219         atomic_store(&b_intf_starting, true);
220         o_vout_dict = [[NSMutableDictionary alloc] init];
221         o_keyboard_backlight = [[VLCKeyboardBacklightControl alloc] init];
222         i_currentWindowLevel = NSNormalWindowLevel;
223         _currentStatusWindowLevel = NSFloatingWindowLevel;
224     }
225     return self;
226 }
227
228 - (void)dealloc
229 {
230     NSArray *keys = [o_vout_dict allKeys];
231     for (NSValue *key in keys)
232         [self removeVoutforDisplay:key];
233
234     if (var_InheritBool(getIntf(), "macosx-dim-keyboard")) {
235         [o_keyboard_backlight switchLightsInstantly:YES];
236     }
237 }
238
239 #pragma mark -
240 #pragma mark Methods for vout provider
241
242 - (VLCVoutView *)setupVoutForWindow:(vout_window_t *)p_wnd withProposedVideoViewPosition:(NSRect)videoViewPosition
243 {
244     BOOL b_nonembedded = NO;
245     BOOL b_nativeFullscreenMode = [[VLCMain sharedInstance] nativeFullscreenMode];
246     BOOL b_video_deco = var_InheritBool(getIntf(), "video-deco");
247     BOOL b_video_wallpaper = var_InheritBool(getIntf(), "video-wallpaper");
248     BOOL b_multiple_vout_windows = [o_vout_dict count] > 0;
249     VLCVoutView *o_vout_view;
250     VLCVideoWindowCommon *o_new_video_window;
251
252     // should be called before any window resizing occurs
253     if (!b_multiple_vout_windows)
254         [[[VLCMain sharedInstance] mainWindow] videoplayWillBeStarted];
255
256     if (b_multiple_vout_windows && b_video_wallpaper)
257         b_video_wallpaper = false;
258
259     // TODO: make lion fullscreen compatible with video-wallpaper
260     if ((b_video_wallpaper || !b_video_deco) && !b_nativeFullscreenMode) {
261         // b_video_wallpaper is priorized over !b_video_deco
262
263         msg_Dbg(getIntf(), "Creating background / blank window");
264         NSScreen *screen = [NSScreen screenWithDisplayID:(CGDirectDisplayID)var_InheritInteger(getIntf(), "macosx-vdev")];
265         if (!screen)
266             screen = [[[VLCMain sharedInstance] mainWindow] screen];
267
268         NSRect window_rect;
269         if (b_video_wallpaper)
270             window_rect = [screen frame];
271         else
272             window_rect = [[[VLCMain sharedInstance] mainWindow] frame];
273
274         NSUInteger mask = NSBorderlessWindowMask;
275         if (!b_video_deco)
276             mask |= NSResizableWindowMask;
277
278         BOOL b_no_video_deco_only = !b_video_wallpaper;
279         o_new_video_window = [[VLCVideoWindowCommon alloc] initWithContentRect:window_rect styleMask:mask backing:NSBackingStoreBuffered defer:YES];
280         [o_new_video_window setDelegate:o_new_video_window];
281         [o_new_video_window setReleasedWhenClosed: NO];
282
283         if (b_video_wallpaper)
284             [o_new_video_window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey) + 1];
285
286         [o_new_video_window setBackgroundColor: [NSColor blackColor]];
287         [o_new_video_window setCanBecomeKeyWindow: !b_video_wallpaper];
288         [o_new_video_window setCanBecomeMainWindow: !b_video_wallpaper];
289         [o_new_video_window setAcceptsMouseMovedEvents: !b_video_wallpaper];
290         [o_new_video_window setMovableByWindowBackground: !b_video_wallpaper];
291         [o_new_video_window useOptimizedDrawing: YES];
292
293         o_vout_view = [[VLCVoutView alloc] initWithFrame:[[o_new_video_window contentView] bounds]];
294         [o_vout_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
295         [[o_new_video_window contentView] addSubview:o_vout_view positioned:NSWindowAbove relativeTo:nil];
296         [o_new_video_window setVideoView:o_vout_view];
297
298
299         if (b_video_wallpaper)
300             [o_new_video_window orderBack:nil];
301         else {
302             // no frame autosave for additional vout windows
303             if (!b_multiple_vout_windows) {
304                 // initial window position
305                 [o_new_video_window center];
306                 [o_new_video_window setFrameAutosaveName:@"extra-videowindow"];
307             }
308
309             [o_new_video_window setContentMinSize: NSMakeSize(f_min_video_height, f_min_video_height)];
310         }
311
312         b_nonembedded = YES;
313     } else {
314         if ((var_InheritBool(getIntf(), "embedded-video") && !b_mainwindow_has_video)) {
315             // setup embedded video
316             o_new_video_window = [[VLCMain sharedInstance] mainWindow] ;
317             o_vout_view = [o_new_video_window videoView];
318             b_mainwindow_has_video = YES;
319             b_nonembedded = NO;
320         } else {
321             // setup detached window with controls
322             NSWindowController *o_controller = [[NSWindowController alloc] initWithWindowNibName:@"DetachedVideoWindow"];
323             [o_controller loadWindow];
324             o_new_video_window = (VLCDetachedVideoWindow *)[o_controller window];
325
326             // no frame autosave for additional vout windows
327             if (b_multiple_vout_windows)
328                 [o_new_video_window setFrameAutosaveName:@""];
329
330             [o_new_video_window setDelegate: o_new_video_window];
331             [o_new_video_window setLevel:NSNormalWindowLevel];
332             [o_new_video_window useOptimizedDrawing: YES];
333             o_vout_view = [o_new_video_window videoView];
334             b_nonembedded = YES;
335         }
336     }
337
338     NSSize videoViewSize = NSMakeSize(videoViewPosition.size.width, videoViewPosition.size.height);
339
340     // Avoid flashes if video will directly start in fullscreen
341     NSDisableScreenUpdates();
342
343     if (!b_video_wallpaper) {
344         // set (only!) window origin if specified
345         if (b_nonembedded) {
346             NSRect window_rect = [o_new_video_window frame];
347             if (videoViewPosition.origin.x > 0.)
348                 window_rect.origin.x = videoViewPosition.origin.x;
349             if (videoViewPosition.origin.y > 0.)
350                 window_rect.origin.y = videoViewPosition.origin.y;
351
352             [o_new_video_window setFrame:window_rect display:YES];
353         }
354
355         // cascade windows if we have more than one vout
356         if (b_multiple_vout_windows) {
357             if ([o_vout_dict count] == 1) {
358                 NSWindow * o_first_window = [o_vout_dict objectForKey: [[o_vout_dict allKeys] firstObject]];
359
360                 NSRect topleftBaseRect = NSMakeRect(0, [o_first_window frame].size.height, 0, 0);
361                 top_left_point = [o_first_window convertRectToScreen: topleftBaseRect].origin;
362             }
363
364             top_left_point = [o_new_video_window cascadeTopLeftFromPoint: top_left_point];
365             [o_new_video_window setFrameTopLeftPoint: top_left_point];
366         }
367
368         // resize window
369         [o_new_video_window setNativeVideoSize:videoViewSize];
370
371         [o_new_video_window makeKeyAndOrderFront: self];
372     }
373
374     [o_new_video_window setAlphaValue: config_GetFloat(getIntf(), "macosx-opaqueness")];
375
376     [o_vout_view setVoutThread:(vout_thread_t *)p_wnd->obj.parent];
377     [o_new_video_window setHasActiveVideo: YES];
378     [o_vout_dict setObject:o_new_video_window forKey:[NSValue valueWithPointer:p_wnd]];
379
380     [[VLCMain sharedInstance] setActiveVideoPlayback: YES];
381     [[[VLCMain sharedInstance] mainWindow] setNonembedded:!b_mainwindow_has_video];
382
383     // beware of order, setActiveVideoPlayback:, setHasActiveVideo: and setNonembedded: must be called before
384     if ([o_new_video_window class] == [VLCMainWindow class])
385         [[[VLCMain sharedInstance] mainWindow] changePlaylistState: psVideoStartedOrStoppedEvent];
386
387     if (b_nonembedded) {
388         // events might be posted before window is created, so call them again
389         [[[VLCMain sharedInstance] mainWindow] updateName];
390         [[[VLCMain sharedInstance] mainWindow] updateWindow]; // update controls bar
391     }
392
393     // TODO: find a cleaner way for "start in fullscreen"
394     // Start in fs, because either prefs settings, or fullscreen button was pressed before
395     char *psz_splitter = var_GetString(pl_Get(getIntf()), "video-splitter");
396     BOOL b_have_splitter = psz_splitter != NULL && *psz_splitter != '\0';
397     free(psz_splitter);
398
399     if (!b_video_wallpaper && !b_have_splitter && (var_InheritBool(getIntf(), "fullscreen") || var_GetBool(pl_Get(getIntf()), "fullscreen"))) {
400
401         // this is not set when we start in fullscreen because of
402         // fullscreen settings in video prefs the second time
403         var_SetBool(p_wnd->obj.parent, "fullscreen", 1);
404
405         [self setFullscreen:1 forWindow:p_wnd withAnimation:NO];
406     }
407
408     NSEnableScreenUpdates();
409
410     return o_vout_view;
411 }
412
413 - (void)removeVoutforDisplay:(NSValue *)o_key
414 {
415     VLCVideoWindowCommon *o_window = [o_vout_dict objectForKey:o_key];
416     if (!o_window) {
417         msg_Err(getIntf(), "Cannot close nonexisting window");
418         return;
419     }
420
421     [[o_window videoView] releaseVoutThread];
422
423     // set active video to no BEFORE closing the window and exiting fullscreen
424     // (avoid stopping playback due to NSWindowWillCloseNotification, preserving fullscreen state)
425     [o_window setHasActiveVideo: NO];
426
427     // prevent visible extra window if in fullscreen
428     NSDisableScreenUpdates();
429     BOOL b_native = [[[VLCMain sharedInstance] mainWindow] nativeFullscreenMode];
430
431     // close fullscreen, without changing fullscreen vars
432     if (!b_native && ([o_window fullscreen] || [o_window inFullscreenTransition]))
433         [o_window leaveFullscreenWithAnimation:NO];
434
435     // native fullscreen window will not be closed if
436     // fullscreen was triggered without video
437     if ((b_native && [o_window class] == [VLCMainWindow class] && [o_window fullscreen] && [o_window windowShouldExitFullscreenWhenFinished])) {
438         [o_window toggleFullScreen:self];
439     }
440
441     if ([o_window class] != [VLCMainWindow class]) {
442         [o_window close];
443     }
444     NSEnableScreenUpdates();
445
446     [o_vout_dict removeObjectForKey:o_key];
447     if ([o_vout_dict count] == 0) {
448         [[VLCMain sharedInstance] setActiveVideoPlayback:NO];
449         i_statusLevelWindowCounter = 0;
450     }
451
452     if ([o_window class] == [VLCMainWindow class]) {
453         b_mainwindow_has_video = NO;
454
455         // video in main window might get stopped while another vout is open
456         if ([o_vout_dict count] > 0)
457             [[[VLCMain sharedInstance] mainWindow] setNonembedded:YES];
458
459         // beware of order, setActiveVideoPlayback:, setHasActiveVideo: and setNonembedded: must be called before
460         [[[VLCMain sharedInstance] mainWindow] changePlaylistState: psVideoStartedOrStoppedEvent];
461     }
462 }
463
464
465 - (void)setNativeVideoSize:(NSSize)size forWindow:(vout_window_t *)p_wnd
466 {
467     VLCVideoWindowCommon *o_window = [o_vout_dict objectForKey:[NSValue valueWithPointer:p_wnd]];
468     if (!o_window) {
469         msg_Err(getIntf(), "Cannot set size for nonexisting window");
470         return;
471     }
472
473     [o_window setNativeVideoSize:size];
474 }
475
476 - (void)setWindowLevel:(NSInteger)i_level forWindow:(vout_window_t *)p_wnd
477 {
478     VLCVideoWindowCommon *o_window = [o_vout_dict objectForKey:[NSValue valueWithPointer:p_wnd]];
479     if (!o_window) {
480         msg_Err(getIntf(), "Cannot set level for nonexisting window");
481         return;
482     }
483
484     // only set level for helper windows to normal if no status vout window exist anymore
485     if(i_level == NSStatusWindowLevel) {
486         i_statusLevelWindowCounter++;
487         // window level need to stay on normal in fullscreen mode
488         if (![o_window fullscreen] && ![o_window inFullscreenTransition])
489             [self updateWindowLevelForHelperWindows:i_level];
490     } else {
491         if (i_statusLevelWindowCounter > 0)
492             i_statusLevelWindowCounter--;
493
494         if (i_statusLevelWindowCounter == 0) {
495             [self updateWindowLevelForHelperWindows:i_level];
496         }
497     }
498
499     [o_window setWindowLevel:i_level];
500 }
501
502 - (void)setFullscreen:(int)i_full forWindow:(vout_window_t *)p_wnd withAnimation:(BOOL)b_animation
503 {
504     intf_thread_t *p_intf = getIntf();
505     BOOL b_nativeFullscreenMode = [[VLCMain sharedInstance] nativeFullscreenMode];
506
507     if (!p_intf || (!b_nativeFullscreenMode && !p_wnd))
508         return;
509     playlist_t *p_playlist = pl_Get(p_intf);
510     BOOL b_fullscreen = i_full != 0;
511
512     if (!var_GetBool(p_playlist, "fullscreen") != !b_fullscreen)
513         var_SetBool(p_playlist, "fullscreen", b_fullscreen);
514
515     VLCVideoWindowCommon *o_current_window = nil;
516     if(p_wnd)
517         o_current_window = [o_vout_dict objectForKey:[NSValue valueWithPointer:p_wnd]];
518
519     if (var_InheritBool(p_intf, "macosx-dim-keyboard")) {
520         [o_keyboard_backlight switchLightsAsync:!b_fullscreen];
521     }
522
523     if (b_nativeFullscreenMode) {
524         if(!o_current_window)
525             o_current_window = [[VLCMain sharedInstance] mainWindow] ;
526         assert(o_current_window);
527
528         // fullscreen might be triggered twice (vout event)
529         // so ignore duplicate events here
530         if((b_fullscreen && !([o_current_window fullscreen] || [o_current_window inFullscreenTransition])) ||
531            (!b_fullscreen && [o_current_window fullscreen])) {
532
533             [o_current_window toggleFullScreen:self];
534         }
535     } else {
536         assert(o_current_window);
537
538         if (b_fullscreen) {
539             input_thread_t * p_input = pl_CurrentInput(p_intf);
540             if (p_input != NULL && [[VLCMain sharedInstance] activeVideoPlayback]) {
541                 // activate app, as method can also be triggered from outside the app (prevents nasty window layout)
542                 [NSApp activateIgnoringOtherApps:YES];
543                 [o_current_window enterFullscreenWithAnimation:b_animation];
544
545             }
546             if (p_input)
547                 vlc_object_release(p_input);
548         } else {
549             // leaving fullscreen is always allowed
550             [o_current_window leaveFullscreenWithAnimation:YES];
551         }
552     }
553 }
554
555 #pragma mark -
556 #pragma mark Misc methods
557
558 - (void)updateControlsBarsUsingBlock:(void (^)(VLCControlsBarCommon *controlsBar))block
559 {
560     [o_vout_dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
561
562         if ([obj respondsToSelector:@selector(controlsBar)]) {
563             VLCControlsBarCommon *o_controlsBar = [obj controlsBar];
564             if (o_controlsBar && block)
565                 block(o_controlsBar);
566         }
567     }];
568 }
569
570 - (void)updateWindowsUsingBlock:(void (^)(VLCVideoWindowCommon *o_window))windowUpdater
571 {
572     [o_vout_dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
573         if ([obj isKindOfClass: [NSWindow class]])
574             windowUpdater(obj);
575     }];
576 }
577
578 - (void)updateWindowLevelForHelperWindows:(NSInteger)i_level
579 {
580     if (var_InheritBool(getIntf(), "video-wallpaper"))
581         return;
582
583     i_currentWindowLevel = i_level;
584     if (i_level == NSNormalWindowLevel) {
585         _currentStatusWindowLevel = NSFloatingWindowLevel;
586     } else {
587         _currentStatusWindowLevel = i_level + 1;
588     }
589
590     NSInteger currentStatusWindowLevel = self.currentStatusWindowLevel;
591
592     VLCMain *main = [VLCMain sharedInstance];
593     [[[VLCMain sharedInstance] mainWindow] setWindowLevel:i_level];
594     [[main videoEffectsPanel] updateCocoaWindowLevel:currentStatusWindowLevel];
595     [[main audioEffectsPanel] updateCocoaWindowLevel:currentStatusWindowLevel];
596     [[main currentMediaInfoPanel] updateCocoaWindowLevel:currentStatusWindowLevel];
597     [[main bookmarks] updateCocoaWindowLevel:currentStatusWindowLevel];
598     [[main trackSyncPanel] updateCocoaWindowLevel:currentStatusWindowLevel];
599     [[main resumeDialog] updateCocoaWindowLevel:currentStatusWindowLevel];
600 }
601
602 @end