@@ -177,6 +177,10 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() | |||||
extern void initialiseNSApplication(); | extern void initialiseNSApplication(); | ||||
#endif | #endif | ||||
#if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra | |||||
extern int juce_gtkWebkitMain (int argc, const char* argv[]); | |||||
#endif | |||||
#if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
const char* const* juce_argv = nullptr; | const char* const* juce_argv = nullptr; | ||||
int juce_argc = 0; | int juce_argc = 0; | ||||
@@ -218,6 +222,11 @@ int JUCEApplicationBase::main (int argc, const char* argv[], void* customDelegat | |||||
initialiseNSApplication(); | initialiseNSApplication(); | ||||
#endif | #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 | #if JUCE_IOS | ||||
return juce_iOSMain (argc, argv, customDelegate); | return juce_iOSMain (argc, argv, customDelegate); | ||||
#else | #else | ||||
@@ -69,14 +69,16 @@ public: | |||||
of the XEmbedProtocol. When using this version of the protocol | of the XEmbedProtocol. When using this version of the protocol | ||||
you must call getHostWindowID() and pass this id to the foreign toolkit. | 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 | /** Create a JUCE component wrapping the foreign widget with id wID | ||||
Use this constructor if you are using the client initiated version | Use this constructor if you are using the client initiated version | ||||
of the XEmbedProtocol. | of the XEmbedProtocol. | ||||
*/ | */ | ||||
XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus = true); | |||||
XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus = true, | |||||
bool allowForeignWidgetToResizeComponent = false); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
@@ -21,6 +21,10 @@ | |||||
============================================================================== | ============================================================================== | ||||
*/ | */ | ||||
//============================================================================== | |||||
extern int juce_gtkWebkitMain (int argc, const char* argv[]); | |||||
class CommandReceiver | class CommandReceiver | ||||
{ | { | ||||
public: | public: | ||||
@@ -150,7 +154,7 @@ public: | |||||
: outChannel (outChannelToUse), receiver (this, inChannel) | : outChannel (outChannelToUse), receiver (this, inChannel) | ||||
{} | {} | ||||
void entry() | |||||
int entry() | |||||
{ | { | ||||
CommandReceiver::setBlocking (outChannel, true); | CommandReceiver::setBlocking (outChannel, true); | ||||
@@ -197,6 +201,7 @@ public: | |||||
receiver.tryNextRead(); | receiver.tryNextRead(); | ||||
gtk_main(); | gtk_main(); | ||||
return 0; | |||||
} | } | ||||
void goToURL (const var& params) | void goToURL (const var& params) | ||||
@@ -256,7 +261,7 @@ public: | |||||
void quit() | void quit() | ||||
{ | { | ||||
exit (-1); | |||||
gtk_main_quit(); | |||||
} | } | ||||
bool onNavigation (String frameName, | bool onNavigation (String frameName, | ||||
@@ -502,12 +507,25 @@ private: | |||||
{ | { | ||||
xembed = nullptr; | 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; | childProcess = 0; | ||||
} | } | ||||
@@ -530,8 +548,24 @@ private: | |||||
close (inPipe[0]); | close (inPipe[0]); | ||||
close (outPipe[1]); | 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); | exit (0); | ||||
} | } | ||||
@@ -766,3 +800,13 @@ void WebBrowserComponent::clearCookies() | |||||
// store cookies on linux | // store cookies on linux | ||||
jassertfalse; | 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: | 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), | : owner (parent), atoms (x11display.get()), clientInitiated (isClientInitiated), | ||||
wantsFocus (wantsKeyboardFocus) | |||||
wantsFocus (wantsKeyboardFocus), allowResize (shouldAllowResize) | |||||
{ | { | ||||
if (widgets == nullptr) | if (widgets == nullptr) | ||||
widgets = new Array<Pimpl*>; | widgets = new Array<Pimpl*>; | ||||
@@ -337,6 +338,7 @@ private: | |||||
bool clientInitiated; | bool clientInitiated; | ||||
bool wantsFocus = false; | bool wantsFocus = false; | ||||
bool allowResize = false; | |||||
bool supportsXembed = false; | bool supportsXembed = false; | ||||
bool hasBeenMapped = false; | bool hasBeenMapped = false; | ||||
int xembedVersion = maxXEmbedVersionToSupport; | int xembedVersion = maxXEmbedVersionToSupport; | ||||
@@ -582,7 +584,11 @@ private: | |||||
propertyChanged (e.xproperty.atom); | propertyChanged (e.xproperty.atom); | ||||
return true; | return true; | ||||
case ConfigureNotify: | case ConfigureNotify: | ||||
configureNotify(); | |||||
if (allowResize) | |||||
configureNotify(); | |||||
else | |||||
MessageManager::callAsync([this] () {componentMovedOrResized (owner, true, true);}); | |||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
@@ -713,14 +719,14 @@ Array<XEmbedComponent::Pimpl*>* XEmbedComponent::Pimpl::widgets = nullptr; | |||||
HashMap<ComponentPeer*,XEmbedComponent::Pimpl::SharedKeyWindow*>* XEmbedComponent::Pimpl::SharedKeyWindow::keyWindows = 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); | 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); | setOpaque (true); | ||||
} | } | ||||