diff options
| author | Manolo Gouy <Manolo> | 2014-11-30 12:34:21 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2014-11-30 12:34:21 +0000 |
| commit | 0fdb271a788555775f34326b9f1a1d15a313961a (patch) | |
| tree | ea4aaa0e69b3acb81a104754720bd1c633777d3d /src | |
| parent | 979756355244b3327a99a90a3e603168b1ba3e2e (diff) | |
Make sure that subwindows won’t leak out of their parent window
even if they have coordinates that would provoke it.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10475 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_cocoa.mm | 163 |
1 files changed, 82 insertions, 81 deletions
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 0f310c98d..af785d357 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -1919,7 +1919,7 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi that implements the NSTextInputClient protocol to properly handle text input. It also implements the old NSTextInput protocol to run with OS <= 10.4. The few NSTextInput protocol methods that differ in signature from the NSTextInputClient protocol transmit the received message to the corresponding NSTextInputClient method. - If OS < 10.6, the FLView class is replaced by the FLViewBefore10_6 class that re-implements its fl_handle_keydown_event method. + If OS < 10.6, the FLView class implements differently its fl_handle_keydown_event method. Keyboard input sends keyDown: and performKeyEquivalent: messages to myview. The latter occurs for keys such as ForwardDelete, arrows and F1, and when the Ctrl or Cmd modifiers are used. Other key presses send keyDown: messages. @@ -1959,8 +1959,8 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi selectedRange = NSMakeRange(100, newSelection.length); to indicate that this length of text is selected. With OS <= 10.5, the fl_handle_keydown_event: method is implemented differently because neither the - inputContext nor the handleEvent: methods are available. It is re-implemented - by the FLViewBefore10_6 class as [[FLTextInputContext singleInstance] handleEvent:event]. + inputContext nor the handleEvent: methods are available. + It becomes [[FLTextInputContext singleInstance] handleEvent:event]. Method +[FLTextInputContext singleInstance] returns an instance of class FLTextInputContext that possesses a handleEvent: method. The class FLTextView implements the so-called view's "field editor". This editor is an instance of the FLTextView class allocated by the -(id)[FLWindowDelegate windowWillReturnFieldEditor: toObject:] method. @@ -2050,7 +2050,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil; } + (void)prepareEtext:(NSString*)aString; + (void)concatEtext:(NSString*)aString; -- (id)init; +- (id)initWithFrame:(NSRect)frameRect; - (void)drawRect:(NSRect)rect; - (BOOL)acceptsFirstResponder; - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent; @@ -2086,10 +2086,10 @@ static FLTextInputContext* fltextinputcontext_instance = nil; @end @implementation FLView -- (id)init +- (id)initWithFrame:(NSRect)frameRect { static NSInteger counter = 0; - self = [super init]; + self = [super initWithFrame:frameRect]; if (self) { in_key_event = NO; identifier = ++counter; @@ -2110,7 +2110,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil; - (BOOL)acceptsFirstResponder { - return YES; + return [[self window] parentWindow] ? NO : YES; // 10.2 } - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { @@ -2324,8 +2324,11 @@ static FLTextInputContext* fltextinputcontext_instance = nil; return NSDragOperationGeneric; } -- (BOOL)fl_handle_keydown_event:(NSEvent*)event { // used if OS ≥ 10.6 - return [[self performSelector:@selector(inputContext)] handleEvent:event]; +- (BOOL)fl_handle_keydown_event:(NSEvent*)event { + return fl_mac_os_version >= 100600 ? + [[self performSelector:@selector(inputContext)] handleEvent:event] + : + [[FLTextInputContext singleInstance] handleEvent:event]; } + (void)prepareEtext:(NSString*)aString { @@ -2410,6 +2413,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil; // for some reason, with the palette, the window does not redraw until the next mouse move or button push // sending a 'redraw()' or 'awake()' does not solve the issue! if (palette) Fl::flush(); + if (fl_mac_os_version < 100600) [[FLTextView singleInstance] setActive:NO]; fl_unlock_function(); } @@ -2539,26 +2543,8 @@ static FLTextInputContext* fltextinputcontext_instance = nil; - (NSInteger)conversationIdentifier { return identifier; } - -@end - -@interface FLViewBefore10_6 : FLView -- (BOOL)fl_handle_keydown_event:(NSEvent*)event; -- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange; -@end -@implementation FLViewBefore10_6 -- (BOOL)fl_handle_keydown_event:(NSEvent*)event -{ - return [[FLTextInputContext singleInstance] handleEvent:event]; -} -- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { - [super insertText:aString replacementRange:replacementRange]; - [[FLTextView singleInstance] setActive:NO]; -} @end -static Class FLViewThisOS = (fl_mac_os_version >= 100600 ? [FLView class] : [FLViewBefore10_6 class]); - void Fl_Window::fullscreen_x() { _set_fullscreen(); @@ -2726,8 +2712,10 @@ void Fl_X::make(Fl_Window* w) contentRect:crect styleMask:winstyle]; [cw setFrameOrigin:crect.origin]; - if (!w->parent()) [cw setHasShadow:YES]; - [cw setAcceptsMouseMovedEvents:YES]; + if (!w->parent()) { + [cw setHasShadow:YES]; + [cw setAcceptsMouseMovedEvents:YES]; + } if (w->shape_data_) { [cw setOpaque:NO]; // shaped windows must be non opaque [cw setBackgroundColor:[NSColor clearColor]]; // and with transparent background color @@ -2746,7 +2734,7 @@ void Fl_X::make(Fl_Window* w) x->next = NULL; Fl_X::first = x; } - FLView *myview = [[FLViewThisOS alloc] init]; + FLView *myview = [[FLView alloc] initWithFrame:crect]; [cw setContentView:myview]; [myview release]; [cw setLevel:winlevel]; @@ -2780,29 +2768,39 @@ void Fl_X::make(Fl_Window* w) if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle(FL_FOCUS, w); if (!w->parent()) Fl::first_window(w); [cw setDelegate:[FLWindowDelegate singleInstance]]; - if (fl_show_iconic) { - fl_show_iconic = 0; - [cw miniaturize:nil]; - } else if (w->parent()) { - set_subwindow_frame(w); - } else { - [cw makeKeyAndOrderFront:nil]; - } - - if (w->parent()) { - [cw setIgnoresMouseEvents:YES]; // needs OS X 10.2 - // next 2 statements so a subwindow doesn't leak out of its parent window - [cw setOpaque:NO]; - [cw setBackgroundColor:[NSColor clearColor]]; // transparent background color - } else { - crect = [[cw contentView] frame]; - w->w(int(crect.size.width)); - w->h(int(crect.size.height)); - crect = [cw frame]; - w->x(int(crect.origin.x)); - w->y(int(main_screen_height - (crect.origin.y + w->h()))); + if (fl_show_iconic) { + fl_show_iconic = 0; + [cw miniaturize:nil]; + } else if (w->parent()) { + [cw setIgnoresMouseEvents:YES]; // needs OS X 10.2 + // next 2 statements so a subwindow doesn't leak out of its parent window + [cw setOpaque:NO]; + [cw setBackgroundColor:[NSColor clearColor]]; // transparent background color + CGRect prect = CGRectMake(0, 0, w->window()->w(), w->window()->h()); + CGRect srect = CGRectMake(w->x(), w->y(), w->w(), w->h()); + if (!CGRectContainsRect(prect, srect)) { // if subwindow extends outside its parent window + CGRect clip = CGRectIntersection(prect, srect); + clip = CGRectOffset(clip, -w->x(), -w->y()); + clip = fl_cgrectmake_cocoa(clip.origin.x, clip.origin.y, clip.size.width, clip.size.height); + x->subRect = new CGRect(clip); } - + set_subwindow_frame(w); + // needed if top window was first displayed miniaturized + FLWindow *pxid = fl_xid(w->top_window()); + [pxid makeFirstResponder:[pxid contentView]]; + } else { + [cw makeKeyAndOrderFront:nil]; + } + + if (!w->parent()) { + crect = [[cw contentView] frame]; + w->w(int(crect.size.width)); + w->h(int(crect.size.height)); + crect = [cw frame]; + w->x(int(crect.origin.x)); + w->y(int(main_screen_height - (crect.origin.y + w->h()))); + } + int old_event = Fl::e_number; w->handle(Fl::e_number = FL_SHOW); Fl::e_number = old_event; @@ -2872,7 +2870,7 @@ void Fl_Window::show() { labeltype(FL_NO_LABEL); } Fl_Tooltip::exit(this); - if (!shown()) { + if (!shown() && (!parent() || ![fl_xid(top_window()) isMiniaturized])) { Fl_X::make(this); } else { if ( !parent() ) { @@ -2915,39 +2913,42 @@ void Fl_Window::resize(int X,int Y,int W,int H) { } Fl_Group::resize(X,Y,W,H); if ([i->xid parentWindow]) set_subwindow_frame(this); - // make sure that subwindows of this window don't leak out of their parent window - NSArray *children = [fl_xid(this) childWindows]; // 10.2 - NSEnumerator *enumerator = [children objectEnumerator]; - id child; - while ((child = [enumerator nextObject]) != nil) { - [[(FLWindow*)child contentView] setNeedsDisplay:YES]; - Fl_Window *childw = [child getFl_Window]; - CGRect prect = CGRectMake(0, 0, w(), h()); - CGRect srect = CGRectMake(childw->x(), childw->y(), childw->w(), childw->h()); - CGRect **active = &(Fl_X::i(childw)->subRect); - delete *active; - *active = NULL; - if (!CGRectContainsRect(prect, srect)) { // if subwindow extends outside its parent window - CGRect clip = CGRectIntersection(prect, srect); - clip = CGRectOffset(clip, -childw->x(), -childw->y()); - clip = fl_cgrectmake_cocoa(clip.origin.x, clip.origin.y, clip.size.width, clip.size.height); - *active = new CGRect(clip); - } - } } else { - x(X); y(Y); + x(X); y(Y); + } + } + else { + resize_from_system = 0; + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) { + redraw(); + } + } else { + x(X); y(Y); } - return; } - resize_from_system = 0; if (is_a_resize) { - Fl_Group::resize(X,Y,W,H); - if (shown()) { - redraw(); + // make sure that subwindows of this window don't leak out of their parent window + NSArray *children = [fl_xid(this) childWindows]; // 10.2 + NSEnumerator *enumerator = [children objectEnumerator]; + id child; + while ((child = [enumerator nextObject]) != nil) { + [[(FLWindow*)child contentView] setNeedsDisplay:YES]; + Fl_Window *childw = [child getFl_Window]; + CGRect prect = CGRectMake(0, 0, w(), h()); + CGRect srect = CGRectMake(childw->x(), childw->y(), childw->w(), childw->h()); + CGRect **active = &(Fl_X::i(childw)->subRect); + delete *active; + *active = NULL; + if (!CGRectContainsRect(prect, srect)) { // if subwindow extends outside its parent window + CGRect clip = CGRectIntersection(prect, srect); + clip = CGRectOffset(clip, -childw->x(), -childw->y()); + clip = fl_cgrectmake_cocoa(clip.origin.x, clip.origin.y, clip.size.width, clip.size.height); + *active = new CGRect(clip); + } } - } else { - x(X); y(Y); } } @@ -3356,7 +3357,7 @@ void Fl_X::map() { } //+ link to window list if (w && w->parent()) { - w->redraw(); + w->redraw(); // possibly not necessary } if (cursor) { [(NSCursor*)cursor release]; |
