From 0da13937e50f389cba25533959c2b760403fb80f Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Mon, 20 Jul 2020 19:19:03 +0200 Subject: [PATCH 01/27] Fix Mac issues in Tkinter example (#309, #441) Still some issues on startup, see: https://github.com/cztomczak/cefpython/issues/583 --- examples/tkinter_.py | 73 +++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/examples/tkinter_.py b/examples/tkinter_.py index c823f3dc..327f171f 100644 --- a/examples/tkinter_.py +++ b/examples/tkinter_.py @@ -44,7 +44,7 @@ def main(): - logger.setLevel(_logging.INFO) + logger.setLevel(_logging.DEBUG) stream_handler = _logging.StreamHandler() formatter = _logging.Formatter("[%(filename)s] %(message)s") stream_handler.setFormatter(formatter) @@ -55,19 +55,23 @@ def main(): logger.info("Tk {ver}".format(ver=tk.Tcl().eval('info patchlevel'))) assert cef.__version__ >= "55.3", "CEF Python v55.3+ required to run this" sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error + # Tk must be initialized before CEF otherwise fatal error (Issue #306) root = tk.Tk() app = MainFrame(root) - # Tk must be initialized before CEF otherwise fatal error (Issue #306) - cef.Initialize() + settings = {} + if MAC: + settings["external_message_pump"] = True + cef.Initialize(settings=settings) app.mainloop() + logger.debug("Main loop exited") cef.Shutdown() - class MainFrame(tk.Frame): def __init__(self, root): self.browser_frame = None self.navigation_bar = None + self.root = root # Root root.geometry("900x640") @@ -124,7 +128,9 @@ def on_focus_out(self, _): def on_close(self): if self.browser_frame: self.browser_frame.on_root_close() - self.master.destroy() + self.browser_frame = None + else: + self.master.destroy() def get_browser(self): if self.browser_frame: @@ -147,11 +153,12 @@ def setup_icon(self): class BrowserFrame(tk.Frame): - def __init__(self, master, navigation_bar=None): + def __init__(self, mainframe, navigation_bar=None): self.navigation_bar = navigation_bar self.closing = False self.browser = None - tk.Frame.__init__(self, master) + tk.Frame.__init__(self, mainframe) + self.mainframe = mainframe self.bind("", self.on_focus_in) self.bind("", self.on_focus_out) self.bind("", self.on_configure) @@ -165,27 +172,42 @@ def embed_browser(self): self.browser = cef.CreateBrowserSync(window_info, url="https://www.google.com/") assert self.browser + self.browser.SetClientHandler(LifespanHandler(self)) self.browser.SetClientHandler(LoadHandler(self)) self.browser.SetClientHandler(FocusHandler(self)) self.message_loop_work() def get_window_handle(self): - if self.winfo_id() > 0: - return self.winfo_id() - elif MAC: - # On Mac window id is an invalid negative value (Issue #308). - # This is kind of a dirty hack to get window handle using - # PyObjC package. If you change structure of windows then you + if MAC: + # Do not use self.winfo_id() on Mac, because of these issues: + # 1. Window id sometimes has an invalid negative value (Issue #308). + # 2. Even with valid window id it crashes during the call to NSView.setAutoresizingMask: + # https://github.com/cztomczak/cefpython/issues/309#issuecomment-661094466 + # + # To fix it using PyObjC package to obtain window handle. If you change structure of windows then you # need to do modifications here as well. + # + # There is still one issue with this solution. Sometimes there is more than one window, for example when application + # didn't close cleanly last time Python displays an NSAlert window asking whether to Reopen that window. In such + # case app will crash and you will see in console: + # > Fatal Python error: PyEval_RestoreThread: NULL tstate + # > zsh: abort python tkinter_.py + # Error messages related to this: https://github.com/cztomczak/cefpython/issues/441 + # + # There is yet another issue that might be related as well: + # https://github.com/cztomczak/cefpython/issues/583 + # noinspection PyUnresolvedReferences from AppKit import NSApp # noinspection PyUnresolvedReferences import objc - # Sometimes there is more than one window, when application - # didn't close cleanly last time Python displays an NSAlert - # window asking whether to Reopen that window. + logger.info("winfo_id={}".format(self.winfo_id())) # noinspection PyUnresolvedReferences - return objc.pyobjc_id(NSApp.windows()[-1].contentView()) + content_view = objc.pyobjc_id(NSApp.windows()[-1].contentView()) + logger.info("content_view={}".format(content_view)) + return content_view + elif self.winfo_id() > 0: + return self.winfo_id() else: raise Exception("Couldn't obtain window handle") @@ -224,10 +246,15 @@ def on_focus_out(self, _): self.browser.SetFocus(False) def on_root_close(self): + logger.info("BrowserFrame.on_root_close") if self.browser: + logger.debug("CloseBrowser") self.browser.CloseBrowser(True) self.clear_browser_references() - self.destroy() + else: + logger.debug("tk.Frame.destroy") + self.destroy() + def clear_browser_references(self): # Clear browser references that you keep anywhere in your @@ -235,6 +262,16 @@ def clear_browser_references(self): self.browser = None +class LifespanHandler(object): + + def __init__(self, tkFrame): + self.tkFrame = tkFrame + + def OnBeforeClose(self, browser, **_): + logger.debug("LifespanHandler.OnBeforeClose") + self.tkFrame.quit() + + class LoadHandler(object): def __init__(self, browser_frame): From 3cc7606101f2b1b8191b4db3648c264349ca4628 Mon Sep 17 00:00:00 2001 From: cztomczak Date: Wed, 19 Aug 2020 11:14:04 +0200 Subject: [PATCH 02/27] Add keyboard handler snippet. --- examples/snippets/keyboard_handler.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 examples/snippets/keyboard_handler.py diff --git a/examples/snippets/keyboard_handler.py b/examples/snippets/keyboard_handler.py new file mode 100644 index 00000000..9b8e40c8 --- /dev/null +++ b/examples/snippets/keyboard_handler.py @@ -0,0 +1,19 @@ +from cefpython3 import cefpython as cef + + +def main(): + cef.Initialize() + browser = cef.CreateBrowserSync(url="https://www.google.com/", + window_title="Keyboard Handler") + browser.SetClientHandler(KeyboardHandler()) + cef.MessageLoop() + del browser + cef.Shutdown() + + +class KeyboardHandler(object): + def OnKeyEvent(self, browser, event, event_handle, **_): + print("OnKeyEvent: "+str(event)) + +if __name__ == '__main__': + main() From 2fcf395f4e67e83e5c1dc06b3bfd6818d4e42602 Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Fri, 9 Oct 2020 13:53:46 +0200 Subject: [PATCH 03/27] Update README.md Fix links. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 747381bf..546cd001 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Table of contents: ## Introduction CEF Python is an open source project founded by -[Czarek Tomczak](https://drive.google.com/file/d/17xmoT5Z_zTHkVclqPzrs2aAV64Uiu7fh/view) +[Czarek Tomczak](https://www.linkedin.com/in/czarektomczak/) in 2012 to provide Python bindings for the [Chromium Embedded Framework](https://bitbucket.org/chromiumembedded/cef) (CEF). The Chromium project focuses mainly on Google Chrome application @@ -317,7 +317,7 @@ notable are: If your company would like to sponsor CEF Python development efforts then please contact -[Czarek](https://drive.google.com/file/d/17xmoT5Z_zTHkVclqPzrs2aAV64Uiu7fh/view). +[Czarek](https://www.linkedin.com/in/czarektomczak/). Long term sponsorships are welcome and Czarek is open to ideas about the project. He would love to spend more time on developing this project, but he can't afford doing so in his free time. Currently there is no company From 019033d2919a4fab84cb832ec5b76aad12e39c40 Mon Sep 17 00:00:00 2001 From: Xianguang Zhou Date: Sun, 14 Feb 2021 22:44:22 +0800 Subject: [PATCH 04/27] Fix the bug of loading shared libraries. (#561) * Prepend the package directory path to the "LD_LIBRARY_PATH" environment variable. * Fix the bug of getting "LD_LIBRARY_PATH" environment variable. * Fix loading shared libraries on Linux. Co-authored-by: Czarek Tomczak --- tools/installer/cefpython3.__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/installer/cefpython3.__init__.py b/tools/installer/cefpython3.__init__.py index fc00000d..ef784f2c 100644 --- a/tools/installer/cefpython3.__init__.py +++ b/tools/installer/cefpython3.__init__.py @@ -26,9 +26,13 @@ package_dir = os.path.dirname(os.path.abspath(__file__)) -# This loads the libcef.so library for the subprocess executable. -# On Mac it works without setting library paths. -os.environ["LD_LIBRARY_PATH"] = package_dir +# This loads the libcef.so library for the subprocess executable on Linux. +# TODO: Use -Wl,-rpath=\$$ORIGIN in Makefile. +ld_library_path = os.environ.get("LD_LIBRARY_PATH") +if ld_library_path and ld_library_path.strip(): + os.environ["LD_LIBRARY_PATH"] = package_dir + os.pathsep + ld_library_path +else: + os.environ["LD_LIBRARY_PATH"] = package_dir # This env variable will be returned by cefpython.GetModuleDirectory(). os.environ["CEFPYTHON3_PATH"] = package_dir From 96f3b5ec1ef951a1959d378a5d4d87bf247b2c36 Mon Sep 17 00:00:00 2001 From: Martin Cejp Date: Sun, 14 Feb 2021 16:20:20 +0100 Subject: [PATCH 05/27] Fix pango library wrong include path (hb.h: No such file or directory) (#589) * Fix Fedora 32 build error (hb.h: No such file or directory) * Update client_handler/Makefile * Update client_handler/Makefile * Update cpp_utils/Makefile * Update subprocess/Makefile * Update subprocess/Makefile-libcefpythonapp * Update tools/cython_setup.py Co-authored-by: Czarek Tomczak --- src/client_handler/Makefile | 1 + src/cpp_utils/Makefile | 2 +- src/subprocess/Makefile | 1 + src/subprocess/Makefile-libcefpythonapp | 1 + tools/cython_setup.py | 2 ++ 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client_handler/Makefile b/src/client_handler/Makefile index d217660e..25e645ff 100644 --- a/src/client_handler/Makefile +++ b/src/client_handler/Makefile @@ -37,6 +37,7 @@ INC = -I./../ -I./../common/ -I$(PYTHON_INCLUDE) \ -I/usr/include/glib-2.0 \ -I/usr/include/cairo \ -I/usr/include/pango-1.0 \ + -I/usr/include/harfbuzz \ -I/usr/include/gdk-pixbuf-2.0 \ -I/usr/include/atk-1.0 \ -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ diff --git a/src/cpp_utils/Makefile b/src/cpp_utils/Makefile index 338fd960..e6a6a2fe 100644 --- a/src/cpp_utils/Makefile +++ b/src/cpp_utils/Makefile @@ -7,7 +7,7 @@ OUT = libcpp_utils.a INC = -I./../ -I/usr/include/gtk-2.0 \ -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include \ -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo \ - -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 \ + -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 \ -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \ -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ -I/usr/lib64/glib-2.0/include -I/usr/lib64/gtk-2.0/include \ diff --git a/src/subprocess/Makefile b/src/subprocess/Makefile index f52b72df..adc34fca 100644 --- a/src/subprocess/Makefile +++ b/src/subprocess/Makefile @@ -11,6 +11,7 @@ INC = -I./../ -I./../common/ -I$(PYTHON_INCLUDE) \ -I/usr/include/glib-2.0 \ -I/usr/include/cairo \ -I/usr/include/pango-1.0 \ + -I/usr/include/harfbuzz \ -I/usr/include/gdk-pixbuf-2.0 \ -I/usr/include/atk-1.0 \ -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ diff --git a/src/subprocess/Makefile-libcefpythonapp b/src/subprocess/Makefile-libcefpythonapp index 23fbde39..e8a6b852 100644 --- a/src/subprocess/Makefile-libcefpythonapp +++ b/src/subprocess/Makefile-libcefpythonapp @@ -36,6 +36,7 @@ INC = -I./../ -I./../common/ -I$(PYTHON_INCLUDE) \ -I/usr/include/glib-2.0 \ -I/usr/include/cairo \ -I/usr/include/pango-1.0 \ + -I/usr/include/harfbuzz \ -I/usr/include/gdk-pixbuf-2.0 \ -I/usr/include/atk-1.0 \ -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ diff --git a/tools/cython_setup.py b/tools/cython_setup.py index 4f0cafc6..52482cba 100644 --- a/tools/cython_setup.py +++ b/tools/cython_setup.py @@ -318,6 +318,7 @@ def get_include_dirs(): '/usr/include/gtk-unix-print-2.0', '/usr/include/cairo', '/usr/include/pango-1.0', + '/usr/include/harfbuzz', '/usr/include/gdk-pixbuf-2.0', '/usr/include/atk-1.0', # Fedora @@ -337,6 +338,7 @@ def get_include_dirs(): '/usr/include/gtk-unix-print-2.0', '/usr/include/cairo', '/usr/include/pango-1.0', + '/usr/include/harfbuzz', '/usr/include/gdk-pixbuf-2.0', '/usr/include/atk-1.0', # Ubuntu From 054ff3ca52106099d078f37b3f8986e5252c7733 Mon Sep 17 00:00:00 2001 From: Bryan Koroleski <44987192+bryan-koroleski-fivestars@users.noreply.github.com> Date: Sun, 14 Feb 2021 10:09:52 -0600 Subject: [PATCH 06/27] Update int range detection for Python 3 (#603) * Update int range detection for Python 3 Python 3 unified ints and longs into a single int type. The long type is still available in Cython as an alias to int. * Update javascript_bindings.pyx * Update process_message_utils.pyx Co-authored-by: Czarek Tomczak --- Authors | 1 + src/javascript_bindings.pyx | 2 ++ src/process_message_utils.pyx | 33 +++++++++------------------------ tools/cython_setup.py | 3 +++ 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/Authors b/Authors index b4c55d20..b44b24e6 100644 --- a/Authors +++ b/Authors @@ -19,3 +19,4 @@ Contributors: Dónal McMullan nobodyguy Elliot Woods + Bryan Koroleski diff --git a/src/javascript_bindings.pyx b/src/javascript_bindings.pyx index 9043639e..31620a6d 100644 --- a/src/javascript_bindings.pyx +++ b/src/javascript_bindings.pyx @@ -140,6 +140,8 @@ cdef class JavascriptBindings: return True elif valueType == int: return True + elif valueType == long: + return True elif valueType == type(None): return True elif IsFunctionOrMethod(valueType): diff --git a/src/process_message_utils.pyx b/src/process_message_utils.pyx index 8ced3f6c..e2d55dab 100644 --- a/src/process_message_utils.pyx +++ b/src/process_message_utils.pyx @@ -238,14 +238,9 @@ cdef CefRefPtr[CefListValue] PyListToCefListValue( ret.get().SetNull(index) elif valueType == bool: ret.get().SetBool(index, bool(value)) - elif valueType == int: - ret.get().SetInt(index, int(value)) - elif valueType == long: - # Int32 range is -2147483648..2147483647, we've increased the - # minimum size by one as Cython was throwing a warning: - # "unary minus operator applied to unsigned type, result still - # unsigned". - if -2147483647 <= value <= 2147483647: + elif valueType == int or valueType == long: # In Py3 int and long types are the same type. + # Int32 range is -2147483648..2147483647 + if INT_MIN <= value <= INT_MAX: ret.get().SetInt(index, int(value)) else: # Long values become strings. @@ -297,14 +292,9 @@ cdef void PyListToExistingCefListValue( cefListValue.get().SetNull(index) elif valueType == bool: cefListValue.get().SetBool(index, bool(value)) - elif valueType == int: - cefListValue.get().SetInt(index, int(value)) - elif valueType == long: - # Int32 range is -2147483648..2147483647, we've increased the - # minimum size by one as Cython was throwing a warning: - # "unary minus operator applied to unsigned type, result still - # unsigned". - if -2147483647 <= value <= 2147483647: + elif valueType == int or valueType == long: # In Py3 int and long types are the same type. + # Int32 range is -2147483648..2147483647 + if INT_MIN <= value <= INT_MAX: cefListValue.get().SetInt(index, int(value)) else: # Long values become strings. @@ -357,14 +347,9 @@ cdef CefRefPtr[CefDictionaryValue] PyDictToCefDictionaryValue( ret.get().SetNull(cefKey) elif valueType == bool: ret.get().SetBool(cefKey, bool(value)) - elif valueType == int: - ret.get().SetInt(cefKey, int(value)) - elif valueType == long: - # Int32 range is -2147483648..2147483647, we've increased the - # minimum size by one as Cython was throwing a warning: - # "unary minus operator applied to unsigned type, result still - # unsigned". - if -2147483647 <= value <= 2147483647: + elif valueType == int or valueType == long: # In Py3 int and long types are the same type. + # Int32 range is -2147483648..2147483647 + if INT_MIN <= value <= INT_MAX: ret.get().SetInt(cefKey, int(value)) else: # Long values become strings. diff --git a/tools/cython_setup.py b/tools/cython_setup.py index 52482cba..5b3049db 100644 --- a/tools/cython_setup.py +++ b/tools/cython_setup.py @@ -470,6 +470,9 @@ def compile_time_constants(): # A way around Python 3.2 bug: UNAME_SYSNAME is not set contents += 'DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0] contents += 'DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major + contents += 'cdef extern from "limits.h":\n' + contents += ' cdef int INT_MIN\n' + contents += ' cdef int INT_MAX\n' fo.write(contents.encode("utf-8")) From 686d528b3eebbe5b84a770f5d266aea8dd185721 Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sun, 14 Feb 2021 17:21:13 +0100 Subject: [PATCH 07/27] Fix pyinstaller hook for pyinstaller >= 4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Brénainn Woodsend (https://github.com/bwoodsend) for the fix. See also https://github.com/cztomczak/cefpython/pull/600 . --- examples/pyinstaller/hook-cefpython3.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/pyinstaller/hook-cefpython3.py b/examples/pyinstaller/hook-cefpython3.py index 7522b7be..9160f67f 100644 --- a/examples/pyinstaller/hook-cefpython3.py +++ b/examples/pyinstaller/hook-cefpython3.py @@ -14,8 +14,13 @@ import sys import PyInstaller from PyInstaller.utils.hooks import is_module_satisfies, get_package_paths -from PyInstaller.compat import is_win, is_darwin, is_linux, is_py2 +from PyInstaller.compat import is_win, is_darwin, is_linux from PyInstaller import log as logging +try: + # PyInstaller >= 4.0 doesn't support Python 2.7 + from PyInstaller.compat import is_py2 +except ImportError: + is_py2 = None # Constants CEFPYTHON_MIN_VERSION = "57.0" From 8e36e82a21a95574fbc2cc329be4f2d5e82f6d00 Mon Sep 17 00:00:00 2001 From: Holger Badorreck <6099617+hoba87@users.noreply.github.com> Date: Sun, 14 Feb 2021 17:30:11 +0100 Subject: [PATCH 08/27] update kivy example (#573) * update old print syntax * remove pygtk, gtk dependencies * restore kivy pygtk dependency for linux, add platform dependent conditional statements * kivy example macos keyboard working * external pump message only for macos * Update kivy_.py Co-authored-by: Czarek Tomczak --- src/linux/binaries_64bit/kivy_.py | 46 ++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/linux/binaries_64bit/kivy_.py b/src/linux/binaries_64bit/kivy_.py index bdfb6d2c..49543bf9 100644 --- a/src/linux/binaries_64bit/kivy_.py +++ b/src/linux/binaries_64bit/kivy_.py @@ -8,11 +8,20 @@ from cefpython3 import cefpython as cef -import pygtk -import gtk import sys import os import time +if sys.platform == 'linux': + import pygtk + import gtk + pygtk.require('2.0') +elif sys.platform == 'darwin': + import gi + gi.require_version("Gtk", "3.0") + from gi.repository import Gtk +elif sys.platform == 'win32': + # no gtk needed on Windows + pass from kivy.app import App from kivy.uix.button import Button @@ -28,9 +37,6 @@ # Global variables g_switches = None -# PyGTK required -pygtk.require('2.0') - class BrowserLayout(BoxLayout): @@ -150,9 +156,6 @@ def start_cef(self): # Configure CEF settings = { - # This directories must be set on Linux - "locales_dir_path": cef.GetModuleDirectory()+"/locales", - "resources_dir_path": cef.GetModuleDirectory(), "browser_subprocess_path": "%s/%s" % ( cef.GetModuleDirectory(), "subprocess"), "windowless_rendering_enabled": True, @@ -161,7 +164,15 @@ def start_cef(self): "enabled": False, }, "external_message_pump": False, # See Issue #246 + "multi_threaded_message_loop": False, } + if sys.platform == 'linux': + # This directories must be set on Linux + settings["locales_dir_path"] = cef.GetModuleDirectory() + "/locales" + settings["resources_dir_path"] = cef.GetModuleDirectory() + if sys.platform == 'darwin': + settings["external_message_pump"] = True # Temporary fix for Issue #246 + switches = { # Tweaking OSR performance by setting the same Chromium flags # as in upstream cefclient (# Issue #240). @@ -190,18 +201,21 @@ def start_cef(self): # Start idle - CEF message loop work. Clock.schedule_once(self._message_loop_work, 0) + windowInfo = cef.WindowInfo() + # TODO: For printing to work in off-screen-rendering mode # it is enough to call gtk_init(). It is not required # to provide window handle when calling SetAsOffscreen(). # However it still needs to be tested whether providing # window handle is required for mouse context menu and # popup widgets to work. - gtkwin = gtk.Window() - gtkwin.realize() - # WindowInfo offscreen flag - windowInfo = cef.WindowInfo() - windowInfo.SetAsOffscreen(gtkwin.window.xid) + if sys.platform == 'linux': + gtkwin = gtk.Window() + gtkwin.realize() + windowInfo.SetAsOffscreen(gtkwin.window.xid) + elif sys.platform == 'darwin' or sys.platform == 'win32': + windowInfo.SetAsOffscreen(0) # Create Broswer and naviagte to empty page <= OnPaint won't get # called yet @@ -519,12 +533,12 @@ def get_windows_key_code(self, kivycode): def go_forward(self, *_): """Going to forward in browser history.""" - print "go forward" + print("go forward") self.browser.GoForward() def go_back(self, *_): """Going back in browser history.""" - print "go back" + print("go back") self.browser.GoBack() def reload(self, *_): @@ -864,7 +878,7 @@ def OnLoadingStateChange(self, is_loading, **_): def OnPaint(self, element_type, paint_buffer, **_): # print "OnPaint()" if element_type != cef.PET_VIEW: - print "Popups aren't implemented yet" + print("Popups aren't implemented yet") return # FPS meter ("fps" arg) From 55e63607afdce5d122f3d78884200a5e3f84938d Mon Sep 17 00:00:00 2001 From: gary Date: Sun, 14 Feb 2021 12:03:24 -0800 Subject: [PATCH 09/27] Add support for Python 3.8 and Upgrade Cython (#594) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/cztomczak/cefpython/issues/546 Had to include harfbuzz manually as newer Pango change this. See: https://github.com/eiskaltdcpp/eiskaltdcpp/issues/413 https://gitlab.gnome.org/GNOME/pango/-/issues/387 Also had to add `-Wno-deprecated-declarations` to get this to compile because of the following errors that didn't seem to be coming from this code directly: warning: ‘GTimeVal’ is deprecated: Use 'GDateTime' instead warning: ‘GTypeDebugFlags’ is deprecated --- README.md | 6 +++--- src/common/cefpython_public_api.h | 2 ++ tools/build.py | 2 +- tools/build_distrib.py | 2 +- tools/common.py | 2 ++ tools/installer/cefpython3.__init__.py | 3 +++ tools/installer/cefpython3.setup.py | 1 + tools/requirements.txt | 2 +- 8 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 546cd001..d4f4c493 100644 --- a/README.md +++ b/README.md @@ -210,9 +210,9 @@ support old operating systems then choose the v31 release. OS | Py2 | Py3 | 32bit | 64bit | Requirements --- | --- | --- | --- | --- | --- -Windows | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | Yes | Yes | Windows 7+ -Linux | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | Yes | Yes | Debian 8+, Ubuntu 14.04+,
Fedora 24+, openSUSE 13.3+ -Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ +Windows | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 | Yes | Yes | Windows 7+ +Linux | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 3.8 | Yes | Yes | Debian 8+, Ubuntu 14.04+,
Fedora 24+, openSUSE 13.3+ +Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 | No | Yes | MacOS 10.9+ These platforms are not supported yet: - ARM - see [Issue #267](../../issues/267) diff --git a/src/common/cefpython_public_api.h b/src/common/cefpython_public_api.h index 53ad62c6..8e4ff60b 100644 --- a/src/common/cefpython_public_api.h +++ b/src/common/cefpython_public_api.h @@ -46,6 +46,8 @@ #include "../../build/build_cefpython/cefpython_py36_fixed.h" #elif PY_MINOR_VERSION == 7 #include "../../build/build_cefpython/cefpython_py37_fixed.h" +#elif PY_MINOR_VERSION == 8 +#include "../../build/build_cefpython/cefpython_py38_fixed.h" #endif // PY_MINOR_VERSION #endif // PY_MAJOR_VERSION diff --git a/tools/build.py b/tools/build.py index 522a9b08..b3bc9920 100644 --- a/tools/build.py +++ b/tools/build.py @@ -293,7 +293,7 @@ def setup_environ(): print("[build.py] PYTHON_INCLUDE: {python_include}" .format(python_include=os.environ["PYTHON_INCLUDE"])) - os.environ["CEF_CCFLAGS"] = "-std=gnu++11 -DNDEBUG -Wall -Werror" + os.environ["CEF_CCFLAGS"] = "-std=gnu++11 -DNDEBUG -Wall -Werror -Wno-deprecated-declarations" if FAST_FLAG: os.environ["CEF_CCFLAGS"] += " -O0" else: diff --git a/tools/build_distrib.py b/tools/build_distrib.py index e0a5bde1..f452bc0d 100644 --- a/tools/build_distrib.py +++ b/tools/build_distrib.py @@ -80,7 +80,7 @@ ALLOW_PARTIAL = False # Python versions -SUPPORTED_PYTHON_VERSIONS = [(2, 7), (3, 4), (3, 5), (3, 6), (3, 7)] +SUPPORTED_PYTHON_VERSIONS = [(2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8)] # Python search paths. It will use first Python found for specific version. # Supports replacement of one environment variable in path eg.: %ENV_KEY%. diff --git a/tools/common.py b/tools/common.py index 113bcd9e..226fd391 100644 --- a/tools/common.py +++ b/tools/common.py @@ -473,6 +473,8 @@ def get_msvs_for_python(vs_prefix=False): return "VS2015" if vs_prefix else "2015" elif sys.version_info[:2] == (3, 7): return "VS2015" if vs_prefix else "2015" + elif sys.version_info[:2] == (3, 8): + return "VS2015" if vs_prefix else "2015" else: print("ERROR: This version of Python is not supported") sys.exit(1) diff --git a/tools/installer/cefpython3.__init__.py b/tools/installer/cefpython3.__init__.py index ef784f2c..5f779a54 100644 --- a/tools/installer/cefpython3.__init__.py +++ b/tools/installer/cefpython3.__init__.py @@ -64,5 +64,8 @@ elif sys.version_info[:2] == (3, 7): # noinspection PyUnresolvedReferences from . import cefpython_py37 as cefpython +elif sys.version_info[:2] == (3, 8): + # noinspection PyUnresolvedReferences + from . import cefpython_py38 as cefpython else: raise Exception("Python version not supported: " + sys.version) diff --git a/tools/installer/cefpython3.setup.py b/tools/installer/cefpython3.setup.py index 6814cbb7..2a926913 100644 --- a/tools/installer/cefpython3.setup.py +++ b/tools/installer/cefpython3.setup.py @@ -148,6 +148,7 @@ def main(): "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Topic :: Desktop Environment", "Topic :: Internet", "Topic :: Internet :: WWW/HTTP", diff --git a/tools/requirements.txt b/tools/requirements.txt index 81ebc0c5..4b083579 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -1,4 +1,4 @@ -Cython == 0.28.4 +Cython == 0.29.21 docopt >= 0.6.2 setuptools wheel From d6deaf8e2b87266d7b5fc4052fc05b5622056b17 Mon Sep 17 00:00:00 2001 From: cztomczak Date: Sun, 14 Feb 2021 23:44:38 +0100 Subject: [PATCH 10/27] Support Python 3.8 and Python 3.9 (Issues #546 and #593). --- README.md | 6 +++--- docs/Build-instructions.md | 8 +++++--- examples/screenshot.py | 2 +- src/common/cefpython_public_api.h | 2 ++ src/compile_time_constants.pxi | 3 +++ src/subprocess/main_message_loop/util_win.cpp | 4 ++-- src/subprocess/main_message_loop/util_win.h | 2 +- tools/build.py | 2 +- tools/build_distrib.py | 5 +++-- tools/common.py | 6 ++++++ tools/cython_setup.py | 7 +++---- tools/installer/cefpython3.__init__.py | 3 +++ tools/installer/cefpython3.setup.py | 1 + tools/make_installer.py | 8 +++++--- 14 files changed, 39 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d4f4c493..48a9af4a 100644 --- a/README.md +++ b/README.md @@ -210,9 +210,9 @@ support old operating systems then choose the v31 release. OS | Py2 | Py3 | 32bit | 64bit | Requirements --- | --- | --- | --- | --- | --- -Windows | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 | Yes | Yes | Windows 7+ -Linux | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 3.8 | Yes | Yes | Debian 8+, Ubuntu 14.04+,
Fedora 24+, openSUSE 13.3+ -Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 | No | Yes | MacOS 10.9+ +Windows | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 / 3.9 | Yes | Yes | Windows 7+ (Note that Python 3.9 supports Windows 8.1+) +Linux | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | Yes | Yes | Debian 8+, Ubuntu 14.04+,
Fedora 24+, openSUSE 13.3+ +Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ These platforms are not supported yet: - ARM - see [Issue #267](../../issues/267) diff --git a/docs/Build-instructions.md b/docs/Build-instructions.md index 5df63bec..9ca4d6e9 100644 --- a/docs/Build-instructions.md +++ b/docs/Build-instructions.md @@ -66,8 +66,9 @@ are named "cefpythonXX" where XX is Chromium version number. from [here](https://www.microsoft.com/en-us/download/details.aspx?id=44266) 5) For Python 2.7 and when using using "Visual C++ compiler for Python 2.7" - you have to install "Visual C++ 2008 Redistributable Package (x64)" - from [here](https://www.microsoft.com/en-us/download/details.aspx?id=15336) + you have to install "Visual C++ 2008 Redistributable Package" + from [here](https://www.microsoft.com/en-us/download/details.aspx?id=29) + and [here](https://www.microsoft.com/en-us/download/details.aspx?id=15336) 6) Clone cefpython, checkout for example "cefpython57" branch that includes Chromium v57, then create a build/ directory and enter it: @@ -164,7 +165,8 @@ requirements common for all platforms. * For Python 2.7 install "Microsoft Visual C++ Compiler for Python 2.7" from [here](https://www.microsoft.com/en-us/download/details.aspx?id=44266) * When using "Visual C++ compiler for Python 2.7" you have to install - "Microsoft Visual C++ 2008 Redistributable Package (x64)" from + "Microsoft Visual C++ 2008 Redistributable Package" from + [here](https://www.microsoft.com/en-us/download/details.aspx?id=29) and [here](https://www.microsoft.com/en-us/download/details.aspx?id=15336) * For Python 2.7 copy "cefpython/src/windows/py27/stdint.h" to "%LocalAppData%\Programs\Common\Microsoft\Visual C++ for Python\9.0\VC\include\" diff --git a/examples/screenshot.py b/examples/screenshot.py index d6dc661c..976ba538 100644 --- a/examples/screenshot.py +++ b/examples/screenshot.py @@ -42,7 +42,7 @@ import sys try: - from PIL import Image, PILLOW_VERSION + from PIL import Image, __version__ as PILLOW_VERSION except ImportError: print("[screenshot.py] Error: PIL module not available. To install" " type: pip install Pillow") diff --git a/src/common/cefpython_public_api.h b/src/common/cefpython_public_api.h index 8e4ff60b..c796388e 100644 --- a/src/common/cefpython_public_api.h +++ b/src/common/cefpython_public_api.h @@ -48,6 +48,8 @@ #include "../../build/build_cefpython/cefpython_py37_fixed.h" #elif PY_MINOR_VERSION == 8 #include "../../build/build_cefpython/cefpython_py38_fixed.h" +#elif PY_MINOR_VERSION == 9 +#include "../../build/build_cefpython/cefpython_py39_fixed.h" #endif // PY_MINOR_VERSION #endif // PY_MAJOR_VERSION diff --git a/src/compile_time_constants.pxi b/src/compile_time_constants.pxi index 609470c1..bf130d6e 100644 --- a/src/compile_time_constants.pxi +++ b/src/compile_time_constants.pxi @@ -5,3 +5,6 @@ DEF UNAME_SYSNAME = "Windows" DEF PY_MAJOR_VERSION = 3 +cdef extern from "limits.h": + cdef int INT_MIN + cdef int INT_MAX diff --git a/src/subprocess/main_message_loop/util_win.cpp b/src/subprocess/main_message_loop/util_win.cpp index bc1f0965..834850e3 100644 --- a/src/subprocess/main_message_loop/util_win.cpp +++ b/src/subprocess/main_message_loop/util_win.cpp @@ -136,8 +136,8 @@ int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam) { return modifiers; } -bool IsKeyDown(WPARAM wparam) { - return (GetKeyState(wparam) & 0x8000) != 0; +bool IsKeyDown(int keycode) { + return (GetKeyState(keycode) & 0x8000) != 0; } float GetDeviceScaleFactor() { diff --git a/src/subprocess/main_message_loop/util_win.h b/src/subprocess/main_message_loop/util_win.h index 39870204..a716d938 100644 --- a/src/subprocess/main_message_loop/util_win.h +++ b/src/subprocess/main_message_loop/util_win.h @@ -31,7 +31,7 @@ WNDPROC SetWndProcPtr(HWND hWnd, WNDPROC wndProc); int GetCefMouseModifiers(WPARAM wparam); int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam); -bool IsKeyDown(WPARAM wparam); +bool IsKeyDown(int keycode); // Returns the device scale factor. For example, 200% display scaling will // return 2.0. diff --git a/tools/build.py b/tools/build.py index b3bc9920..f3960283 100644 --- a/tools/build.py +++ b/tools/build.py @@ -809,7 +809,7 @@ def build_cefpython_module(): args = list() args.append("\"{python}\"".format(python=sys.executable)) args.append(os.path.join(TOOLS_DIR, os.path.basename(__file__))) - assert __file__ in sys.argv[0] + assert os.path.basename(__file__) in sys.argv[0] args.extend(SYS_ARGV_ORIGINAL[1:]) command = " ".join(args) print("[build.py] Running command: %s" % command) diff --git a/tools/build_distrib.py b/tools/build_distrib.py index f452bc0d..01ae66da 100644 --- a/tools/build_distrib.py +++ b/tools/build_distrib.py @@ -80,13 +80,14 @@ ALLOW_PARTIAL = False # Python versions -SUPPORTED_PYTHON_VERSIONS = [(2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8)] +SUPPORTED_PYTHON_VERSIONS = [(2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9)] # Python search paths. It will use first Python found for specific version. # Supports replacement of one environment variable in path eg.: %ENV_KEY%. PYTHON_SEARCH_PATHS = dict( WINDOWS=[ "C:\\Python*\\", + "C:\\Pythons\\Python*\\", "%LOCALAPPDATA%\\Programs\\Python\\Python*\\", "C:\\Program Files\\Python*\\", "C:\\Program Files (x86)\\Python*\\", @@ -614,7 +615,7 @@ def check_cpp_extension_dependencies_issue359(setup_dir, all_pythons): return checked_any = False for python in all_pythons: - if python["version2"] in ((3, 5), (3, 6), (3, 7)): + if python["version2"] in ((3, 5), (3, 6), (3, 7), (3, 8), (3, 9)): checked_any = True if not os.path.exists(os.path.join(setup_dir, "cefpython3", "msvcp140.dll")): diff --git a/tools/common.py b/tools/common.py index 226fd391..303ccb85 100644 --- a/tools/common.py +++ b/tools/common.py @@ -219,15 +219,19 @@ VS_PLATFORM_ARG = "x86" if ARCH32 else "amd64" +# Python 3.5 / 3.6 / 3.7 / 3.8 / 3.9 VS2015_VCVARS = ("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0" "\\VC\\vcvarsall.bat") +# Required for building old CEF branches < 2704 VS2013_VCVARS = ("C:\\Program Files (x86)\\Microsoft Visual Studio 12.0" "\\VC\\vcvarsall.bat") +# Python 3.4 VS2010_VCVARS = ("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0" "\\VC\\vcvarsall.bat") +# Python 2.7 VS2008_VCVARS = ("C:\\Program Files (x86)\\Microsoft Visual Studio 9.0" "\\VC\\vcvarsall.bat") @@ -475,6 +479,8 @@ def get_msvs_for_python(vs_prefix=False): return "VS2015" if vs_prefix else "2015" elif sys.version_info[:2] == (3, 8): return "VS2015" if vs_prefix else "2015" + elif sys.version_info[:2] == (3, 9): + return "VS2015" if vs_prefix else "2015" else: print("ERROR: This version of Python is not supported") sys.exit(1) diff --git a/tools/cython_setup.py b/tools/cython_setup.py index 5b3049db..436bcb2c 100644 --- a/tools/cython_setup.py +++ b/tools/cython_setup.py @@ -147,17 +147,15 @@ def get_winsdk_lib(): if WINDOWS: if ARCH32: winsdk_libs = [ + # Windows 7 SDKs. r"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Lib", r"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\Lib", - # Visual Studio 2008 installation - r"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\Lib", ] elif ARCH64: winsdk_libs = [ + # Windows 7 SDKs. r"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Lib\\x64", r"C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\Lib\\x64", - # Visual Studio 2008 installation - r"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\Lib\\x64", ] else: raise Exception("Unknown architecture") @@ -433,6 +431,7 @@ def get_ext_modules(options): # > Unknown Extension options: 'cython_directives' warnings.warn(msg) cython_directives={ # Any conversion to unicode must be explicit using .decode(). + "language_level": 2, # Yes, Py2 for all python versions. "c_string_type": "bytes", "c_string_encoding": "utf-8", "profile": ENABLE_PROFILING, diff --git a/tools/installer/cefpython3.__init__.py b/tools/installer/cefpython3.__init__.py index 5f779a54..624a26e7 100644 --- a/tools/installer/cefpython3.__init__.py +++ b/tools/installer/cefpython3.__init__.py @@ -67,5 +67,8 @@ elif sys.version_info[:2] == (3, 8): # noinspection PyUnresolvedReferences from . import cefpython_py38 as cefpython +elif sys.version_info[:2] == (3, 9): + # noinspection PyUnresolvedReferences + from . import cefpython_py39 as cefpython else: raise Exception("Python version not supported: " + sys.version) diff --git a/tools/installer/cefpython3.setup.py b/tools/installer/cefpython3.setup.py index 2a926913..d14ee2ce 100644 --- a/tools/installer/cefpython3.setup.py +++ b/tools/installer/cefpython3.setup.py @@ -149,6 +149,7 @@ def main(): "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Desktop Environment", "Topic :: Internet", "Topic :: Internet :: WWW/HTTP", diff --git a/tools/make_installer.py b/tools/make_installer.py index bc3b5cef..012e6657 100644 --- a/tools/make_installer.py +++ b/tools/make_installer.py @@ -338,7 +338,7 @@ def create_empty_log_file(log_file): def copy_cpp_extension_dependencies_issue359(pkg_dir): """CEF Python module is written in Cython and is a Python C++ - extension and depends on msvcpXX.dll. For Python 3.5 / 3.6 / 3.7 + extension and depends on msvcpXX.dll. For Python 3.5 / 3.6 / 3.7 / 3.8 / 3.9 msvcp140.dll is required. See Issue #359. For Python 2.7 msvcp90.dll is required. Etc. These dependencies are not included with Python binaries from Python.org.""" @@ -365,10 +365,12 @@ def copy_cpp_extension_dependencies_issue359(pkg_dir): # in the package. Thus if included, msvcpxx.dll dependency is # required as well. - # Python 3.5 / 3.6 / 3.7 + # Python 3.5 / 3.6 / 3.7 / 3.8 / 3.9 if os.path.exists(os.path.join(pkg_dir, "cefpython_py35.pyd")) \ or os.path.exists(os.path.join(pkg_dir, "cefpython_py36.pyd")) \ - or os.path.exists(os.path.join(pkg_dir, "cefpython_py37.pyd")): + or os.path.exists(os.path.join(pkg_dir, "cefpython_py37.pyd")) \ + or os.path.exists(os.path.join(pkg_dir, "cefpython_py38.pyd")) \ + or os.path.exists(os.path.join(pkg_dir, "cefpython_py39.pyd")): search_paths = [ # This is where Microsoft Visual C++ 2015 Update 3 installs # (14.00.24212). From 92aa6236268620105be0b3d5ce60412a8b5dbf5b Mon Sep 17 00:00:00 2001 From: cztomczak Date: Mon, 15 Feb 2021 19:01:48 +0100 Subject: [PATCH 11/27] Fix Python 3 error in build_distrib.py script (#546). --- tools/build_distrib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_distrib.py b/tools/build_distrib.py index 01ae66da..61560743 100644 --- a/tools/build_distrib.py +++ b/tools/build_distrib.py @@ -379,7 +379,7 @@ def uninstall_cefpython3_packages(pythons): .format(python=python["executable"])) try: output = subprocess.check_output(command, shell=True) - except subprocess.CalledProcessError, exc: + except subprocess.CalledProcessError as exc: # pip show returns error code when package is not installed output = exc.output if not len(output.strip()): From 3beaaf5dc39c80eea54a9bba6c4c35965764d628 Mon Sep 17 00:00:00 2001 From: cztomczak Date: Mon, 15 Feb 2021 19:31:02 +0100 Subject: [PATCH 12/27] Fix build_distrib.py on Python 3 (Issue #546). --- tools/build_distrib.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/build_distrib.py b/tools/build_distrib.py index 61560743..7adb535b 100644 --- a/tools/build_distrib.py +++ b/tools/build_distrib.py @@ -86,7 +86,7 @@ # Supports replacement of one environment variable in path eg.: %ENV_KEY%. PYTHON_SEARCH_PATHS = dict( WINDOWS=[ - "C:\\Python*\\", + "C:\\Python??*\\", "C:\\Pythons\\Python*\\", "%LOCALAPPDATA%\\Programs\\Python\\Python*\\", "C:\\Program Files\\Python*\\", @@ -277,6 +277,8 @@ def search_for_pythons(search_arch): version_str = subprocess.check_output([python, "-c", version_code]) version_str = version_str.strip() + if sys.version_info >= (3, 0): + version_str = version_str.decode("utf-8") match = re.search("^\((\d+), (\d+), (\d+)\)$", version_str) assert match, version_str major = match.group(1) @@ -288,6 +290,8 @@ def search_for_pythons(search_arch): "print(str(platform.architecture()[0]));") arch = subprocess.check_output([python, "-c", arch_code]) arch = arch.strip() + if sys.version_info >= (3, 0): + arch = arch.decode("utf-8") if version_tuple2 in SUPPORTED_PYTHON_VERSIONS \ and arch == search_arch: name = ("Python {major}.{minor}.{micro} {arch}" From 06d3b8c8e8164ea1a51caf00591b7eaedcbfc5ac Mon Sep 17 00:00:00 2001 From: cztomczak Date: Mon, 15 Feb 2021 23:26:45 +0100 Subject: [PATCH 13/27] Fix build_distrib.py script for Python 2.7 and Python 3.4 (latest pip versions are broken with these old Pythons). Fix screenshot.py example sometimes failing. When compiling for Python 3.4 you can encounter the the missing "ammintrin.h" header file error. Just copy it from the VS 2019 include/ directory. For Pythons 3.5 / 3.6 / 3.7 / 3.8 / 3.9 you can use the same VC++ 14.2 (VS 2019) compiler which is binary compatible with VC++ 14.1 (VS 2017) and VC++ 14.0 (VS 2015). Currently the subprocess.exe executable built by Python 3.4 (VC++ 10.0 compiler) gives the least amount of false-positives by AVs on virustotal.com . For comparison: Py34 (1/69), Py27 (2/69), Py39 (5/69). Results differ for 32bit and 64bit binaries. --- examples/screenshot.py | 9 ++++++--- tools/build_distrib.py | 28 ++++++++++++++++------------ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/examples/screenshot.py b/examples/screenshot.py index 976ba538..5ca8d491 100644 --- a/examples/screenshot.py +++ b/examples/screenshot.py @@ -158,6 +158,8 @@ def save_screenshot(browser): "raw", "RGBA", 0, 1) image.save(SCREENSHOT_PATH, "PNG") print("[screenshot.py] Saved image: {path}".format(path=SCREENSHOT_PATH)) + # See comments in exit_app() why PostTask must be used + cef.PostTask(cef.TID_UI, exit_app, browser) def open_with_default_application(path): @@ -188,9 +190,10 @@ def OnLoadingStateChange(self, browser, is_loading, **_): # Loading is complete sys.stdout.write(os.linesep) print("[screenshot.py] Web page loading is complete") - save_screenshot(browser) - # See comments in exit_app() why PostTask must be used - cef.PostTask(cef.TID_UI, exit_app, browser) + print("[screenshot.py] Will save screenshot in 2 seconds") + # Give up to 2 seconds for the OnPaint call. Most of the time + # it is already called, but sometimes it may be called later. + cef.PostDelayedTask(cef.TID_UI, 2000, save_screenshot, browser) def OnLoadError(self, browser, frame, error_code, failed_url, **_): """Called when the resource load for a navigation fails diff --git a/tools/build_distrib.py b/tools/build_distrib.py index 7adb535b..051914f5 100644 --- a/tools/build_distrib.py +++ b/tools/build_distrib.py @@ -353,8 +353,14 @@ def install_upgrade_requirements(pythons): " for: {name}".format(name=python["name"])) # Upgrade pip - command = ("\"{python}\" -m pip install --upgrade pip" - .format(python=python["executable"])) + pip_version = "pip" + # Old Python versions require specific versions of pip, latest versions are broken with these. + if python["version2"] == (2, 7): + pip_version = "pip==20.3.4" + elif python["version2"] == (3, 4): + pip_version = "pip==19.1.1" + command = ("\"{python}\" -m pip install --upgrade {pip_version}" + .format(python=python["executable"], pip_version=pip_version)) command = sudo_command(command, python=python["executable"]) pcode = subprocess.call(command, shell=True) if pcode != 0: @@ -522,39 +528,37 @@ def build_cefpython_modules(pythons, arch): def backup_subprocess_executable_issue342(python): - """Use subprocess executable build by Python 2.7 to avoid - false-positives by AVs when building subprocess with Python 3. - Windows-only issue.""" + """Use subprocess executable built by Python 3.4 to have the least amount of + false-positives by AVs. Windows-only issue.""" if not WINDOWS: return if python["version2"] == (2, 7): print("[build_distrib.py] Backup subprocess executable built" - " with Python 2.7 (Issue #342)") + " with Python 3.4 (Issue #342)") cefpython_binary_basename = get_cefpython_binary_basename( get_os_postfix2_for_arch(python["arch"])) cefpython_binary = os.path.join(BUILD_DIR, cefpython_binary_basename) assert os.path.isdir(cefpython_binary) src = os.path.join(cefpython_binary, "subprocess.exe") dst = os.path.join(BUILD_CEFPYTHON, - "subprocess_py27_{arch}_issue342.exe" + "subprocess_py34_{arch}_issue342.exe" .format(arch=python["arch"])) shutil.copy(src, dst) def restore_subprocess_executable_issue342(arch): - """Use subprocess executable build by Python 2.7 to avoid - false-positives by AVs when building subprocess with Python 3. - Windows-only issue.""" + """Use subprocess executable built by Python 3.4 to have the least amount of + false-positives by AVs. Windows-only issue.""" if not WINDOWS: return print("[build_distrib.py] Restore subprocess executable built" - " with Python 2.7 (Issue #342)") + " with Python 3.4 (Issue #342)") cefpython_binary_basename = get_cefpython_binary_basename( get_os_postfix2_for_arch(arch)) cefpython_binary = os.path.join(BUILD_DIR, cefpython_binary_basename) assert os.path.isdir(cefpython_binary) src = os.path.join(BUILD_CEFPYTHON, - "subprocess_py27_{arch}_issue342.exe" + "subprocess_py34_{arch}_issue342.exe" .format(arch=arch)) assert os.path.isfile(src) dst = os.path.join(cefpython_binary, "subprocess.exe") From 0e2503c4675d683d2b853267ee0183e4e7fb5726 Mon Sep 17 00:00:00 2001 From: cztomczak Date: Tue, 16 Feb 2021 19:18:02 +0100 Subject: [PATCH 14/27] Add JS bindings long integer test. Add comments on DPI awareness. --- examples/hello_world.py | 7 +++++++ unittests/main_test.py | 26 ++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/examples/hello_world.py b/examples/hello_world.py index 478c7060..789f4666 100644 --- a/examples/hello_world.py +++ b/examples/hello_world.py @@ -1,5 +1,12 @@ # Hello world example. Doesn't depend on any third party GUI framework. # Tested with CEF Python v57.0+. +# +# ==== High DPI support on Windows ==== +# To enable DPI awareness on Windows you have to either embed DPI aware manifest +# in your executable created with pyinstaller or change python.exe properties manually: +# Compatibility > High DPI scaling override > Application. +# Setting DPI awareness programmatically via a call to cef.DpiAware.EnableHighDpiSupport +# is problematic in Python, may not work and can cause display glitches. from cefpython3 import cefpython as cef import platform diff --git a/unittests/main_test.py b/unittests/main_test.py index 99397da8..ce71af20 100644 --- a/unittests/main_test.py +++ b/unittests/main_test.py @@ -58,17 +58,18 @@ print("test_function() ok"); // Test binding property: test_property1 - if (test_property1 == "Test binding property to the 'window' object") { + if (test_property1 === "Test binding property to the 'window' object") { print("test_property_1 ok"); } else { throw new Error("test_property1 contains invalid string"); } // Test binding property: test_property2 - if (JSON.stringify(test_property2) == '{"key1":"Test binding property'+ - ' to the \\'window\\' object","key2":["Inside list",1,2]}') { + if (JSON.stringify(test_property2) === '{"key1":"Test binding property'+ + ' to the \\'window\\' object","key2":["Inside list",2147483647,"2147483648"]}') { print("test_property2 ok"); } else { + print("test_property2 invalid value: " + JSON.stringify(test_property2)); throw new Error("test_property2 contains invalid value"); } @@ -81,7 +82,7 @@ print("[TIMER] Call Python function and then js callback that was"+ " passed (Issue #277 test)"); external.test_callbacks(function(msg_from_python, py_callback){ - if (msg_from_python == "String sent from Python") { + if (msg_from_python === "String sent from Python") { print("test_callbacks() ok"); var execution_time = new Date().getTime() - start_time; print("[TIMER]: Elapsed = "+String(execution_time)+" ms"); @@ -163,15 +164,23 @@ def test_main(self): cef.LoadCrlSetsFile(crlset) subtest_message("cef.LoadCrlSetsFile ok") - # High DPI on Windows + # High DPI on Windows. + # Setting DPI awareness from Python is usually too late and should be done + # via manifest file. Alternatively change python.exe properties > Compatibility + # > High DPI scaling override > Application. + # Using cef.DpiAware.EnableHighDpiSupport is problematic, it can cause + # display glitches. if WINDOWS: self.assertIsInstance(cef.DpiAware.GetSystemDpi(), tuple) window_size = cef.DpiAware.CalculateWindowSize(800, 600) self.assertIsInstance(window_size, tuple) self.assertGreater(window_size[0], 0) self.assertGreater(cef.DpiAware.Scale((800, 600))[0], 0) - cef.DpiAware.EnableHighDpiSupport() - self.assertTrue(cef.DpiAware.IsProcessDpiAware()) + + # OFF - see comments above. + # cef.DpiAware.EnableHighDpiSupport() + # self.assertTrue(cef.DpiAware.IsProcessDpiAware()) + # Make some calls again after DPI Aware was set self.assertIsInstance(cef.DpiAware.GetSystemDpi(), tuple) self.assertGreater(cef.DpiAware.Scale([800, 600])[0], 0) @@ -374,9 +383,10 @@ def __init__(self, test_case): self.test_case = test_case # Test binding properties to the 'window' object. + # 2147483648 is out of INT_MAX limit and will be sent to JS as string value. self.test_property1 = "Test binding property to the 'window' object" self.test_property2 = {"key1": self.test_property1, - "key2": ["Inside list", 1, 2]} + "key2": ["Inside list", 2147483647, 2147483648]} # Asserts for True/False will be checked just before shutdown self.test_for_True = True # Test whether asserts are working correctly From d2c72528addad8ef41a2a460946f32fe425ed183 Mon Sep 17 00:00:00 2001 From: cztomczak Date: Tue, 16 Feb 2021 19:31:32 +0100 Subject: [PATCH 15/27] Update the sponsors sections in README. --- README.md | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 48a9af4a..e9175971 100644 --- a/README.md +++ b/README.md @@ -55,30 +55,29 @@ PyGame, PyOpenGL, PyWin32, PySide and PySDL2.

- - + +

-Many Thanks to Lampix for sponsoring the -[v66 release](../../releases/tag/v66.0). Lampix is the first hardware -and software solution that turns any surface into a smart, augmented reality -or interactive surface. Please visit their website: -Lampix.com +Thank you to Fivestars for sponsoring the [v66.1 release](../../releases/tag/v66.1) +with Python 3.8 / 3.9 support. Fivestars helps local communities thrive by empowering +small businesses with cutting edge marketing technology. Please visit their website: +Fivestars.com

- - + +

-Many thanks to Fivestars for sponsoring the -[v49 legacy release](../../releases/tag/v49.0). Fivestars helps local -communities thrive by empowering small -businesses with cutting edge marketing technology. Please visit their website: -Fivestars.com +Thank you to Lampix for sponsoring the +[v66 release](../../releases/tag/v66.0). Lampix is the first hardware +and software solution that turns any surface into a smart, augmented reality +or interactive surface. Please visit their website: +Lampix.com @@ -274,6 +273,8 @@ priority. ### Thanks to all +* [2021] Thank you to [Fivestars](https://www.fivestars.com/) for sponsoring + the v66.1 release with Python 3.8 / 3.9 support * [2018] Thanks to [Fivestars](https://www.fivestars.com/) for sponsoring the v49 release for legacy systems (WinXP/Vista) * [2018] Many thanks to [Lampix](https://lampix.com/) for sponsoring the v66 From 431b9956db660d5552c31fb4a3a891f619ed84a8 Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Tue, 13 Apr 2021 10:42:46 +0200 Subject: [PATCH 16/27] Fix Kivy example on Windows (#613). --- src/linux/binaries_64bit/kivy_.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/linux/binaries_64bit/kivy_.py b/src/linux/binaries_64bit/kivy_.py index 49543bf9..a9a1590b 100644 --- a/src/linux/binaries_64bit/kivy_.py +++ b/src/linux/binaries_64bit/kivy_.py @@ -1,7 +1,5 @@ -# An example of embedding CEF browser in the Kivy framework. -# The browser is embedded using off-screen rendering mode. - -# Tested using Kivy 1.7.2 stable, only on Linux. +# An example of embedding CEF browser with the Kivy framework +# by using off-screen rendering mode. # In this example kivy-lang is used to declare the layout which # contains two buttons (back, forward) and the browser view. @@ -44,7 +42,7 @@ def __init__(self, **kwargs): super(BrowserLayout, self).__init__(**kwargs) self.orientation = "vertical" - self.browser_widget = CefBrowser(id="browser") + self.browser_widget = CefBrowser() layout = BoxLayout() layout.size_hint_y = None From 80e6f3c9828fce40b103a4f51b8bc29d64c54b9c Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Wed, 21 Apr 2021 13:50:04 +0200 Subject: [PATCH 17/27] Fix link --- examples/README-examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README-examples.md b/examples/README-examples.md index ea5871c8..ec2f9bcd 100644 --- a/examples/README-examples.md +++ b/examples/README-examples.md @@ -107,7 +107,7 @@ yet ported to latest CEF. Some of them are externally maintained. for reading/modifying web requests: see the [wxpython-response.py](https://github.com/cztomczak/cefpython/blob/cefpython31/cefpython/cef3/linux/binaries_64bit/wxpython-response.py) example in the cefpython31 branch. - Example of using Python network library (urllib3/openssl) instead of Chromium's - network library - see [gist by Massimiliano Dal Cero](https://gist.github.com/yattamax/0252a3c5dc54a2f81650d5c0eafabf99) + network library - see [gist by Massimiliano Dal Cero](https://gist.github.com/cztomczak/83b77cbdda03ccef81e22e8bd36a51f6) - Example of passing exceptions from Python to Javascript and using await syntax to receive values from python return values - see [Managed python calls example by Elliot Woods](https://github.com/elliotwoods/cefpython-tests/tree/0180b22eac10a1bde08820ca192fdc30eb93f00d/6.%20Managed%20python%20calls) ## More examples to come From 5679f28cec18a57a56e298da2927aac8d8f83ad6 Mon Sep 17 00:00:00 2001 From: relyx <12107287+Reskayoi@users.noreply.github.com> Date: Fri, 14 May 2021 17:18:03 +0800 Subject: [PATCH 18/27] fix OnDownloadData decoding bug (#621) --- api/WebRequestClient.md | 2 +- src/web_request.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/WebRequestClient.md b/api/WebRequestClient.md index d8431cec..0c75a668 100644 --- a/api/WebRequestClient.md +++ b/api/WebRequestClient.md @@ -65,7 +65,7 @@ response (or -1 if not determined). | Parameter | Type | | --- | --- | | web_request | [WebRequest](WebRequest.md) | -| data | string | +| data | bytes | | __Return__ | void | Called when some part of the response is read. |data| contains the current diff --git a/src/web_request.pyx b/src/web_request.pyx index 9891dade..8e51fca1 100644 --- a/src/web_request.pyx +++ b/src/web_request.pyx @@ -176,7 +176,7 @@ cdef public void WebRequestClient_OnDownloadData( if userCallback: userCallback( web_request=webRequest, - data=VoidPtrToString(data, dataLength)) + data=VoidPtrToBytes(data, dataLength)) except: (exc_type, exc_value, exc_trace) = sys.exc_info() sys.excepthook(exc_type, exc_value, exc_trace) From b070673ba96572f49354b5507822528430525099 Mon Sep 17 00:00:00 2001 From: jonastieppo Date: Thu, 19 Dec 2024 14:41:39 -0300 Subject: [PATCH 19/27] Update README.md (#675) Just updating to the latest version (really minor change). --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9175971..f9a76a57 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ also download packages for offline installation available on the [GitHub Releases](../../releases) pages. Command to install with pip: ``` -pip install cefpython3==66.0 +pip install cefpython3==66.1 ``` From 05586d5bd92b9b98f0d96f9d069f8c5b10223e9b Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:06:33 +0100 Subject: [PATCH 20/27] Update README.md --- README.md | 311 +++++++++++++----------------------------------------- 1 file changed, 71 insertions(+), 240 deletions(-) diff --git a/README.md b/README.md index f9a76a57..80bda463 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,12 @@ Table of contents: * [Introduction](#introduction) -* [Latest releases sponsored by](#latest-releases-sponsored-by) - * [Thanks to all sponsors](#thanks-to-all-sponsors) * [Install](#install) -* [Tutorial](#tutorial) * [Examples](#examples) * [Support](#support) -* [Releases](#releases) - * [Next release](#next-release) - * [Latest release](#latest-release) - * [v49 release (WinXP/Vista)](#v49-release-winxpvista) - * [v31 release (old systems)](#v31-release-old-systems) * [Support development](#support-development) - * [Thanks to all](#thanks-to-all) -* [Seeking new sponsors](#seeking-new-sponsors) -* [Other READMEs](#other-readmes) -* [Quick links](#quick-links) +* [Seeking sponsors](#seeking-sponsors) +* [API](#api) ## Introduction @@ -49,39 +39,82 @@ frameworks such as PyQt, wxPython, PyGTK, PyGObject, Tkinter, Kivy, Panda3D, PyGame, PyOpenGL, PyWin32, PySide and PySDL2. -## Latest releases sponsored by +## Install - -
+You can install [pypi/cefpython3](https://pypi.python.org/pypi/cefpython3) +package using pip tool. On Linux pip 8.1+ is required. You can +also download packages for offline installation available on the +[GitHub Releases](../../releases) pages. Command to install with pip: -

- - - -

+``` +pip install cefpython3==66.1 +``` -Thank you to Fivestars for sponsoring the [v66.1 release](../../releases/tag/v66.1) -with Python 3.8 / 3.9 support. Fivestars helps local communities thrive by empowering -small businesses with cutting edge marketing technology. Please visit their website: -Fivestars.com +Below is a table with supported platforms, python versions and architectures. -
+OS | Py2 | Py3 | 32bit | 64bit | Requirements +--- | --- | --- | --- | --- | --- +Windows | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 / 3.9 | Yes | Yes | Windows 7+ (Note that Python 3.9 supports Windows 8.1+) +Linux | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | Yes | Yes | Debian 8+, Ubuntu 14.04+,
Fedora 24+, openSUSE 13.3+ +Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ -

- - - -

-Thank you to Lampix for sponsoring the -[v66 release](../../releases/tag/v66.0). Lampix is the first hardware -and software solution that turns any surface into a smart, augmented reality -or interactive surface. Please visit their website: -Lampix.com +## Examples + +- [Tutorial](docs/Tutorial.md) +- [All examples](examples/README-examples.md). +- [Snippets](examples/snippets/README-snippets.md). +- [PyInstaller packager](examples/pyinstaller/README-pyinstaller.md). -
-### Thanks to all sponsors +## Support + +- Ask questions and report problems on the + [Forum](https://groups.google.com/group/cefpython) +- Supported examples are listed in the + [README-examples.md](examples/README-examples.md) file +- Documentation is in the [docs/](docs) directory: + - [Build instructions](docs/Build-instructions.md) + - [Contributing code](docs/Contributing-code.md) + - [Knowledge Base](docs/Knowledge-Base.md) + - [Migration guide](docs/Migration-guide.md) + - [Tutorial](docs/Tutorial.md) +- API reference is in the [api/](api) directory: + - [API categories](api/API-categories.md#api-categories) + - [API index](api/API-index.md#api-index) +- Additional documentation is available in + [Issues labelled Knowledge Base](../../issues?q=is%3Aissue+is%3Aopen+label%3A%22Knowledge+Base%22) +- To search documentation use GitHub "This repository" search + at the top. To narrow results to documentation only select + "Markdown" in the right pane. +- You can vote on issues in the tracker to let us know which issues are + important to you. To do that add a +1 thumb up reaction to the first post + in the issue. See + [Most popular issues](../../issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) + sorted by reactions. + + +## Support development + +If you would like to support general CEF Python development efforts +by making a donation then please click the Paypal Donate button below. + + + +

+ + +## Seeking sponsors + +CEF Python is seeking companies to sponsor development of this project. Most important +thing would be to have continuous monthly releases with updates to latest Chromium. There is +also lots of cool features and new settings that would be nice to implement. We have not yet +exposed all of upstream CEF APIs. If your company would like to sponsor CEF Python development efforts +then please contact [Czarek](https://www.linkedin.com/in/czarektomczak/). There are no active sponsors +at this moment. + + +### Previous sponsors @@ -139,209 +172,7 @@ or interactive surface. Please visit their website:
-## Install - -You can install [pypi/cefpython3](https://pypi.python.org/pypi/cefpython3) -package using pip tool. On Linux pip 8.1+ is required. You can -also download packages for offline installation available on the -[GitHub Releases](../../releases) pages. Command to install with pip: - -``` -pip install cefpython3==66.1 -``` - - -## Tutorial - -See the [Tutorial.md](docs/Tutorial.md) document. - - -## Examples - -See the [README-examples.md](examples/README-examples.md) and -[README-snippets.md](examples/snippets/README-snippets.md) documents. - - -## Support - -- Ask questions and report problems on the - [Forum](https://groups.google.com/group/cefpython) -- Supported examples are listed in the - [README-examples.md](examples/README-examples.md) file -- Documentation is in the [docs/](docs) directory: - - [Build instructions](docs/Build-instructions.md) - - [Contributing code](docs/Contributing-code.md) - - [Knowledge Base](docs/Knowledge-Base.md) - - [Migration guide](docs/Migration-guide.md) - - [Tutorial](docs/Tutorial.md) -- API reference is in the [api/](api) directory: - - [API categories](api/API-categories.md#api-categories) - - [API index](api/API-index.md#api-index) -- Additional documentation is available in - [Issues labelled Knowledge Base](../../issues?q=is%3Aissue+is%3Aopen+label%3A%22Knowledge+Base%22) -- To search documentation use GitHub "This repository" search - at the top. To narrow results to documentation only select - "Markdown" in the right pane. -- You can vote on issues in the tracker to let us know which issues are - important to you. To do that add a +1 thumb up reaction to the first post - in the issue. See - [Most popular issues](../../issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) - sorted by reactions. - - -## Releases - -Information on planned new and current releases, supported platforms, -python versions, architectures and requirements. If you want to -support old operating systems then choose the v31 release. - -### Next release - -- To see planned new features or bugs to be fixed in the near future in one of - next releases, see the - [next release](../../issues?q=is%3Aissue+is%3Aopen+label%3A%22next+release%22) - label in the tracker -- To see planned new features or bugs to be fixed in further future, see the - [next release 2](../../issues?q=is%3Aissue+is%3Aopen+label%3A%22next+release+2%22) - label in the tracker - -### Latest release - -OS | Py2 | Py3 | 32bit | 64bit | Requirements ---- | --- | --- | --- | --- | --- -Windows | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 / 3.8 / 3.9 | Yes | Yes | Windows 7+ (Note that Python 3.9 supports Windows 8.1+) -Linux | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | Yes | Yes | Debian 8+, Ubuntu 14.04+,
Fedora 24+, openSUSE 13.3+ -Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ - -These platforms are not supported yet: -- ARM - see [Issue #267](../../issues/267) -- Android - see [Issue #307](../../issues/307) - - -### v49 release (WinXP/Vista) - -OS | Py2 | Py3 | 32bit | 64bit | Requirements ---- | --- | --- | --- | --- | --- -Windows | 2.7 | 3.4 | Yes | Yes | Windows XP+ - -- Install with command: `pip --no-cache-dir install cefpython3==49.0`. - - Please note that if you were previously installing cefpython3 - package it is required to use the `--no-cache-dir` flag, - otherwise pip will end up with error message - `No matching distribution found for cefpython3==49.0`. - This happens because 49.0 release occured after 57.0 and 66.0 - releases. -- Downloads are available on GitHub Releases tagged - [v49.0](../../releases/tag/v49.0). -- See [Migration guide](docs/Migration-guide.md) document for changes - in this release -- Documentation is available in the [docs/](../../tree/cefpython49-winxp/docs) - directory in the `cefpython49-winxp` branch -- API reference is available in the [api/](../../tree/cefpython49-winxp/api) - directory in the `cefpython49-winxp` branch - - -### v31 release (old systems) - -OS | Py2 | Py3 | 32bit | 64bit | Requirements ---- | --- | --- | --- | --- | --- -Windows | 2.7 | No | Yes | Yes | Windows XP+ -Linux | 2.7 | No | Yes | Yes | Debian 7+ / Ubuntu 12.04+ -Mac | 2.7 | No | Yes | Yes | MacOS 10.7+ - -Additional information for v31.2 release: -- On Windows/Mac you can install with command: `pip install cefpython3==31.2` -- Downloads are available on the GitHub Releases page tagged - [v31.2](../../releases/tag/v31.2). -- API reference is available in revision [169a1b2](../../tree/169a1b20d3cd09879070d41aab28cfa195d2a7d5/docs/api) -- Other documentation can be downloaded by cloning the - cefpython.wiki repository: `git clone git@github.com:cztomczak/cefpython.wiki.git` - - -## Support development - -If you would like to support general CEF Python development efforts -by making a donation then please click the Paypal Donate button below. -If you would like to see a specific feature implemented then you can make -a comment about that when making a donation and that will give it a higher -priority. - - - -

- - -### Thanks to all - -* [2021] Thank you to [Fivestars](https://www.fivestars.com/) for sponsoring - the v66.1 release with Python 3.8 / 3.9 support -* [2018] Thanks to [Fivestars](https://www.fivestars.com/) for sponsoring - the v49 release for legacy systems (WinXP/Vista) -* [2018] Many thanks to [Lampix](https://lampix.com/) for sponsoring the v66 - release for all platforms -* [2017] Many thanks to [HighSide Inc.](https://highside.io/) for sponsoring - the v55/v56 releases for all platforms -* [2016-2018] Thanks to JetBrains for providing an Open Source license for - [PyCharm](https://www.jetbrains.com/pycharm/) -* [2014] Thanks to Adam Duston for donating a Macbook to aid the development - of Mac port -* [2013-2015] Lots of thanks goes to [Cyan Inc.](http://www.blueplanet.com/) - for sponsoring this project for a long time, making CEF Python 3 mature -* [2013] Thanks to [Rentouch GmbH](http://www.rentouch.ch/) for sponsoring the - development of the off-screen rendering support -* [2013] Thanks to Thomas Wusatiuk for sponsoring the development of the web - response reading features -* [2012-2018] Thanks to those who have made a Paypal donation: - [Rentouch GmbH](http://www.rentouch.ch/), Walter Purvis, Rokas Stupuras, - Alex Rattray, Greg Kacy, Paul Korzhyk, Tomasz Tomanek. -* [2012-2017] Thanks to those who have donated their time through code - contributions, they are listed in the [Authors](Authors) file - - -## Seeking new sponsors - -CEF Python is seeking companies to sponsor further development of the project. -There are many proposals for new features submitted in the issue tracker. Most -notable are: - -* Monthly releases with latest Chromium -* An automated build system similar to upstream CEF Spotify Automated Builds -* ARM and Android support -* Multi-threaded support for increased performance -* Proprietary codecs support in build tools: H264, H265,AC3, EAC3, MPEG-4 -* More CEF API exposed, only about 50% is exposed so far -* Hundreds of new settings and Chromium preferences not yet exposed -* Easier integration with popular GUI toolkits in just a few lines of code - and support for more third party GUI frameworks -* More examples of implementing various advanced features and more snippets - as well - -If your company would like to sponsor CEF Python development efforts then -please contact -[Czarek](https://www.linkedin.com/in/czarektomczak/). -Long term sponsorships are welcome and Czarek is open to ideas about -the project. He would love to spend more time on developing this project, -but he can't afford doing so in his free time. Currently there is no company -supporting this project actively on a daily basis. - - -## Other READMEs - -- [PyInstaller packager](examples/pyinstaller/README-pyinstaller.md) - - - -## Quick links - -### Docs - -- [Build instructions](docs/Build-instructions.md) -- [Knowledge Base](docs/Knowledge-Base.md) -- [Migration guide](docs/Migration-guide.md) -- [Tutorial](docs/Tutorial.md) - - -### API categories +## API #### Modules From 811fa74c8ef413d5b82371d6d74166e7d5eab47b Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:07:19 +0100 Subject: [PATCH 21/27] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 80bda463..35127ab7 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,9 @@ Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ ## Examples - [Tutorial](docs/Tutorial.md) -- [All examples](examples/README-examples.md). -- [Snippets](examples/snippets/README-snippets.md). -- [PyInstaller packager](examples/pyinstaller/README-pyinstaller.md). +- [All examples](examples/README-examples.md) +- [Snippets](examples/snippets/README-snippets.md) +- [PyInstaller packager](examples/pyinstaller/README-pyinstaller.md) ## Support From 6c72dc3d093d3eebbee3ff0b79dc58b762f10846 Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:11:02 +0100 Subject: [PATCH 22/27] Update README.md --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 35127ab7..2e127e63 100644 --- a/README.md +++ b/README.md @@ -86,13 +86,7 @@ Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ [Issues labelled Knowledge Base](../../issues?q=is%3Aissue+is%3Aopen+label%3A%22Knowledge+Base%22) - To search documentation use GitHub "This repository" search at the top. To narrow results to documentation only select - "Markdown" in the right pane. -- You can vote on issues in the tracker to let us know which issues are - important to you. To do that add a +1 thumb up reaction to the first post - in the issue. See - [Most popular issues](../../issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) - sorted by reactions. - + "Markdown" in the side pane. ## Support development From 0d3295e05212333f14155f416cc483bd2b2f3e3f Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:12:07 +0100 Subject: [PATCH 23/27] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e127e63..06d3a4e3 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ by making a donation then please click the Paypal Donate button below. -

+
## Seeking sponsors From a6f5def34270b8d64a733597146b98633a7e7dd3 Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:17:13 +0100 Subject: [PATCH 24/27] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 06d3a4e3..b6fe4539 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,7 @@ Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ ## Support development -If you would like to support general CEF Python development efforts -by making a donation then please click the Paypal Donate button below. +To support general CEF Python development efforts please make a donation using PayPal button below: From de22be237b20b504eb6bdc385eae436eb12d225b Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:18:30 +0100 Subject: [PATCH 25/27] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6fe4539..755d6299 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ ## Support development -To support general CEF Python development efforts please make a donation using PayPal button below: +To support general CEF Python development efforts you can make a donation using PayPal button below: From 5217c04feaa6b8a4abbcb18bba34ad586e3cecd1 Mon Sep 17 00:00:00 2001 From: Czarek Tomczak Date: Sat, 8 Feb 2025 01:23:50 +0100 Subject: [PATCH 26/27] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 755d6299..4ff688b0 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,16 @@ PyGame, PyOpenGL, PyWin32, PySide and PySDL2. ## Install -You can install [pypi/cefpython3](https://pypi.python.org/pypi/cefpython3) -package using pip tool. On Linux pip 8.1+ is required. You can -also download packages for offline installation available on the -[GitHub Releases](../../releases) pages. Command to install with pip: +Command to install with pip: ``` pip install cefpython3==66.1 ``` +Hosted at [pypi/cefpython3](https://pypi.python.org/pypi/cefpython3). On Linux pip 8.1+ is required. + +You can also download packages for offline installation available on the [GitHub Releases](../../releases) pages. + Below is a table with supported platforms, python versions and architectures. OS | Py2 | Py3 | 32bit | 64bit | Requirements From 3d6f6c19992cb112d6de8ff856bce443bdf3bbea Mon Sep 17 00:00:00 2001 From: Mandru-JashwanthKumar Date: Wed, 26 Nov 2025 10:17:23 +0530 Subject: [PATCH 27/27] Fix formatting of README.md documentation section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ff688b0..b85f34c6 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Mac | 2.7 | 3.4 / 3.5 / 3.6 / 3.7 | No | Yes | MacOS 10.9+ [Issues labelled Knowledge Base](../../issues?q=is%3Aissue+is%3Aopen+label%3A%22Knowledge+Base%22) - To search documentation use GitHub "This repository" search at the top. To narrow results to documentation only select - "Markdown" in the side pane. + "Markdown" in the side pane ## Support development