summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2014-11-30 12:34:21 +0000
committerManolo Gouy <Manolo>2014-11-30 12:34:21 +0000
commit0fdb271a788555775f34326b9f1a1d15a313961a (patch)
treeea4aaa0e69b3acb81a104754720bd1c633777d3d /src
parent979756355244b3327a99a90a3e603168b1ba3e2e (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.mm163
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];