When some application in OS X has multiple windows (many open documents, each in own window), it seems that all them share the same system menu, at least in FLTK. Is there a way to find the most recent selected window to send an event to it from the menu?
Here is my setup (Mac OS X 10.6.2, FLTK 1.3.3): have Shell
class with system menu. Each time new document is opened, new Shell
is created:
#ifdef __APPLE__
void Shell::macOpen(const char *fileName)
{
// If there are empty shell, open the model in it
if (s_empty != 0)
{
...
s_empty = 0;
}
// Otherwise, create new shell with the model
else
{
char *args[1];
args[0] = (char *) fileName;
new Shell(1, args, s_conf, s_dct, fileName, 1);
}
}
#endif
Then I keep track on the most recently selected Shell
saving it into static Shell *Shell::s_current
:
int Shell::handle(int event)
{
...
case FL_FOCUS:
#ifdef __APPLE__
// We just selected some shell, it is current.
s_current = this;
cout << "Select shell with address: [" << s_current << "]" << endl;
#endif
return 1;
...
}
This piece seems to work, as I can see the traces each time I select some Shell
:
Select shell with address: [0x8206db0]
Select shell with address: [0x82375f0]
Select shell with address: [0x5d20650]
Select shell with address: [0x82375f0]
Now, given:
Shell *Shell::currentShell(Fl_Widget *w)
{
cout << "Widget address: [" << w << "]" << endl;
Shell *result = 0;
if (w != 0)
{
result = (Shell *) w->window();
cout << "Widget wingow address: [" << result << "]" << endl;
}
#ifdef __APPLE__
else
{
result = s_current;
cout << "Last selected shell address: [" << result << "]" << endl;
}
#endif
return result;
}
I have some callback:
void Shell::shortcutCB(Fl_Widget *w, void *data)
{
cout << "Shortcut" << endl;
Shell *ref = currentShell(w);
if (ref != 0)
{
...
}
}
When this callback is executed from the menu and more Shell
s are open, I get the following error:
Bus error
With no trace from either Shell::shortcutCB
or Shell::currentShell
. When the only Shell
is open, all works perfectly. When more Shell
s are open and I close all but one, the error arises again. There is no problems when the same callback is called from some widget within Shell
or is delivered from keyboard shortcut.
Solved the problem with the following 3 steps:
Declaring manu bar in OS X also static (here was the fail):
#ifdef __APPLE__
static Fl_Sys_Menu_Bar *s_menubar;
#else
Fl_Sys_Menu_Bar *m_menubar;
#endif
Save current Shell::s_current
not only on FL_FOCUS
event, but on any event handled by Shell
, that is, each time it returns 1:
int Shell::handle(int event)
{
int result = 0;
switch (event)
{
// Set result = 1 when handling the event
...
}
#ifdef __APPLE__
if (result == 1)
{
// We just selected some shell, it is current.
s_current = this;
cout << "Select shell with address: [" << s_current << "]" << endl;
}
#endif
return result;
}
Use Shell::s_current
for menu callbacks on OS X regardless of generating widget of the call:
Shell *Shell::currentShell(Fl_Widget *w)
{
Shell *result = 0;
#ifdef __APPLE__
result = s_current;
cout << "Last selected shell address: [" << result << "]" << endl;
#else
cout << "Widget address: [" << w << "]" << endl;
if (w != 0)
{
result = (Shell *) w->window();
cout << "Widget wingow address: [" << result << "]" << endl;
}
#endif
return result;
}