You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by tr...@apache.org on 2016/10/04 13:10:13 UTC

mac commit: CB-11948 Modal dialog (window.confirm) opens behind fullscreen window and cannot be closed

Repository: cordova-osx
Updated Branches:
  refs/heads/master 2f0f8e73a -> 4339aee7a


CB-11948 Modal dialog (window.confirm) opens behind fullscreen window and cannot be closed


Project: http://git-wip-us.apache.org/repos/asf/cordova-osx/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-osx/commit/4339aee7
Tree: http://git-wip-us.apache.org/repos/asf/cordova-osx/tree/4339aee7
Diff: http://git-wip-us.apache.org/repos/asf/cordova-osx/diff/4339aee7

Branch: refs/heads/master
Commit: 4339aee7a3142f84546376c314c51cce4c30154a
Parents: 2f0f8e7
Author: Tobias Bocanegra <tr...@adobe.com>
Authored: Tue Oct 4 20:15:00 2016 +0900
Committer: Tobias Bocanegra <tr...@adobe.com>
Committed: Tue Oct 4 20:15:00 2016 +0900

----------------------------------------------------------------------
 .../CordovaLib/Classes/CDVWebViewDelegate.m     | 39 ++++++++++---
 .../Classes/Commands/CDVWindowSizeCommand.m     |  2 +-
 .../CordovaLib/Classes/Utils/NSWindow+Utils.h   | 16 +++++-
 .../CordovaLib/Classes/Utils/NSWindow+Utils.m   | 58 +++++++++++++++++++-
 4 files changed, 102 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-osx/blob/4339aee7/CordovaLib/CordovaLib/Classes/CDVWebViewDelegate.m
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLib/Classes/CDVWebViewDelegate.m b/CordovaLib/CordovaLib/Classes/CDVWebViewDelegate.m
index 234b7ca..a234e1c 100644
--- a/CordovaLib/CordovaLib/Classes/CDVWebViewDelegate.m
+++ b/CordovaLib/CordovaLib/Classes/CDVWebViewDelegate.m
@@ -21,6 +21,7 @@
 #import "CDVWebViewDelegate.h"
 #import "CDVConsole.h"
 #import "CDVBridge.h"
+#import "NSWindow+Utils.h"
 // #import "CookieJar.h"
 
 @implementation CDVWebViewDelegate
@@ -114,7 +115,15 @@
     [alert addButtonWithTitle:NSLocalizedString(@"OK", @"")];
     [alert setMessageText:message];
 
-    [alert runModal];
+    // workaround for fullscreen windows (see CB-11948)
+    [alert.window setLevel:NSMainMenuWindowLevel + 2];
+    [alert.window setIsLevelLocked:true];
+
+    @try {
+        [alert runModal];
+    } @finally {
+        [alert.window setIsLevelLocked:false];
+    }
 }
 
 - (BOOL) webView:(WebView*) sender runJavaScriptConfirmPanelWithMessage:(NSString*) message initiatedByFrame:(WebFrame*) frame {
@@ -123,7 +132,14 @@
     [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"")];
     [alert setMessageText:message];
 
-    return ([alert runModal] == NSAlertFirstButtonReturn);
+    // workaround for fullscreen windows (see CB-11948)
+    [alert.window setLevel:NSMainMenuWindowLevel + 2];
+    [alert.window setIsLevelLocked:true];
+    @try {
+        return ([alert runModal] == NSAlertFirstButtonReturn);
+    } @finally {
+        [alert.window setIsLevelLocked:false];
+    }
 }
 
 - (NSString*) webView:(WebView*) sender runJavaScriptTextInputPanelWithPrompt:(NSString*) prompt defaultText:(NSString*) defaultText initiatedByFrame:(WebFrame*) frame {
@@ -135,13 +151,20 @@
     [input setStringValue:defaultText];
     [alert setAccessoryView:input];
 
-    NSInteger button = [alert runModal];
-    if (button == NSAlertFirstButtonReturn) {
-        [input validateEditing];
-        return [input stringValue];
-    }
+    // workaround for fullscreen windows (see CB-11948)
+    [alert.window setLevel:NSMainMenuWindowLevel + 2];
+    [alert.window setIsLevelLocked:true];
 
-    return nil;
+    @try {
+        NSInteger button = [alert runModal];
+        if (button == NSAlertFirstButtonReturn) {
+            [input validateEditing];
+            return [input stringValue];
+        }
+        return nil;
+    } @finally {
+        [alert.window setIsLevelLocked:false];
+    }
 }
 
 # pragma mark WebResourceLoadDelegate

http://git-wip-us.apache.org/repos/asf/cordova-osx/blob/4339aee7/CordovaLib/CordovaLib/Classes/Commands/CDVWindowSizeCommand.m
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLib/Classes/Commands/CDVWindowSizeCommand.m b/CordovaLib/CordovaLib/Classes/Commands/CDVWindowSizeCommand.m
index 69abc92..4d32434 100644
--- a/CordovaLib/CordovaLib/Classes/Commands/CDVWindowSizeCommand.m
+++ b/CordovaLib/CordovaLib/Classes/Commands/CDVWindowSizeCommand.m
@@ -27,7 +27,7 @@ static NSRect savedFrameRect;
 
 /**
  * Makes the window fullscreen by resizing it to the size of all attached displays. This is different from just entering
- * normal OSX fullscreen mode which only overs the main display.
+ * normal OSX fullscreen mode which only covers the main display.
  */
 + (void) makeFullScreen:(NSWindow*) window {
     NSRect fullScreenRect = [NSScreen fullScreenRect];

http://git-wip-us.apache.org/repos/asf/cordova-osx/blob/4339aee7/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.h
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.h b/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.h
index 03e4253..bac2a3e 100644
--- a/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.h
+++ b/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.h
@@ -6,9 +6,9 @@
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
- 
+
  http://www.apache.org/licenses/LICENSE-2.0
- 
+
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -24,4 +24,16 @@
 
 - (float) titleBarHeight;
 
+/**
+ * Sets the internal 'lock' flag that prevents setting the window level. this is
+ * mainly used to make the modal alert boxes work with our fullscreen mode.
+ */
+- (void) setIsLevelLocked:(bool) lock;
+
+/**
+ * see {@link #setIsLevelLocked}
+ */
+- (bool) getIsLevelLocked;
+
+
 @end

http://git-wip-us.apache.org/repos/asf/cordova-osx/blob/4339aee7/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.m
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.m b/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.m
index 52363d6..c4b1744 100644
--- a/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.m
+++ b/CordovaLib/CordovaLib/Classes/Utils/NSWindow+Utils.m
@@ -18,12 +18,27 @@
  */
 
 
+#import <objc/runtime.h>
 #import "NSWindow+Utils.h"
 
+#define KEY_LEVEL_LOCKED @"level_lock"
+
 @implementation NSWindow (Utils)
 
-- (float) titleBarHeight
-{
+
++ (NSWindow*) instance {
+    static NSWindow* _instance = nil;
+
+    @synchronized (self) {
+        if (_instance == nil) {
+            _instance = [[self alloc] init];
+        }
+    }
+
+    return _instance;
+}
+
+- (float) titleBarHeight {
     NSRect frame = [self frame];
     NSRect contentRect = [NSWindow contentRectForFrameRect: frame
 												 styleMask: NSTitledWindowMask];
@@ -31,4 +46,43 @@
     return (float) (frame.size.height - contentRect.size.height);
 }
 
+- (NSMutableDictionary*) props {
+    NSMutableDictionary* p = objc_getAssociatedObject(self, @selector(props));
+    if (p == nil) {
+        p = [NSMutableDictionary dictionary];
+        p[KEY_LEVEL_LOCKED] = @NO;
+        objc_setAssociatedObject(self, @selector(props), p, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+    }
+    return p;
+}
+
+- (bool) getIsLevelLocked {
+    NSMutableDictionary* p = [self props];
+    return [@YES isEqualTo:p[KEY_LEVEL_LOCKED]];
+}
+
+- (void) setIsLevelLocked:(bool) lock {
+    NSMutableDictionary* p = [self props];
+    p[KEY_LEVEL_LOCKED] = lock ? @YES : @NO;
+}
+
+- (void) swizzled_setLevel: (NSInteger) level {
+    if ([self getIsLevelLocked]) {
+        return;
+    }
+
+#pragma clang diagnostic push
+#pragma ide diagnostic ignored "InfiniteRecursion"
+    [self swizzled_setLevel:level];
+#pragma clang diagnostic pop
+}
+
++ (void)load {
+    Method original, swizzled;
+
+    original = class_getInstanceMethod(self, @selector(setLevel:));
+    swizzled = class_getInstanceMethod(self, @selector(swizzled_setLevel:));
+    method_exchangeImplementations(original, swizzled);
+}
+
 @end


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org