Fix camino bug 311683. The earlier fix for bug 297343 introduced a short delay before the dispatch of focus/activate events on window activation. It turns out that this was bad, as you could end up with two windows which continually each come to the front ("duelling windows"). This patch makes things synchronous again, but fixes the original bug by exposing a category on NSWindow in the widget code that allows the embedder to know if a SetFocus() call is coming as a result of window activation. r=mento

This commit is contained in:
smfr%smfr.org 2005-10-12 17:38:29 +00:00
Родитель c30640ebdf
Коммит 26796e8397
6 изменённых файлов: 45 добавлений и 30 удалений

Просмотреть файл

@ -38,6 +38,8 @@
#import <Cocoa/Cocoa.h>
// this implements the mozWindow protocol (see mozView.h)
@interface BrowserWindow : NSWindow
{
IBOutlet id mAutoCompleteTextField;
@ -50,9 +52,11 @@
- (BOOL)makeFirstResponder:(NSResponder*) responder;
// mozWindow protocol
- (BOOL)suppressMakeKeyFront;
- (void)setSuppressMakeKeyFront:(BOOL)inSuppress;
// scripting
- (NSString*)getURL;
@end

Просмотреть файл

@ -36,6 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
#import "mozView.h"
#import "BrowserWindow.h"
#import "BrowserWindowController.h"
#import "AutoCompleteTextField.h"

Просмотреть файл

@ -421,7 +421,7 @@ enum BWCOpenDest {
- (BrowserTabViewItem*)openNewTab:(BOOL)aLoadInBG;
- (void)setupToolbar;
- (void)delayedSetActive:(NSNumber*)inActive; // NSNumber with bool
- (void)setGeckoActive:(BOOL)inActive;
- (NSString*)getContextMenuNodeDocumentURL;
- (void)loadSourceOfURL:(NSString*)urlStr;
- (void)transformFormatString:(NSMutableString*)inFormat domain:(NSString*)inDomain search:(NSString*)inSearch;
@ -495,7 +495,7 @@ enum BWCOpenDest {
// the widget code (via -viewsWindowDidBecomeKey) takes care
// of sending focus and activate events to gecko,
// but we still need to call the embedding activate API
[self performSelector:@selector(delayedSetActive:) withObject:[NSNumber numberWithBool:YES] afterDelay:0];
[self setGeckoActive:YES];
}
- (void)windowDidResignKey:(NSNotification *)notification
@ -508,13 +508,18 @@ enum BWCOpenDest {
// the widget code (via -viewsWindowDidResignKey) takes care
// of sending focus and activate events to gecko,
// but we still need to call the embedding activate API
[self performSelector:@selector(delayedSetActive:) withObject:[NSNumber numberWithBool:NO] afterDelay:0];
[self setGeckoActive:NO];
}
- (void)delayedSetActive:(NSNumber*)inActive
- (void)setGeckoActive:(BOOL)inActive
{
if ([self isResponderGeckoView:[[self window] firstResponder]])
[mBrowserView setBrowserActive:[inActive boolValue]];
{
BrowserWindow* browserWin = (BrowserWindow*)[self window];
[browserWin setSuppressMakeKeyFront:YES]; // prevent gecko focus bringing the window to the front
[mBrowserView setBrowserActive:inActive];
[browserWin setSuppressMakeKeyFront:NO];
}
}
- (void)windowDidBecomeMain:(NSNotification *)notification

Просмотреть файл

@ -39,6 +39,8 @@
#import "NSString+Utils.h"
#import "mozView.h"
// Embedding includes
#include "nsIWebNavigation.h"
#include "nsIWebProgress.h"

Просмотреть файл

@ -75,3 +75,18 @@ class nsIWidget;
@end
//
// An informal protocol implemented by the NSWindow of the host application.
//
// It's used to prevent re-entrant calls to -makeKeyAndOrderFront: when gecko
// focus/activate events propagate out to the embedder's
// nsIEmbeddingSiteWindow::SetFocus implementation.
//
@interface NSObject(mozWindow)
- (BOOL)suppressMakeKeyFront;
- (void)setSuppressMakeKeyFront:(BOOL)inSuppress;
@end

Просмотреть файл

@ -111,9 +111,6 @@
- (void)flushRect:(NSRect)inRect;
- (BOOL)isRectObscuredBySubview:(NSRect)inRect;
- (void)sendActivateEvent;
- (void)sendDeactivateEvent;
#if USE_CLICK_HOLD_CONTEXTMENU
// called on a timer two seconds after a mouse down to see if we should display
// a context menu (click-hold)
@ -3451,38 +3448,29 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
}
- (void)viewsWindowDidBecomeKey
{
// When unhiding the app, -windowBecameKey: gets called when two bits of window
// state are incorrect (on Tiger):
//
// 1. [window isVisible] returns YES even though it's not on the screen
// 2. [NSApp keyWindow] is not the right window yet
//
// Because this state is not correct at this time, we postpone sending
// the events into gecko (which in turn propagate into the host app)
// until the next time through the event loop, when we're off this stack
// and Cocoa has got its story straight.
[self performSelector:@selector(sendActivateEvent) withObject:nil afterDelay:0];
}
- (void)viewsWindowDidResignKey
{
[self performSelector:@selector(sendDeactivateEvent) withObject:nil afterDelay:0];
}
- (void)sendActivateEvent
{
if (!mGeckoChild)
return; // we've been destroyed
return; // we've been destroyed (paranoia)
// check to see if the window implements the mozWindow protocol. This
// allows embedders to avoid re-entrant calls to -makeKeyAndOrderFront,
// which can happen because these activate/focus calls propagate out
// to the embedder via nsIEmbeddingSiteWindow::SetFocus().
BOOL isMozWindow = [[self window] respondsToSelector:@selector(setSuppressMakeKeyFront:)];
if (isMozWindow)
[[self window] setSuppressMakeKeyFront:YES];
nsFocusEvent focusEvent(PR_TRUE, NS_GOTFOCUS, mGeckoChild);
mGeckoChild->DispatchWindowEvent(focusEvent);
nsFocusEvent activateEvent(PR_TRUE, NS_ACTIVATE, mGeckoChild);
mGeckoChild->DispatchWindowEvent(activateEvent);
if (isMozWindow)
[[self window] setSuppressMakeKeyFront:NO];
}
- (void)sendDeactivateEvent
- (void)viewsWindowDidResignKey
{
if (!mGeckoChild)
return; // we've been destroyed