Browse Source

Fixed resizing issues and memory leaks in linux web browser component

tags/2021-05-28
hogliux 8 years ago
parent
commit
7a7619d64e
4 changed files with 78 additions and 17 deletions
  1. +9
    -0
      modules/juce_events/messages/juce_ApplicationBase.cpp
  2. +4
    -2
      modules/juce_gui_extra/embedding/juce_XEmbedComponent.h
  3. +52
    -8
      modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp
  4. +13
    -7
      modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp

+ 9
- 0
modules/juce_events/messages/juce_ApplicationBase.cpp View File

@@ -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


+ 4
- 2
modules/juce_gui_extra/embedding/juce_XEmbedComponent.h View File

@@ -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. */


+ 52
- 8
modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp View File

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

+ 13
- 7
modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp View File

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


Loading…
Cancel
Save