| @@ -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); | |||
| } | |||