11# Example of embedding CEF Python browser using PyGTK library (GTK 2).
2- # Tested with GTK 2.24 and CEF Python v55.3+, only on Linux.
2+ # Tested with GTK 2.24 and CEF Python v55.3+, on Windows/ Linux.
33# Known issue on Linux: Keyboard focus problem (Issue #284).
44
55from cefpython3 import cefpython as cef
88import gobject
99import sys
1010import os
11+ import platform
12+
13+ # Fix for PyCharm hints warnings
14+ WindowUtils = cef .WindowUtils ()
15+
16+ # Platforms
17+ WINDOWS = (platform .system () == "Windows" )
18+ LINUX = (platform .system () == "Linux" )
19+ MAC = (platform .system () == "Darwin" )
1120
1221# In CEF you can run message loop in two ways (see API docs for more details):
13- # 1. By calling cef.MessageLoop() instead of an application-provided
22+ # 1. By calling cef.MessageLoopWork() in a timer - each call performs
23+ # a single iteration of CEF message loop processing.
24+ # 2. By calling cef.MessageLoop() instead of an application-provided
1425# message loop to get the best balance between performance and CPU
1526# usage. This function will block until a quit message is received by
16- # the system.
17- # 2. By calling cef.MessageLoopWork() in a timer - each call performs
18- # a single iteration of CEF message loop processing.
19- MESSAGE_LOOP_BEST = 1
20- MESSAGE_LOOP_TIMER = 2 # Pass --message-loop-timer flag to script to use this
27+ # the system. This seem to work only on Linux in GTK example.
28+ MESSAGE_LOOP_TIMER = 1
29+ MESSAGE_LOOP_CEF = 2 # Pass --message-loop-cef flag to script on Linux
2130g_message_loop = None
2231
2332
@@ -28,7 +37,7 @@ def main():
2837 cef .Initialize ()
2938 gobject .threads_init ()
3039 Gtk2Example ()
31- if g_message_loop == MESSAGE_LOOP_BEST :
40+ if g_message_loop == MESSAGE_LOOP_CEF :
3241 cef .MessageLoop ()
3342 else :
3443 gtk .main ()
@@ -46,13 +55,13 @@ def check_versions():
4655
4756def configure_message_loop ():
4857 global g_message_loop
49- if "--message-loop-timer" in sys .argv :
58+ if "--message-loop-cef" in sys .argv :
59+ print ("[gkt2.py] Message loop mode: CEF (best performance)" )
60+ g_message_loop = MESSAGE_LOOP_CEF
61+ sys .argv .remove ("--message-loop-cef" )
62+ else :
5063 print ("[gkt2.py] Message loop mode: TIMER" )
5164 g_message_loop = MESSAGE_LOOP_TIMER
52- sys .argv .remove ("--message-loop-timer" )
53- else :
54- print ("[gkt2.py] Message loop mode: BEST" )
55- g_message_loop = MESSAGE_LOOP_BEST
5665 if len (sys .argv ) > 1 :
5766 print ("[gkt2.py] ERROR: unknown argument passed" )
5867 sys .exit (1 )
@@ -83,7 +92,7 @@ def __init__(self):
8392 self .main_window .add (self .vbox )
8493
8594 windowInfo = cef .WindowInfo ()
86- windowInfo .SetAsChild (self .main_window . window . xid )
95+ windowInfo .SetAsChild (self .get_handle () )
8796 self .browser = cef .CreateBrowserSync (windowInfo , settings = {},
8897 url = "https://www.google.com/" )
8998 self .browser .SetClientHandler (LoadHandler ())
@@ -95,6 +104,12 @@ def __init__(self):
95104 if g_message_loop == MESSAGE_LOOP_TIMER :
96105 gobject .timeout_add (10 , self .on_timer )
97106
107+ def get_handle (self ):
108+ if LINUX :
109+ return self .main_window .window .xid
110+ else :
111+ return self .main_window .window .handle
112+
98113 def create_menu (self ):
99114 item1 = gtk .MenuItem ('MenuBar' )
100115 item1 .show ()
@@ -131,16 +146,22 @@ def on_vbox_size_allocate(self, _, data):
131146 y = data .y + self .menubar_height
132147 width = data .width
133148 height = data .height - self .menubar_height
134- self .browser .SetBounds (x , y , width , height )
149+ if WINDOWS :
150+ WindowUtils .OnSize (self .get_handle (), 0 , 0 , 0 )
151+ elif LINUX :
152+ self .browser .SetBounds (x , y , width , height )
135153
136154 def on_menubar_size_allocate (self , _ , data ):
137155 self .menubar_height = data .height
138156
139157 def on_exit (self , * _ ):
158+ if self .exiting :
159+ print ("[gtk2.py] on_exit() called, but already exiting" )
160+ return
140161 self .exiting = True
141162 self .browser .CloseBrowser (True )
142163 self .browser = None
143- if g_message_loop == MESSAGE_LOOP_BEST :
164+ if g_message_loop == MESSAGE_LOOP_CEF :
144165 cef .QuitMessageLoop ()
145166 else :
146167 gtk .main_quit ()
@@ -158,9 +179,10 @@ def OnLoadStart(self, browser, **_):
158179 # sometimes during initial loading, keyboard focus may
159180 # break and it is not possible to type anything, even
160181 # though a type cursor blinks in web view.
161- print ("[gtk2.py] LoadHandler.OnLoadStart:"
162- " keyboard focus fix (#284)" )
163- browser .SetFocus (True )
182+ if LINUX :
183+ print ("[gtk2.py] LoadHandler.OnLoadStart:"
184+ " keyboard focus fix (#284)" )
185+ browser .SetFocus (True )
164186 self .initial_app_loading = False
165187
166188
0 commit comments