summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--src/Fl_Menu.cxx46
-rw-r--r--src/Fl_mac.cxx15
3 files changed, 53 insertions, 10 deletions
diff --git a/CHANGES b/CHANGES
index fcff32489..1ae85e6fb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,7 @@
CHANGES IN FLTK 1.1.8
+ - Better event mouse handling fixing detached menus and
+ sticky tooltips (STR #1463, STR #449)
- Documentation fixes (STR #1454, STR #1455, STR #1456,
STR #1457, STR #1458, STR #1460, STR #1481)
- Added Fl::scrollbar_size() methods that are used by all
diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx
index c04a1c9b2..2f06f4850 100644
--- a/src/Fl_Menu.cxx
+++ b/src/Fl_Menu.cxx
@@ -94,6 +94,9 @@ class menuwindow : public Fl_Menu_Window {
public:
menutitle* title;
int handle(int);
+#ifdef __APPLE__
+ int early_hide_handle(int);
+#endif
int itemheight; // zero == menubar
int numitems;
int selected;
@@ -526,6 +529,7 @@ struct menustate {
int nummenus;
int menubar; // if true p[0] is a menubar
int state;
+ menuwindow* fakemenu; // kludge for buttons in menubar
int is_inside(int mx, int my);
};
static menustate* p;
@@ -580,6 +584,35 @@ static int backward(int menu) { // previous item in menu menu if possible
}
int menuwindow::handle(int e) {
+#ifdef __APPLE__
+ // This off-route takes care of the "detached menu" bug on OS X.
+ // Apple event handler requires that we hide all menu windows right
+ // now, so that Carbon can continue undisturbed with handling window
+ // manager events, like dragging the application window.
+ int ret = early_hide_handle(e);
+ menustate &pp = *p;
+ if (pp.state == DONE_STATE) {
+ hide();
+ if (pp.fakemenu) {
+ pp.fakemenu->hide();
+ if (pp.fakemenu->title)
+ pp.fakemenu->title->hide();
+ }
+ int i = pp.nummenus;
+ while (i>0) {
+ menuwindow *mw = pp.p[--i];
+ if (mw) {
+ mw->hide();
+ if (mw->title)
+ mw->title->hide();
+ }
+ }
+ }
+ return ret;
+}
+
+int menuwindow::early_hide_handle(int e) {
+#endif
menustate &pp = *p;
switch (e) {
case FL_KEYBOARD:
@@ -723,8 +756,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
pp.nummenus = 1;
pp.menubar = menubar;
pp.state = INITIAL_STATE;
-
- menuwindow* fakemenu = 0; // kludge for buttons in menubar
+ pp.fakemenu = 0; // kludge for buttons in menubar
// preselected item, pop up submenus if necessary:
if (initial_item && mw.selected >= 0) {
@@ -761,7 +793,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
if (pp.current_item == oldi) continue;}
// only do rest if item changes:
- delete fakemenu; fakemenu = 0; // turn off "menubar button"
+ delete pp.fakemenu; pp.fakemenu = 0; // turn off "menubar button"
if (!pp.current_item) { // pointing at nothing
// turn off selection in deepest menu, but don't erase other menus:
@@ -769,7 +801,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
continue;
}
- delete fakemenu; fakemenu = 0;
+ delete pp.fakemenu; pp.fakemenu = 0;
initial_item = 0; // stop the startup code
pp.p[pp.menu_number]->autoscroll(pp.item_number);
@@ -831,17 +863,17 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus];
if (!pp.menu_number && pp.menubar) {
// kludge so "menubar buttons" turn "on" by using menu title:
- fakemenu = new menuwindow(0,
+ pp.fakemenu = new menuwindow(0,
cw.x()+cw.titlex(pp.item_number),
cw.y()+cw.h(), 0, 0,
0, m, 0, 1);
- fakemenu->title->show();
+ pp.fakemenu->title->show();
}
}
}
const Fl_Menu_Item* m = pp.current_item;
Fl::release();
- delete fakemenu;
+ delete pp.fakemenu;
while (pp.nummenus>1) delete pp.p[--pp.nummenus];
mw.hide();
return m;
diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx
index 8bc32f085..8f21001f3 100644
--- a/src/Fl_mac.cxx
+++ b/src/Fl_mac.cxx
@@ -967,14 +967,18 @@ static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, Even
{
case kEventMouseDown:
part = FindWindow( pos, &tempXid );
- if ( part != inContent ) {
+ if ( part == inGrow && !Fl::grab()) {
fl_unlock_function();
suppressed = 1;
+ Fl_Tooltip::current(0L);
+ // if (grab() && grab()!=thisWindow) handle grab first (popping down menu bars)
+ // if (modal() && modal()!=thisWindow) handle modal first (popping down menu bars)
return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us
}
suppressed = 0;
- if ( !IsWindowActive( xid ) )
+ if (part==inContent && !IsWindowActive( xid ) ) {
CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect
+ }
// normal handling of mouse-down follows
fl_os_capture = xid;
sendEvent = FL_PUSH;
@@ -1019,7 +1023,12 @@ static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, Even
Fl::e_x = pos.h;
Fl::e_y = pos.v;
SetPort( oldPort );
- Fl::handle( sendEvent, window );
+ if (GetEventKind(event)==kEventMouseDown && part!=inContent) {
+ Fl::handle( sendEvent, window );
+ CallNextEventHandler( nextHandler, event ); // let the OS handle this for us
+ } else {
+ Fl::handle( sendEvent, window );
+ }
break;
}