A modal dialog is a child CefWindow that implements some special behaviors
relative to a parent CefWindow. Like any CefWindow it can be framed with
titlebar or frameless, and optionally contain draggable regions (subject to
platform limitations described below). Modal dialogs are shown centered on
the parent window (inside a single display) and always stay on top of the
parent window in z-order. Sizing behavior and available window buttons are
controlled via the usual CefWindowDelegate callbacks. For example, the dialog
can have a preferred size with resize, minimize and maximize disabled (via
GetPreferredSize, CanResize, CanMinimize and CanMaximize respectively).
This change adds support for two modality modes. With window modality all
controls in the parent window are disabled. With browser modality only the
browser view in the parent window is disabled.
Both modality modes require that a valid parent window be returned via
GetParentWindow. For window modality return true from IsWindowModalDialog
and call CefWindow::Show. For browser modality return false from
IsWindowModalDialog (the default value) and call
CefWindow::ShowAsBrowserModalDialog with a reference to the parent window's
browser view.
Window modal dialog behavior depends on the platform. On Windows and
Linux these dialogs have a titlebar and can be moved independent of the
parent window. On macOS these dialogs do not have a titlebar, move with
the parent window, and do not support draggable regions (because they are
implemented using sheets). On Linux disabling the parent window controls
requires a window manager the supports _NET_WM_STATE_MODAL.
Browser modal dialog behavior is similar on all platforms. The dialog will
be automatically sized and positioned relative to the parent window's
browser view. Closing the parent window or navigating the parent browser
view will dismiss the dialog. The dialog can also be moved independent of
the parent window though it will be recentered when the parent window
itself is resized or redisplayed. On MacOS the dialog will move along with
the parent window while on Windows and Linux the parent window can be moved
independently.
To test: Use the Tests > Dialog Window menu option in cefclient with Views
enabled (`--use-views` or `--enable-chrome-runtime` command-line flag).
Browser modal dialog is the default behavior. For window modal dialog add
the `--use-window-modal-dialog` command-line flag.
This is intended for usage with frameless windows that show the standard window
buttons, where resizing the title bar height changes the button offset. Returning a
different value from CefWindowDelegate::GetTitlebarHeight and forcing a resize of
the NSWindow's theme frame (see ViewsWindow::NudgeWindow) will update the
title bar height.
To test:
1. Run `cefclient --use-views --hide-frame --show-window-buttons --url=http://tests/window`
2. Enter a new value for title bar height and click the "Set Titlebar Height" button
Frameless windows now display as expected. Default traffic light buttons can
optionally be shown at configurable vertical position. Layout respects text
direction.
The cefclient sample app will persist window state across application restart
if run with views, cache_path and persist_user_references enabled.
To test:
1. Run `cefclient --use-views --cache-path=/path/to/cache --persist-user-preferences`
2. Move or resize the window, maximize, minimize, etc.
3. Exit cefclient.
4. Run cefclient again with the same arguments. The previous window state will
be restored.
- Windows: SDK version 10.0.20348.0 is now required.
- MacOS: SDK version 12.3 (Xcode 13.3) is now required.
- Legacy swiftshader binaries (`swiftshader/*` on Win/Linux and
`libswiftshader_*.dylib` on MacOS) have been removed (see issue #3176).
This change provides a generic solution for active (key) window tracking that
works with both Views-hosted and native windows on MacOS. With this new approach
we can now successfully route top menu actions to the currently active window.
Prior to this change CEF's Views API was using focus notifications as a proxy
for window activation notifications. That doesn't work on MacOS where NSWindow
activation (key status) is independent of NSView focus (first responder) status,
and changes in activation don't necessarily generate focus notifications (see
NativeWidgetMac::OnWindowKeyStatusChanged). To make this work reliably on all
platforms we now expose a CefWindowDelegate::OnWindowActivationChanged callback.
This change also fixes an uninitialized variable
(RootWindowMacImpl::with_extension_) that was causing flaky behavior in
RootWindowManager::OnRootWindowActivated.
To test:
1. Run `cefclient [--use-views]`
2. Select Popup Window from the Tests menu. Do not explicitly activate the popup
window (e.g. don't click on it).
3. Verify that further Tests menu actions go to the popup window.
4. Change activation to a first window by clicking on it. Verify that Test
menu actions go to that window.
5. Close the currently active window. Do not explicitly activate the remaining
window (e.g. don't click on it).
6. Verify that Test menu actions go to the only remaining window.
This change adds a `--use-default-popup` command-line option to cefclient. When
specified, popup windows will be created with default styling (e.g. without an
application-provided native parent window).
This change also adds some reasonable default window bounds in cases where they
are not specified by the client.
This change adds Chrome runtime support on Windows and Linux for creating a
browser parented to a native window supplied by the client application.
Expected API usage and window behavior is similar to what already exists with
the Alloy runtime. The parent window handle should be specified by using
CefWindowInfo::SetAsChild in combination with the CefBrowserHost::CreateBrowser
and CefLifeSpanHandler::OnBeforePopup callbacks.
The previously existing behavior of creating a fully-featured Chrome browser
window when empty CefWindowInfo is used with CreateBrowser remains unchanged
and Views is still the preferred API for creating top-level Chrome windows
with custom styling (e.g. title bar only, frameless, etc).
The cefclient Popup Window test with a native parent window continues to crash
on Linux with both the Alloy and Chrome runtimes (see issue #3165).
Also adds Chrome runtime support for CefDisplayHandler::OnCursorChange.
To test:
- Run `cefclient --enable-chrome-runtime [--use-views]` for the default (and
previously existing) Views-based behavior.
- Run `cefclient --enable-chrome-runtime --use-native` for the new native
parent window behavior.
- Run `cefclient --enable-chrome-runtime --use-native --no-activate` and the
window will not be activated (take input focus) on launch (Windows only).
- Run `cefclient --enable-chrome-runtime [--use-views|--use-native]
--mouse-cursor-change-disabled` and the mouse cursor will not change on
mouseover of DOM elements.
To test:
Run `cefclient.exe --use-views --hide-frame --hide-controls`
Add `--enable-chrome-runtime` for the same behavior using the Chrome location
bar instead of a text field.
The Chrome browser can now be hosted in a Views-based application on Mac
(see issue #2969).
To launch a fully-featured Chrome window using cefsimple:
$ open cefsimple.app --args --enable-chrome-runtime
To launch a minimally-styled Views-hosted window using cefsimple:
$ open cefsimple.app --args --use-views [--enable-chrome-runtime]
To launch a fully-styled Views-hosted window using cefclient:
$ open cefclient.app --args --use-views [--enable-chrome-runtime]
Known issues:
- Some Views unit tests are currently failing on Mac.
The Chrome browser can now be hosted in a Views-based application on Windows
and Linux.
To launch a fully-featured Chrome window using cefsimple:
$ cefsimple --enable-chrome-runtime
To launch a minimally-styled Views-hosted window using cefsimple:
$ cefsimple --enable-chrome-runtime --use-views
To launch a fully-styled Views-hosted window using cefclient:
$ cefclient --enable-chrome-runtime --use-views
Views unit tests also now pass with the Chrome runtime enabled:
$ ceftests --gtest_filter=Views* --enable-chrome-runtime
Known issues:
- Popup browsers cannot be intercepted and reparented.
- CefURLRequest::Create is no longer supported in the renderer process
(see https://crbug.com/891872). Use CefFrame::CreateURLRequest instead.
- Mac platform definitions have been changed from `MACOSX` to `MAC`
(see https://crbug.com/1105907) and related CMake macro names have
been updated. The old `OS_MACOSX` define is still set in code and CMake
for backwards compatibility.
- Linux ARM build is currently broken (see https://crbug.com/1123214).
As of https://crrev.com/9e653328e3 the Views framework will apply the "always
on top" (WS_EX_TOPMOST) style by default to widgets created with TYPE_MENU. CEF
uses this type in CefWindowView::CreateWidget to support child windows that are
not clipped to the parent window bounds (currently indicated by returning a
parent window from CefWindowDelegate::GetParentWindow and setting |is_menu| to
true).
Not setting "always on top" shouldn't be a problem except in cases where some
other window is already "always on top" and the child CefWindow is expected to
overlay that window. For this reason any menus created using ShowMenu will
continue to have the "always on top" style.
Ozone builds can run with different platform backends (Wayland, X11, etc). Usage of the Views framework is required, and the cefclient sample application is not supported.
Example usage:
$ export GN_DEFINES="use_ozone=true"
$ cd /path/to/chromium/src/cef
$ ./cef_create_projects.sh
$ cd /path/to/chromium/src
$ ninja -C out/Release_GN_x64 cefsimple
$ ./out/Release_GN_x64/cefsimple --use-views --ozone-platform=wayland
Binary distributions can be created by passing the `--ozone` flag to make_distrib.py.
- Add CefRequestContext::LoadExtension, CefExtension, CefExtensionHandler and
related methods/interfaces.
- Add chrome://extensions-support that lists supported Chrome APIs.
- Add CefBrowserHost::SetAutoResizeEnabled and CefDisplayHandler::OnAutoResize
to support browser resize based on preferred web contents size.
- views: Add support for custom CefMenuButton popups.
- cefclient: Run with `--load-extension=set_page_color` command-line flag for
an extension loading example. Add `--use-views` on Windows and Linux for an
even better example.
- Don't set InitParams::TRANSLUCENT_WINDOW. Setting this resulted in
the WS_EX_COMPOSITED style being added and the WS_THICKFRAME style
being removed, which disabled Aero Snap.
- Remove the non-client border to get a completely frameless window.
Having a border is problematic because the top is drawn by Windows
while the rest is drawn black. Having Windows draw part of the
border is required to enable the window drop shadow (see
HWNDMessageHandler::SetDwmFrameExtension).
- Delete the remove_caption patches which are no longer required.
- Add Views header files in a new include/views directory.
- Add initial top-level window (CefWindow), control (CefBrowserView,
CefLabelButton, CefMenuButton, CefPanel, CefScrollView,
CefTextfield) and layout (CefBoxLayout, CefFlowLayout) support.
See libcef/browser/views/view_impl.h comments for implementation
details.
- Add Views example usage in cefclient and cefsimple and Views unit
tests in cef_unittests. Pass the `--use-views` command-line flag to
cefclient, cefsimple and cef_unittests to run using the Views
framework instead of platform APIs. For cefclient and cefsimple
this will create the browser window and all related functionality
using the Views framework. For cef_unittests this will run all
tests (except OSR tests) in a Views-based browser window. Views-
specific unit tests (`--gtest_filter=Views*`) will be run even if
the the `--use-views` flag is not specified.
- Pass the `--hide-frame` command-line flag to cefclient to demo a
frameless Views-based browser window.
- Pass the `--hide-controls` command-line flag to cefclient to demo a
browser window without top controls. This also works in non-Views
mode.
- Pass the `--enable-high-dpi-support` command-line flag to
cef_unittests on Windows to test high-DPI support on a display
that supports it.
- Add CefImage for reading/writing image file formats.
- Add CefBrowser::DownloadImage() for downloading image URLs as a
CefImage representation. This is primarily for loading favicons.
- Add CefMenuModel::CreateMenuModel() and CefMenuModelDelegate for
creating custom menus. This is primarily for use with
CefMenuButton.
- Add CefBrowser::TryCloseBrowser() helper for closing a browser.
Also improve related documentation in cef_life_span_handler.h.
- Rename cef_page_range_t to cef_range_t. It is now also used by
CefTextfield.
- Remove CefLifeSpanHandler::RunModal() which is never called.
- Add draggable regions example to cefclient.