Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
ardublockly
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
ardublockly
Commits
e54d2a8e
Commit
e54d2a8e
authored
May 28, 2015
by
carlosperate
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update CEF GUI with Mac OS X compatibility
parent
55765797
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
60 deletions
+107
-60
start_cef.py
start_cef.py
+107
-60
No files found.
start_cef.py
View file @
e54d2a8e
#!/usr/bin/env python2
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
# Embedding CEF browser in a wxPython window to launch Ardublockly.
# Embedding Chromium Embedded Framework browser in a wxPython window to launch
# Ardublockly.
#
#
# Copyright (c) 2015 carlosperate https://github.com/carlosperate/
# Based on an example to from the CEF Python repository.
#
# https://code.google.com/p/cefpython/source/browse/cefpython/cef3/windows/binaries_64bit/wxpython.py
# Licensed under the Apache License, Version 2.0 (the "License");
# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
# you may not use this file except in compliance with the License.
# Website: http://code.google.com/p/cefpython/
# You may obtain a copy of the License at
# New BSD license:
#
# https://code.google.com/p/cefpython/source/browse/cefpython/LICENSE.txt
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Changes are copyright (c) 2015 carlosperate https://github.com/carlosperate/
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# In Mac cefpython library must be the very first library imported. This is
# because CEF was compiled with the tcmalloc memory allocator which hooks
# globally and replaces the default malloc allocator. If memory was allocated
# using malloc and then freed using tcmalloc then this would result in random
# segmentation faults in an application. See Issue 155 which is to provide CEF
# builds on Mac with tcmalloc disabled:
# https://code.google.com/p/cefpython/issues/detail?id=155
import
sys
try
:
from
cefpython3
import
cefpython
import
wx
import
wx.lib.agw.flatmenu
as
FM
except
ImportError
:
print
(
"You need to have ce fpython3, and wx installed!"
)
sys
.
exit
(
1
)
import
os
import
os
import
re
import
re
import
sys
import
time
import
time
import
uuid
#import uuid
import
struct
#import ctypes
#import struct
import
codecs
import
codecs
import
inspect
import
inspect
import
platform
import
platform
import
traceback
import
traceback
from
ArdublocklyServer.BlocklyHTTPServer
import
start_server
from
ArdublocklyServer.BlocklyHTTPServer
import
start_server
try
:
import
wx
import
wx.lib.agw.flatmenu
as
FM
from
cefpython3
import
cefpython
except
ImportError
:
print
(
"You need to have cefpython3, and wx installed!"
)
sys
.
exit
(
1
)
# Needed for packaging the application on self contained executable
__file__
=
sys
.
argv
[
0
]
__file__
=
sys
.
argv
[
0
]
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
...
@@ -44,7 +49,9 @@ __file__ = sys.argv[0]
...
@@ -44,7 +49,9 @@ __file__ = sys.argv[0]
g_applicationSettings
=
None
g_applicationSettings
=
None
g_browserSettings
=
None
g_browserSettings
=
None
g_countWindows
=
0
g_ardutag
=
"[ardublockly] "
g_ardutag
=
"[ardublockly] "
g_ardu_link
=
"http://localhost:8000/ardublockly/index.html"
g_platform_os
=
None
g_platform_os
=
None
# Which method to use for message loop processing.
# Which method to use for message loop processing.
...
@@ -143,7 +150,7 @@ class MainFrame(wx.Frame):
...
@@ -143,7 +150,7 @@ class MainFrame(wx.Frame):
size
=
(
1250
,
768
)
size
=
(
1250
,
768
)
# This is an optional code to enable High DPI support.
# This is an optional code to enable High DPI support.
if
(
g_platform_os
==
"win"
)
\
if
(
g_platform_os
==
"win
dows
"
)
\
and
(
"auto_zooming"
in
g_applicationSettings
)
\
and
(
"auto_zooming"
in
g_applicationSettings
)
\
and
(
g_applicationSettings
[
"auto_zooming"
]
==
"system_dpi"
):
and
(
g_applicationSettings
[
"auto_zooming"
]
==
"system_dpi"
):
# This utility function will adjust width/height using
# This utility function will adjust width/height using
...
@@ -153,9 +160,16 @@ class MainFrame(wx.Frame):
...
@@ -153,9 +160,16 @@ class MainFrame(wx.Frame):
self
.
SetSize
(
size
)
self
.
SetSize
(
size
)
# On mac the cefpython.Shutdown() has to be place in the onClose method.
# So, the number of opened windows has to be tracked/
if
g_platform_os
==
"mac"
:
global
g_countWindows
g_countWindows
+=
1
if
not
url
:
if
not
url
:
url
=
"http://localhost:8000/ardublockly/index.html"
url
=
g_ardu_link
# Cannot attach browser to the main frame as the menu won't work.
# Also have to set wx.WANTS_CHARS style for all parent panels/controls
# Also have to set wx.WANTS_CHARS style for all parent panels/controls
self
.
mainPanel
=
wx
.
Panel
(
self
,
style
=
wx
.
WANTS_CHARS
)
self
.
mainPanel
=
wx
.
Panel
(
self
,
style
=
wx
.
WANTS_CHARS
)
...
@@ -169,11 +183,13 @@ class MainFrame(wx.Frame):
...
@@ -169,11 +183,13 @@ class MainFrame(wx.Frame):
self
.
clientHandler
.
_OnAfterCreated
)
self
.
clientHandler
.
_OnAfterCreated
)
windowInfo
=
cefpython
.
WindowInfo
()
windowInfo
=
cefpython
.
WindowInfo
()
windowInfo
.
SetAsChild
(
self
.
GetHandleForBrowser
())
(
width
,
height
)
=
self
.
mainPanel
.
GetClientSizeTuple
()
windowInfo
.
SetAsChild
(
self
.
GetHandleForBrowser
(),
[
0
,
0
,
width
,
height
])
self
.
browser
=
cefpython
.
CreateBrowserSync
(
self
.
browser
=
cefpython
.
CreateBrowserSync
(
windowInfo
,
windowInfo
,
browserSettings
=
g_browserSettings
,
browserSettings
=
g_browserSettings
,
navigateUrl
=
url
)
navigateUrl
=
url
)
self
.
clientHandler
.
mainBrowser
=
self
.
browser
self
.
clientHandler
.
mainBrowser
=
self
.
browser
self
.
browser
.
SetClientHandler
(
self
.
clientHandler
)
self
.
browser
.
SetClientHandler
(
self
.
clientHandler
)
...
@@ -197,7 +213,8 @@ class MainFrame(wx.Frame):
...
@@ -197,7 +213,8 @@ class MainFrame(wx.Frame):
self
.
Bind
(
wx
.
EVT_CLOSE
,
self
.
OnClose
)
self
.
Bind
(
wx
.
EVT_CLOSE
,
self
.
OnClose
)
if
USE_EVT_IDLE
and
not
popup
:
if
USE_EVT_IDLE
and
not
popup
:
# Bind EVT_IDLE only for the main application frame.
# Bind EVT_IDLE only for the main application frame.
print
(
g_ardutag
+
"Using EVT_IDLE to execute the CEF message loop work"
)
print
(
g_ardutag
+
\
"Using EVT_IDLE to execute the CEF message loop work"
)
self
.
Bind
(
wx
.
EVT_IDLE
,
self
.
OnIdle
)
self
.
Bind
(
wx
.
EVT_IDLE
,
self
.
OnIdle
)
self
.
CreateMenu
()
self
.
CreateMenu
()
...
@@ -262,11 +279,11 @@ class MainFrame(wx.Frame):
...
@@ -262,11 +279,11 @@ class MainFrame(wx.Frame):
self
.
menubar
.
SetBarHeight
()
self
.
menubar
.
SetBarHeight
()
def
OnSetFocus
(
self
,
event
):
def
OnSetFocus
(
self
,
event
):
if
g_platform_os
!=
"linux
"
:
if
g_platform_os
==
"windows
"
:
cefpython
.
WindowUtils
.
OnSetFocus
(
self
.
GetHandleForBrowser
(),
0
,
0
,
0
)
cefpython
.
WindowUtils
.
OnSetFocus
(
self
.
GetHandleForBrowser
(),
0
,
0
,
0
)
def
OnSize
(
self
,
event
):
def
OnSize
(
self
,
event
):
if
g_platform_os
!=
"linux
"
:
if
g_platform_os
==
"windows
"
:
cefpython
.
WindowUtils
.
OnSize
(
self
.
GetHandleForBrowser
(),
0
,
0
,
0
)
cefpython
.
WindowUtils
.
OnSize
(
self
.
GetHandleForBrowser
(),
0
,
0
,
0
)
def
OnClose
(
self
,
event
):
def
OnClose
(
self
,
event
):
...
@@ -288,12 +305,22 @@ class MainFrame(wx.Frame):
...
@@ -288,12 +305,22 @@ class MainFrame(wx.Frame):
# | self.browser.ParentWindowWillClose()
# | self.browser.ParentWindowWillClose()
# | event.Skip()
# | event.Skip()
# On Win/Linux the call to cefpython.Shutdown() is after app.MainLoop()
# returns, but on Mac it needs to be here.
if
g_platform_os
==
"mac"
:
global
g_countWindows
g_countWindows
-=
1
if
g_countWindows
==
0
:
cefpython
.
Shutdown
()
print
(
g_ardutag
+
"OnClose: Exiting"
)
wx
.
GetApp
().
Exit
()
def
OnIdle
(
self
,
event
):
def
OnIdle
(
self
,
event
):
cefpython
.
MessageLoopWork
()
cefpython
.
MessageLoopWork
()
def
PyPrint
(
message
):
def
PyPrint
(
message
):
print
(
g_ardutag
+
"PyPrint: "
+
message
)
print
(
g_ardutag
+
"PyPrint: "
+
message
)
class
JavascriptExternal
:
class
JavascriptExternal
:
...
@@ -317,15 +344,16 @@ class JavascriptExternal:
...
@@ -317,15 +344,16 @@ class JavascriptExternal:
frame
.
Show
()
frame
.
Show
()
def
Print
(
self
,
message
):
def
Print
(
self
,
message
):
print
(
g_ardutag
+
"Print: "
+
message
)
print
(
g_ardutag
+
"Print: "
+
message
)
def
TestAllTypes
(
self
,
*
args
):
def
TestAllTypes
(
self
,
*
args
):
print
(
g_ardutag
+
"TestAllTypes: "
+
str
(
args
))
print
(
g_ardutag
+
"TestAllTypes: "
+
str
(
args
))
def
ExecuteFunction
(
self
,
*
args
):
def
ExecuteFunction
(
self
,
*
args
):
if
g_platform_os
==
"linux"
:
if
g_platform_os
==
"windows"
:
self
.
mainBrowser
.
ExecuteFunction
(
*
args
)
else
:
self
.
mainBrowser
.
GetMainFrame
().
ExecuteFunction
(
*
args
)
self
.
mainBrowser
.
GetMainFrame
().
ExecuteFunction
(
*
args
)
self
.
mainBrowser
.
ExecuteFunction
(
*
args
)
def
TestJSCallback
(
self
,
jsCallback
):
def
TestJSCallback
(
self
,
jsCallback
):
print
(
g_ardutag
+
"jsCallback.GetFunctionName() = %s"
%
print
(
g_ardutag
+
"jsCallback.GetFunctionName() = %s"
%
...
@@ -473,6 +501,8 @@ class ClientHandler:
...
@@ -473,6 +501,8 @@ class ClientHandler:
print
(
" source = %s"
%
source
)
print
(
" source = %s"
%
source
)
print
(
" line = %s"
%
line
)
print
(
" line = %s"
%
line
)
# onKeyEvent removed to avoid users using common browser key commands
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# RequestHandler
# RequestHandler
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
...
@@ -615,7 +645,7 @@ class ClientHandler:
...
@@ -615,7 +645,7 @@ class ClientHandler:
def
_Browser_LoadUrl
(
self
,
browser
):
def
_Browser_LoadUrl
(
self
,
browser
):
if
browser
.
GetUrl
()
==
"data:text/html,Test#Browser.LoadUrl"
:
if
browser
.
GetUrl
()
==
"data:text/html,Test#Browser.LoadUrl"
:
browser
.
LoadUrl
(
"http://localhost:8000/ardublockly/index.html"
)
browser
.
LoadUrl
(
g_ardu_link
)
def
OnLoadError
(
self
,
browser
,
frame
,
errorCode
,
errorTextList
,
failedUrl
):
def
OnLoadError
(
self
,
browser
,
frame
,
errorCode
,
errorTextList
,
failedUrl
):
print
(
g_ardutag
+
"LoadHandler::OnLoadError()"
)
print
(
g_ardutag
+
"LoadHandler::OnLoadError()"
)
...
@@ -649,22 +679,20 @@ class ClientHandler:
...
@@ -649,22 +679,20 @@ class ClientHandler:
# Set WindowInfo object:
# Set WindowInfo object:
# > windowInfo[0] = cefpython.WindowInfo()
# > windowInfo[0] = cefpython.WindowInfo()
# On Windows there are keyboard problems in popups, when popup
# On Windows there are keyboard problems in popups in wxPython, when
# is created using "window.open" or "target=blank". This issue
# popup is created using "window.open" or "target=blank".
# occurs only in wxPython. PyGTK or PyQt do not require this fix.
# The solution is to create window explicitly, and not depend
# The solution is to create window explicitly, and not depend
# on CEF to create window internally. See Issue 80 for details:
# on CEF to create window internally. See Issue 80 for details:
# https://code.google.com/p/cefpython/issues/detail?id=80
# https://code.google.com/p/cefpython/issues/detail?id=80
#
# If you set allowPopups=True then CEF will create popup window.
# If you set allowPopups=True then CEF will create popup window.
# The wx.Frame cannot be created here, as this callback is
# The wx.Frame cannot be created here, as this callback is
executed on
#
executed on the IO thread. Window should be created on the UI
#
the IO thread. Window should be created on the UI thread.
#
thread. One solution is to call cefpython.CreateBrowser()
#
One solution is to call cefpython.CreateBrowser() which runs
#
which runs
asynchronously and can be called on any thread.
# asynchronously and can be called on any thread.
# The other solution is to post a task on the UI thread, so
# The other solution is to post a task on the UI thread, so
that
#
that
cefpython.CreateBrowserSync() can be used.
# cefpython.CreateBrowserSync() can be used.
cefpython
.
PostTask
(
cefpython
.
TID_UI
,
self
.
_CreatePopup
,
targetUrl
)
cefpython
.
PostTask
(
cefpython
.
TID_UI
,
self
.
_CreatePopup
,
targetUrl
)
allowPopups
=
False
allowPopups
=
False
return
not
allowPopups
return
not
allowPopups
...
@@ -786,17 +814,27 @@ def cef_init():
...
@@ -786,17 +814,27 @@ def cef_init():
"devtools"
:
True
},
# Developer Tools
"devtools"
:
True
},
# Developer Tools
"downloads_enabled"
:
True
,
"downloads_enabled"
:
True
,
"ignore_certificate_errors"
:
True
,
"ignore_certificate_errors"
:
True
,
"locales_dir_path"
:
cefpython
.
GetModuleDirectory
()
+
os
.
sep
+
"locales"
,
"debug"
:
True
,
"debug"
:
True
,
"log_file"
:
GetApplicationPath
(
"cef_debug.log"
),
"log_file"
:
GetApplicationPath
(
"cef_debug.log"
),
"log_severity"
:
cefpython
.
LOGSEVERITY_INFO
,
"log_severity"
:
cefpython
.
LOGSEVERITY_INFO
,
"release_dcheck_enabled"
:
False
,
"release_dcheck_enabled"
:
False
,
"remote_debugging_port"
:
0
,
"remote_debugging_port"
:
0
,
"resources_dir_path"
:
cefpython
.
GetModuleDirectory
(),
"unique_request_context_per_browser"
:
True
,
"unique_request_context_per_browser"
:
True
,
"auto_zooming"
:
"system_dpi"
"auto_zooming"
:
"system_dpi"
}
}
# "resources_dir_path" must be set on Mac, "locales_dir_path" not.
if
g_platform_os
==
"mac"
:
g_applicationSettings
[
"resources_dir_path"
]
=
\
cefpython
.
GetModuleDirectory
()
+
os
.
sep
+
"Resources"
else
:
g_applicationSettings
[
"resources_dir_path"
]
=
\
cefpython
.
GetModuleDirectory
()
g_applicationSettings
[
"locales_dir_path"
]
=
\
cefpython
.
GetModuleDirectory
()
+
os
.
sep
+
"locales"
# High DPI support is available only on Windows.
# High DPI support is available only on Windows.
# Example values for auto_zooming are:
# Example values for auto_zooming are:
# "system_dpi", "0.0" (96 DPI), "1.0" (120 DPI),
# "system_dpi", "0.0" (96 DPI), "1.0" (120 DPI),
...
@@ -807,8 +845,8 @@ def cef_init():
...
@@ -807,8 +845,8 @@ def cef_init():
# Medium 125% = 120 DPI = 1.0 zoom level
# Medium 125% = 120 DPI = 1.0 zoom level
# Larger 150% = 144 DPI = 2.0 zoom level
# Larger 150% = 144 DPI = 2.0 zoom level
# Custom 75% = 72 DPI = -1.0 zoom level
# Custom 75% = 72 DPI = -1.0 zoom level
#g_applicationSettings["auto_zooming"] = "system_dpi"
if
g_platform_os
==
"windows"
:
if
g_platform_os
==
"win"
:
#g_applicationSettings["auto_zooming"] = "system_dpi"
print
(
g_ardutag
+
"Calling SetProcessDpiAware"
)
print
(
g_ardutag
+
"Calling SetProcessDpiAware"
)
cefpython
.
DpiAware
.
SetProcessDpiAware
()
cefpython
.
DpiAware
.
SetProcessDpiAware
()
...
@@ -819,6 +857,11 @@ def cef_init():
...
@@ -819,6 +857,11 @@ def cef_init():
"no-proxy-server"
:
""
,
"no-proxy-server"
:
""
,
#"disable-remote-fonts": False,
#"disable-remote-fonts": False,
}
}
# On Mac it is required to provide path to a specific locale.pak file.
# On Win/Linux you only specify the ApplicationSettings.locales_dir_path.
if
g_platform_os
==
"mac"
:
g_commandLineSwitches
[
"locale_pak"
]
=
cefpython
.
GetModuleDirectory
()
+
\
"/Resources/en.lproj/locale.pak"
cefpython
.
Initialize
(
g_applicationSettings
,
g_commandLineSwitches
)
cefpython
.
Initialize
(
g_applicationSettings
,
g_commandLineSwitches
)
...
@@ -853,11 +896,12 @@ def detect_os():
...
@@ -853,11 +896,12 @@ def detect_os():
Options for g_platform_os are: win, lin, mac
Options for g_platform_os are: win, lin, mac
"""
"""
global
g_platform_os
global
g_platform_os
if
os
.
name
==
"nt"
:
os
=
platform
.
system
()
g_platform_os
=
"win"
if
os
==
"Windows"
:
elif
os
.
name
==
"posix"
:
g_platform_os
=
"windows"
elif
os
==
"Linux"
:
g_platform_os
=
"linux"
g_platform_os
=
"linux"
elif
os
.
name
==
"mac
"
:
elif
os
==
"Darwin
"
:
g_platform_os
=
"mac"
g_platform_os
=
"mac"
...
@@ -907,7 +951,10 @@ def main(argv):
...
@@ -907,7 +951,10 @@ def main(argv):
# This is to ensure reliable CEF shutdown.
# This is to ensure reliable CEF shutdown.
del
app
del
app
cefpython
.
Shutdown
()
# On Mac cefpython.Shutdown() is called in MainFrame.OnClose,
# followed by wx.GetApp.Exit().
if
g_platform_os
!=
"mac"
:
cefpython
.
Shutdown
()
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment