@@ -177,6 +177,10 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() | |||
extern void initialiseNSApplication(); | |||
#endif | |||
#if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra | |||
extern int juce_gtkWebkitMain (int argc, const char* argv[]); | |||
#endif | |||
#if JUCE_WINDOWS | |||
const char* const* juce_argv = nullptr; | |||
int juce_argc = 0; | |||
@@ -218,6 +222,11 @@ int JUCEApplicationBase::main (int argc, const char* argv[], void* customDelegat | |||
initialiseNSApplication(); | |||
#endif | |||
#if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra | |||
if (argc >= 2 && String (argv[1]) == "--juce-gtkwebkitfork-child") | |||
return juce_gtkWebkitMain (argc, argv); | |||
#endif | |||
#if JUCE_IOS | |||
return juce_iOSMain (argc, argv, customDelegate); | |||
#else | |||
@@ -69,14 +69,16 @@ public: | |||
of the XEmbedProtocol. When using this version of the protocol | |||
you must call getHostWindowID() and pass this id to the foreign toolkit. | |||
*/ | |||
XEmbedComponent (bool wantsKeyboardFocus = true); | |||
XEmbedComponent (bool wantsKeyboardFocus = true, | |||
bool allowForeignWidgetToResizeComponent = false); | |||
/** Create a JUCE component wrapping the foreign widget with id wID | |||
Use this constructor if you are using the client initiated version | |||
of the XEmbedProtocol. | |||
*/ | |||
XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus = true); | |||
XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus = true, | |||
bool allowForeignWidgetToResizeComponent = false); | |||
/** Destructor. */ | |||
@@ -21,6 +21,10 @@ | |||
============================================================================== | |||
*/ | |||
//============================================================================== | |||
extern int juce_gtkWebkitMain (int argc, const char* argv[]); | |||
class CommandReceiver | |||
{ | |||
public: | |||
@@ -150,7 +154,7 @@ public: | |||
: outChannel (outChannelToUse), receiver (this, inChannel) | |||
{} | |||
void entry() | |||
int entry() | |||
{ | |||
CommandReceiver::setBlocking (outChannel, true); | |||
@@ -197,6 +201,7 @@ public: | |||
receiver.tryNextRead(); | |||
gtk_main(); | |||
return 0; | |||
} | |||
void goToURL (const var& params) | |||
@@ -256,7 +261,7 @@ public: | |||
void quit() | |||
{ | |||
exit (-1); | |||
gtk_main_quit(); | |||
} | |||
bool onNavigation (String frameName, | |||
@@ -502,12 +507,25 @@ private: | |||
{ | |||
xembed = nullptr; | |||
kill (childProcess, SIGTERM); | |||
int status = 0, result; | |||
int status = 0; | |||
result = waitpid (childProcess, &status, WNOHANG); | |||
for (int i = 0; i < 15 && (! WIFEXITED(status) || result != childProcess); ++i) | |||
{ | |||
Thread::sleep (100); | |||
result = waitpid (childProcess, &status, WNOHANG); | |||
} | |||
while (! WIFEXITED(status)) | |||
waitpid (childProcess, &status, 0); | |||
// clean-up any zombies | |||
status = 0; | |||
if (! WIFEXITED(status) || result != childProcess) | |||
{ | |||
do | |||
{ | |||
kill (childProcess, SIGTERM); | |||
waitpid (childProcess, &status, 0); | |||
} while (! WIFEXITED(status)); | |||
} | |||
childProcess = 0; | |||
} | |||
@@ -530,8 +548,24 @@ private: | |||
close (inPipe[0]); | |||
close (outPipe[1]); | |||
GtkChildProcess child (outPipe[0], inPipe[1]); | |||
child.entry(); | |||
HeapBlock<const char*> argv (5); | |||
StringArray arguments; | |||
arguments.add (File::getSpecialLocation (File::currentExecutableFile).getFullPathName()); | |||
arguments.add ("--juce-gtkwebkitfork-child"); | |||
arguments.add (String (outPipe[0])); | |||
arguments.add (String (inPipe [1])); | |||
for (int i = 0; i < arguments.size(); ++i) | |||
argv[i] = arguments[i].toRawUTF8(); | |||
argv[4] = nullptr; | |||
#if JUCE_STANDALONE_APPLICATION | |||
execv (arguments[0].toRawUTF8(), (char**) argv.getData()); | |||
#else | |||
juce_gtkWebkitMain (4, (const char**) argv.getData()); | |||
#endif | |||
exit (0); | |||
} | |||
@@ -766,3 +800,13 @@ void WebBrowserComponent::clearCookies() | |||
// store cookies on linux | |||
jassertfalse; | |||
} | |||
int juce_gtkWebkitMain (int argc, const char* argv[]) | |||
{ | |||
if (argc != 4) return -1; | |||
GtkChildProcess child (String (argv[2]).getIntValue(), | |||
String (argv[3]).getIntValue()); | |||
return child.entry(); | |||
} |
@@ -203,9 +203,10 @@ public: | |||
public: | |||
//============================================================================== | |||
Pimpl (XEmbedComponent& parent, Window x11Window, bool wantsKeyboardFocus, bool isClientInitiated) | |||
Pimpl (XEmbedComponent& parent, Window x11Window, | |||
bool wantsKeyboardFocus, bool isClientInitiated, bool shouldAllowResize) | |||
: owner (parent), atoms (x11display.get()), clientInitiated (isClientInitiated), | |||
wantsFocus (wantsKeyboardFocus) | |||
wantsFocus (wantsKeyboardFocus), allowResize (shouldAllowResize) | |||
{ | |||
if (widgets == nullptr) | |||
widgets = new Array<Pimpl*>; | |||
@@ -337,6 +338,7 @@ private: | |||
bool clientInitiated; | |||
bool wantsFocus = false; | |||
bool allowResize = false; | |||
bool supportsXembed = false; | |||
bool hasBeenMapped = false; | |||
int xembedVersion = maxXEmbedVersionToSupport; | |||
@@ -582,7 +584,11 @@ private: | |||
propertyChanged (e.xproperty.atom); | |||
return true; | |||
case ConfigureNotify: | |||
configureNotify(); | |||
if (allowResize) | |||
configureNotify(); | |||
else | |||
MessageManager::callAsync([this] () {componentMovedOrResized (owner, true, true);}); | |||
return true; | |||
} | |||
} | |||
@@ -713,14 +719,14 @@ Array<XEmbedComponent::Pimpl*>* XEmbedComponent::Pimpl::widgets = nullptr; | |||
HashMap<ComponentPeer*,XEmbedComponent::Pimpl::SharedKeyWindow*>* XEmbedComponent::Pimpl::SharedKeyWindow::keyWindows = nullptr; | |||
//============================================================================== | |||
XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus) | |||
: pimpl (new Pimpl (*this, 0, wantsKeyboardFocus, false)) | |||
XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent) | |||
: pimpl (new Pimpl (*this, 0, wantsKeyboardFocus, false, allowForeignWidgetToResizeComponent)) | |||
{ | |||
setOpaque (true); | |||
} | |||
XEmbedComponent::XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus) | |||
: pimpl (new Pimpl (*this, wID, wantsKeyboardFocus, true)) | |||
XEmbedComponent::XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent) | |||
: pimpl (new Pimpl (*this, wID, wantsKeyboardFocus, true, allowForeignWidgetToResizeComponent)) | |||
{ | |||
setOpaque (true); | |||
} | |||