Skip to content

Commit 0ee18e9

Browse files
committed
Version 0.23
+ Developer tools + cefwindow.MoveWindow()
1 parent f70263a commit 0ee18e9

22 files changed

Lines changed: 256 additions & 142 deletions

accelerated compositing.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
architecture > accelerated compositing buggy? disable by default in browserSettings.

browser.pyx

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ class Browser:
66

77
windowID = 0
88

9-
# This is required for weakref.ref() to work.
10-
__slots__ = ["GetWindowID", "CloseBrowser"]
11-
12-
def __init__(self, inWindowID):
9+
def __init__(self, windowID):
1310

14-
self.windowID = inWindowID
11+
self.windowID = windowID
12+
assert win32gui.IsWindow(windowID), "Invalid window handle (windowID)"
13+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(self.windowID)
14+
assert <void*>cefBrowser != NULL, "CefBrowser not found for this window handle (windowID)"
1515

1616
def GetWindowID(self):
1717

@@ -20,13 +20,9 @@ class Browser:
2020

2121
def CloseBrowser(self):
2222

23-
# weakref.proxy() or checks like this in every method?
24-
if not self.windowID:
25-
raise Exception("Browser.CloseBrowser(): browser is already closed")
26-
23+
assert self.windowID, "Browser was destroyed earlier"
2724
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(self.windowID)
28-
if <void*>cefBrowser == NULL:
29-
return
25+
assert <void*>cefBrowser != NULL, "CefBrowser not found, destroyed?"
3026

3127
if __debug: print "CefBrowser.ParentWindowWillClose()"
3228
(<CefBrowser*>(cefBrowser.get())).ParentWindowWillClose()
@@ -37,3 +33,20 @@ class Browser:
3733
__cefBrowsers.erase(<int>self.windowID)
3834
del __pyBrowsers[self.windowID]
3935
self.windowID = 0
36+
37+
def ShowDevTools(self):
38+
39+
assert self.windowID, "Browser was destroyed earlier"
40+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(self.windowID)
41+
assert <void*>cefBrowser != NULL, "CefBrowser not found, destroyed?"
42+
43+
(<CefBrowser*>(cefBrowser.get())).ShowDevTools()
44+
45+
def CloseDevTools(self):
46+
47+
assert self.windowID, "Browser was destroyed earlier"
48+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(self.windowID)
49+
assert <void*>cefBrowser != NULL, "CefBrowser not found, destroyed?"
50+
51+
(<CefBrowser*>(cefBrowser.get())).CloseDevTools()
52+
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
CEF Python provides bindings for the Chromium Embedded Framework (CEF).
2+
13
Example application
24
There are 2 example applications:
35
- cefsimple.py
@@ -41,7 +43,10 @@ icon.ico
4143

4244
CHANGELOG.
4345

44-
Version 0.22
46+
Version xx released on xx.
47+
* More api for the Browser object, developer tools and others.
48+
49+
Version 0.22 released on 2012-07-02.
4550
* Object oriented model for the Browser api
4651
* Removed cefwindow as a dependency of cefpython module.
4752
* Fixed bug: browser's client area did not get keyboard focus.

cefexample/cefadvanced.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
<li>javascript bindings
2626
<li>javascript callbacks
2727
<li>popup and modal windows
28-
<li>resizing and moving windows
29-
<li>developer tools
3028
<li>loading content from zip (optionally encrypted)
3129
</ul>
3230

cefexample/cefadvanced.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import cefwindow
77
import win32con # pywin32 extension
88
import win32gui
9+
import os
10+
import sys
11+
import traceback
12+
import time
913

1014

1115
def QuitApplication(windowID, msg, wparam, lparam):
1216

1317
browser = cefpython.GetBrowserByWindowID(windowID)
1418
browser.CloseBrowser()
15-
print "after CloseBrowser, browser = %s" % browser
1619
cefwindow.DestroyWindow(windowID)
1720
win32gui.PostQuitMessage(0)
1821

@@ -21,7 +24,8 @@ def CefAdvanced():
2124

2225
# Programming API:
2326
# http://code.google.com/p/cefpython/wiki/API
24-
27+
28+
sys.excepthook = cefpython.ExceptHook # In case of exception display it, write to error.log, shutdown CEF and exit application.
2529
cefwindow.__debug = True # Whether to print debug output to console.
2630
cefpython.__debug = True
2731

cefexample/cefsimple.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def QuitApplication(windowID, msg, wparam, lparam):
1515

1616
def CefSimple():
1717

18+
sys.excepthook = cefpython.ExceptHook # In case of exception display it, write to error.log, shutdown CEF and exit application.
1819
cefpython.Initialize({"multi_threaded_message_loop": False})
1920
wndproc = {
2021
win32con.WM_CLOSE: QuitApplication,

cefexample/cefwindow.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,34 @@ def GetWindowClassname(windowID):
101101
if key == windowID:
102102
return __windows[key]
103103

104+
def MoveWindow(windowID, xpos=None, ypos=None, width=None, height=None, center=None):
105+
106+
(left, top, right, bottom) = win32gui.GetWindowRect(windowID)
107+
if xpos == None and ypos == None:
108+
xpos = left
109+
ypos = top
110+
if width == None and height == None:
111+
width = right - left
112+
height = bottom - top
113+
# Case: only ypos provided
114+
if not xpos:
115+
xpos = left
116+
if not ypos:
117+
ypos = top
118+
# Case: only height provided
119+
if not width:
120+
width = right - left
121+
if not height:
122+
height = bottom - top
123+
if center:
124+
screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
125+
screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
126+
xpos = int(math.floor((screenx - width) / 2))
127+
ypos = int(math.floor((screeny - height) / 2))
128+
if xpos < 0: xpos = 0
129+
if ypos < 0: ypos = 0
130+
win32gui.MoveWindow(windowID, xpos, ypos, width, height, 1)
131+
104132

105133
def WM_CLOSE(windowID, msg, wparam, lparam):
106134

cefexample/debug.log

Lines changed: 0 additions & 35 deletions
This file was deleted.

cefpython.pyx

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,54 @@ import win32con
88
import win32gui
99
import win32api
1010
import cython
11-
import weakref
11+
import traceback
12+
import time
1213

1314
from libcpp cimport bool as cbool
14-
from libc.stdlib cimport malloc, free
1515
from libcpp.map cimport map
1616

17-
from cef cimport *
17+
# When pyx file cimports * from a pxd file and that cimports * from another pxd
18+
# then these another names will be visible in pyx file.
19+
20+
# Circular imports are allowed in form "cimport ...",
21+
# but won't work if you do "from ... cimport *", this
22+
# is important to know in pxd files.
23+
24+
from windows cimport *
25+
from cef_string cimport *
26+
from cef_type_wrappers cimport *
27+
from cef_task cimport *
28+
from cef_win cimport *
29+
from cef_ptr cimport *
30+
from cef_app cimport *
31+
from cef_browser cimport *
32+
from cef_client cimport *
33+
from cef_client2 cimport *
34+
35+
# Global variables.
1836

1937
__debug = False
20-
cdef map[int, cefrefptr_cefbrowser_t] __cefBrowsers # windowID(int): browser
38+
cdef map[int, CefRefPtr[CefBrowser]] __cefBrowsers # windowID(int): browser
2139
__pyBrowsers = {}
22-
cdef CefRefPtr[CefClient2] __cefclient2 = <cefrefptr_cefclient2_t?>new CefClient2() # <...?> means to throw an error if the cast is not allowed
40+
cdef CefRefPtr[CefClient2] __cefclient2 = <CefRefPtr[CefClient2]?>new CefClient2() # <...?> means to throw an error if the cast is not allowed
41+
42+
43+
def ExceptHook(type, value, traceobject):
44+
45+
error = "\n".join(traceback.format_exception(type, value, traceobject))
46+
if hasattr(sys, "frozen"): path = os.path.dirname(sys.executable)
47+
elif "__file__" in locals(): path = os.path.dirname(os.path.realpath(__file__))
48+
else: path = os.getcwd()
49+
with open(path+"/error.log", "a") as file:
50+
file.write("\n[%s] %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), error))
51+
print "\n"+error+"\n"
52+
CefQuitMessageLoop()
53+
CefShutdown()
54+
os._exit(1) # so that "finally" does not execute
2355

2456

2557
def GetLastError():
58+
2659
code = win32api.GetLastError()
2760
return "(%d) %s" % (code, win32api.FormatMessage(code))
2861

@@ -87,7 +120,7 @@ def CreateBrowser(windowID, browserSettings, url):
87120
cdef CefString *cefUrl = new CefString()
88121
cefUrl.FromASCII(<char*>url)
89122

90-
cdef CefRefPtr[CefBrowser] cefBrowser = CreateBrowserSync(info, <cefrefptr_cefclient_t?>__cefclient2, cefUrl[0], cefBrowserSettings)
123+
cdef CefRefPtr[CefBrowser] cefBrowser = CreateBrowserSync(info, <CefRefPtr[CefClient]?>__cefclient2, cefUrl[0], cefBrowserSettings)
91124

92125
if <void*>cefBrowser == NULL:
93126
if __debug: print "CreateBrowserSync(): NULL"
@@ -99,21 +132,22 @@ def CreateBrowser(windowID, browserSettings, url):
99132
__cefBrowsers[<int>windowID] = cefBrowser
100133
__pyBrowsers[windowID] = Browser(windowID)
101134

102-
return weakref.ref(__pyBrowsers[windowID])
135+
return __pyBrowsers[windowID]
103136

104137

105138
cdef CefRefPtr[CefBrowser] GetCefBrowserByWindowID(windowID):
106139

107140
# Map key exists: http://stackoverflow.com/questions/1939953/how-to-find-if-a-given-key-exists-in-a-c-stdmap
141+
assert windowID, "Browser was destroyed"
108142
if __cefBrowsers.find(windowID) == __cefBrowsers.end():
109-
return <CefRefPtr[CefBrowser]?>NULL
143+
raise Exception("Browser for this window handle (windowID) does not exist")
110144
return __cefBrowsers[<int>windowID]
111145

112146

113147
def GetBrowserByWindowID(windowID):
114148

115149
if windowID in __pyBrowsers:
116-
return weakref.ref(__pyBrowsers[windowID])
150+
return __pyBrowsers[windowID]
117151
else:
118152
return None
119153

@@ -137,4 +171,15 @@ def Shutdown():
137171
if __debug: print "GetLastError(): %s" % GetLastError()
138172

139173

174+
# ------------------
175+
176+
cimport cef_types
177+
178+
TID_UI = cef_types.TID_UI
179+
TID_IO = cef_types.TID_IO
180+
TID_FILE = cef_types.TID_FILE
181+
182+
def CurrentlyOn(threadID):
140183

184+
threadID = <int>int(threadID)
185+
return CefCurrentlyOn(<CefThreadId>threadID)

cefwindow wiki.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=`cefwindow` module=
2+
3+
windowID *!CreateWindow*(string `title`, string `classname`, int `width`, int `height`, int `xpos`=None, int `ypos`=None, string `icon`, dict `wndproc`=None)
4+
5+
Creates window using pywin32 extension. `classname` must be a unique string for each of the window. Parameters `xpos` and `ypos` are position of the window, if you do not provide them the window will be centered on the screen. `wndproc` is a dictionary list of window procedures like [http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx WM_CLOSE], [http://msdn.microsoft.com/en-us/library/windows/desktop/ms632646(v=vs.85).aspx WM_SIZE].
6+
7+
`windowID` is an int memory address that points to HWND, to check whether it is a valid window handle call `win32gui.IsWindow(windowID)`.
8+
9+
void *!DestroyWindow*(windowID)
10+
11+
Destroys window. Call it after [cefpython].`CloseBrowser()`.
12+
13+
void *!MoveWindow*(`windowID`, int `xpos`=None, int `ypos`=None, int `width`=None, int `height`=None, bool center=None):
14+
15+
Change position of window, resize or center it. You don't have to provide all parameters, you can use any combination of them, examples:
16+
17+
{{{
18+
MoveWindow(windowID, width=500, height=400) # x and y position of the window are not changed.
19+
MoveWindow(windowID, width=1000, center=True) # height stays the same, additionally center on the screen.
20+
}}}

0 commit comments

Comments
 (0)