Search code examples
pythoninterfacefreezechromium-embedded

cef python - Freeze when resizing


Today I am trying to develop an UI using cefpython which allows me to embed a web browser and interacts with it with javascript bindings.

I'm using it to develop on Windows platform. For this purpose, I am using the "multi_threaded_message_loop" flag which allows me to gain in performance. I'm also using wxpython on python 3 to embed it.

The problem is when I resize my window, the use of WindowUtils.OnSize() freezes my app. 99% of the time, it happens when the browser is loading (but it also happens when it's done (rarely)).

Here is a sample code to reproduce :

import platform
import sys

import wx
from cefpython3 import cefpython

WindowUtils = cefpython.WindowUtils()

WIDTH = 800
HEIGHT = 600

import os

class MainFrame(wx.Frame):
    browser = None
    mainPanel = None

    def createMainBrowser(self):
        self.browser = self.createBrowser(self.mainPanel)

    def createBrowser(self, parent):
        browser = cefpython.CreateBrowserSync(
            self.getWindowInfo(parent),
            browserSettings={},
            navigateUrl='http://www.google.com'
        )
        return browser

    def getWindowInfo(self, parent):
        windowInfo = cefpython.WindowInfo()
        windowInfo.SetAsChild(parent.GetHandle(), [0, 0, WIDTH, HEIGHT])
        return windowInfo

    def __init__(self):
        wx.Frame.__init__(
            self, parent=None, id=wx.ID_ANY, title='wx', size=(WIDTH, HEIGHT)
        )
        self.mainPanel = wx.Panel(self)
        self.mainPanel.SetBackgroundColour(wx.GREEN)

        cefpython.PostTask(cefpython.TID_UI, self.createMainBrowser)

        self.mainPanel.Bind(wx.EVT_SIZE, self.OnSize)

    def OnSize(self, _):
        if not self.browser:
            return

        WindowUtils.OnSize(self.mainPanel.GetHandle(), 0, 0, 0)
        self.browser.NotifyMoveOrResizeStarted()


class App(wx.App):
    def OnInit(self):
        frame = MainFrame()
        frame.Show()
        return True

if __name__ == '__main__':
    sys.excepthook = cefpython.ExceptHook  # To shutdown all CEF processes on error
    cefpython.Initialize({
        "locales_dir_path": cefpython.GetModuleDirectory() + "/locales",
        "browser_subprocess_path": cefpython.GetModuleDirectory() + "/subprocess",
        "auto_zooming": "system_dpi",
        "multi_threaded_message_loop": True,
    })
    app = App(False)
    app.MainLoop()
    cefpython.Shutdown()

Thank you a lot for your help !

Alann


Solution

  • Problem solved ! Instead of using

    def OnSize(self, _):
        if not self.browser:
            return
    
        WindowUtils.OnSize(self.mainPanel.GetHandle(), 0, 0, 0)
        self.browser.NotifyMoveOrResizeStarted()
    

    I use

    def OnSize(self, sizeEvent):
        if not self.browser:
            return
    
        w = sizeEvent.GetSize().GetWidth()
        h = sizeEvent.GetSize().GetHeight()
        win32gui.SetWindowPos(self.browser.GetWindowHandle(), 0, 0, 0, w, h, 0)
        self.browser.NotifyMoveOrResizeStarted()
    

    I don't know if this is because I'm on windows 10 but maybe WindowsUtils needs to be updated !