electron/atom/browser/native_window.h

374 lines
13 KiB
C
Raw Normal View History

// Copyright (c) 2013 GitHub, Inc.
2014-04-25 09:49:37 +00:00
// Use of this source code is governed by the MIT license that can be
2013-04-12 07:04:46 +00:00
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NATIVE_WINDOW_H_
#define ATOM_BROWSER_NATIVE_WINDOW_H_
#include <map>
2016-07-04 06:08:55 +00:00
#include <memory>
#include <string>
#include <vector>
2014-08-11 02:01:05 +00:00
#include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/cancelable_callback.h"
#include "base/memory/weak_ptr.h"
2013-04-18 12:50:58 +00:00
#include "base/observer_list.h"
2015-10-01 05:45:59 +00:00
#include "base/supports_user_data.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "extensions/browser/app_window/size_constraints.h"
#include "native_mate/persistent_dictionary.h"
2015-02-07 01:00:26 +00:00
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
2013-04-12 07:04:46 +00:00
class SkRegion;
namespace brightray {
class InspectableWebContents;
}
2013-04-12 07:04:46 +00:00
namespace content {
struct NativeWebKeyboardEvent;
2013-04-12 07:04:46 +00:00
}
namespace gfx {
class Point;
class Rect;
class Size;
}
namespace mate {
class Dictionary;
}
2013-04-12 07:04:46 +00:00
namespace atom {
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
class NativeBrowserView;
struct DraggableRegion;
2015-10-01 05:45:59 +00:00
class NativeWindow : public base::SupportsUserData,
public content::WebContentsObserver {
2013-04-12 07:04:46 +00:00
public:
~NativeWindow() override;
2013-04-12 07:04:46 +00:00
// Create window with existing WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(
brightray::InspectableWebContents* inspectable_web_contents,
2016-06-19 03:06:08 +00:00
const mate::Dictionary& options,
NativeWindow* parent = nullptr);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
void InitFromOptions(const mate::Dictionary& options);
2013-04-12 07:04:46 +00:00
virtual void Close() = 0;
2013-05-01 08:12:00 +00:00
virtual void CloseImmediately() = 0;
2015-08-06 03:10:34 +00:00
virtual bool IsClosed() const { return is_closed_; }
2013-04-12 07:04:46 +00:00
virtual void Focus(bool focus) = 0;
2013-05-16 14:56:52 +00:00
virtual bool IsFocused() = 0;
2013-04-12 07:04:46 +00:00
virtual void Show() = 0;
2014-10-17 14:51:20 +00:00
virtual void ShowInactive() = 0;
2013-04-12 07:04:46 +00:00
virtual void Hide() = 0;
2013-10-03 00:27:59 +00:00
virtual bool IsVisible() = 0;
virtual bool IsEnabled() = 0;
2013-04-12 07:04:46 +00:00
virtual void Maximize() = 0;
virtual void Unmaximize() = 0;
2014-05-14 21:58:49 +00:00
virtual bool IsMaximized() = 0;
2013-04-12 07:04:46 +00:00
virtual void Minimize() = 0;
virtual void Restore() = 0;
2014-07-26 05:58:26 +00:00
virtual bool IsMinimized() = 0;
2014-11-25 06:34:14 +00:00
virtual void SetFullScreen(bool fullscreen) = 0;
2015-04-21 13:35:36 +00:00
virtual bool IsFullscreen() const = 0;
virtual void SetBounds(const gfx::Rect& bounds, bool animate = false) = 0;
virtual gfx::Rect GetBounds() = 0;
virtual void SetSize(const gfx::Size& size, bool animate = false);
virtual gfx::Size GetSize();
virtual void SetPosition(const gfx::Point& position, bool animate = false);
virtual gfx::Point GetPosition();
virtual void SetContentSize(const gfx::Size& size, bool animate = false);
virtual gfx::Size GetContentSize();
2016-08-04 19:02:24 +00:00
virtual void SetContentBounds(const gfx::Rect& bounds, bool animate = false);
virtual gfx::Rect GetContentBounds();
virtual void SetSizeConstraints(
const extensions::SizeConstraints& size_constraints);
virtual extensions::SizeConstraints GetSizeConstraints();
virtual void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints);
virtual extensions::SizeConstraints GetContentSizeConstraints();
virtual void SetMinimumSize(const gfx::Size& size);
virtual gfx::Size GetMinimumSize();
virtual void SetMaximumSize(const gfx::Size& size);
virtual gfx::Size GetMaximumSize();
virtual void SetSheetOffset(const double offsetX, const double offsetY);
virtual double GetSheetOffsetX();
virtual double GetSheetOffsetY();
2013-04-12 07:04:46 +00:00
virtual void SetResizable(bool resizable) = 0;
2013-04-18 07:38:04 +00:00
virtual bool IsResizable() = 0;
virtual void SetMovable(bool movable) = 0;
virtual bool IsMovable() = 0;
virtual void SetMinimizable(bool minimizable) = 0;
virtual bool IsMinimizable() = 0;
2016-01-22 21:24:33 +00:00
virtual void SetMaximizable(bool maximizable) = 0;
virtual bool IsMaximizable() = 0;
2016-01-23 07:47:37 +00:00
virtual void SetFullScreenable(bool fullscreenable) = 0;
virtual bool IsFullScreenable() = 0;
virtual void SetClosable(bool closable) = 0;
virtual bool IsClosable() = 0;
2016-09-22 16:22:28 +00:00
virtual void SetAlwaysOnTop(bool top,
const std::string& level = "floating",
int relativeLevel = 0,
std::string* error = nullptr) = 0;
2013-04-18 07:38:04 +00:00
virtual bool IsAlwaysOnTop() = 0;
virtual void Center() = 0;
virtual void Invalidate() = 0;
2013-04-12 07:04:46 +00:00
virtual void SetTitle(const std::string& title) = 0;
2013-04-18 06:30:05 +00:00
virtual std::string GetTitle() = 0;
2013-04-12 07:04:46 +00:00
virtual void FlashFrame(bool flash) = 0;
virtual void SetSkipTaskbar(bool skip) = 0;
2013-04-12 07:04:46 +00:00
virtual void SetKiosk(bool kiosk) = 0;
virtual bool IsKiosk() = 0;
2015-10-23 03:35:33 +00:00
virtual void SetBackgroundColor(const std::string& color_name) = 0;
2016-01-23 10:55:12 +00:00
virtual void SetHasShadow(bool has_shadow) = 0;
virtual bool HasShadow() = 0;
virtual void SetRepresentedFilename(const std::string& filename);
virtual std::string GetRepresentedFilename();
virtual void SetDocumentEdited(bool edited);
virtual bool IsDocumentEdited();
virtual void SetIgnoreMouseEvents(bool ignore) = 0;
virtual void SetContentProtection(bool enable) = 0;
2016-06-13 08:10:28 +00:00
virtual void SetFocusable(bool focusable);
virtual void SetMenu(AtomMenuModel* menu);
virtual void SetParentWindow(NativeWindow* parent);
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
virtual void SetBrowserView(NativeBrowserView* browser_view) = 0;
virtual gfx::NativeView GetNativeView() = 0;
virtual gfx::NativeWindow GetNativeWindow() = 0;
2016-01-07 20:38:35 +00:00
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
2015-08-06 03:10:34 +00:00
// Taskbar/Dock APIs.
enum ProgressState {
PROGRESS_NONE, // no progress, no marking
PROGRESS_INDETERMINATE, // progress, indeterminate
PROGRESS_ERROR, // progress, errored (red)
PROGRESS_PAUSED, // progress, paused (yellow)
PROGRESS_NORMAL, // progress, not marked (green)
};
virtual void SetProgressBar(double progress,
const ProgressState state) = 0;
2015-02-07 01:00:26 +00:00
virtual void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) = 0;
2015-08-06 03:10:34 +00:00
// Workspace APIs.
2015-03-27 11:41:07 +00:00
virtual void SetVisibleOnAllWorkspaces(bool visible) = 0;
virtual bool IsVisibleOnAllWorkspaces() = 0;
2014-02-24 04:08:33 +00:00
virtual void SetAutoHideCursor(bool auto_hide);
2016-11-07 20:22:41 +00:00
// Vibrancy API
virtual void SetVibrancy(const std::string& type);
2016-11-07 20:22:41 +00:00
// Touchbar API
virtual void SetTouchBar(
const std::vector<mate::PersistentDictionary>& items);
2017-03-01 00:08:12 +00:00
virtual void RefreshTouchBarItem(const std::string& item_id);
2017-03-29 04:11:39 +00:00
virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
2015-08-06 03:10:34 +00:00
// Webview APIs.
virtual void FocusOnWebView();
virtual void BlurWebView();
virtual bool IsWebViewFocused();
2014-11-12 09:36:20 +00:00
// Toggle the menu bar.
virtual void SetAutoHideMenuBar(bool auto_hide);
virtual bool IsMenuBarAutoHide();
virtual void SetMenuBarVisibility(bool visible);
virtual bool IsMenuBarVisible();
// Set the aspect ratio when resizing window.
double GetAspectRatio();
gfx::Size GetAspectRatioExtraSize();
virtual void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size);
2016-11-21 18:30:13 +00:00
// File preview APIs.
2016-10-14 16:42:50 +00:00
virtual void PreviewFile(const std::string& path,
2016-10-26 00:47:22 +00:00
const std::string& display_name);
2016-11-21 18:30:13 +00:00
virtual void CloseFilePreview();
base::WeakPtr<NativeWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// Requests the WebContents to close, can be cancelled by the page.
virtual void RequestToClosePage();
// Methods called by the WebContents.
virtual void CloseContents(content::WebContents* source);
virtual void RendererUnresponsive(content::WebContents* source);
virtual void RendererResponsive(content::WebContents* source);
virtual void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {}
// Public API used by platform-dependent delegates and observers to send UI
// related notifications.
void NotifyWindowClosed();
void NotifyWindowEndSession();
void NotifyWindowBlur();
void NotifyWindowFocus();
void NotifyWindowShow();
void NotifyWindowHide();
2014-11-25 04:43:25 +00:00
void NotifyWindowMaximize();
void NotifyWindowUnmaximize();
void NotifyWindowMinimize();
void NotifyWindowRestore();
2015-05-09 15:55:10 +00:00
void NotifyWindowMove();
void NotifyWindowResize();
2015-05-20 08:37:13 +00:00
void NotifyWindowMoved();
2016-01-22 00:31:09 +00:00
void NotifyWindowScrollTouchBegin();
void NotifyWindowScrollTouchEnd();
void NotifyWindowScrollTouchEdge();
void NotifyWindowSwipe(const std::string& direction);
void NotifyWindowSheetBegin();
void NotifyWindowSheetEnd();
2014-11-25 04:43:25 +00:00
void NotifyWindowEnterFullScreen();
void NotifyWindowLeaveFullScreen();
void NotifyWindowEnterHtmlFullScreen();
void NotifyWindowLeaveHtmlFullScreen();
void NotifyWindowExecuteWindowsCommand(const std::string& command);
void NotifyTouchBarItemInteraction(const std::string& item_id,
const base::DictionaryValue& details);
2015-10-27 01:12:01 +00:00
#if defined(OS_WIN)
void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param);
#endif
2013-04-18 12:50:58 +00:00
void AddObserver(NativeWindowObserver* obs) {
observers_.AddObserver(obs);
}
void RemoveObserver(NativeWindowObserver* obs) {
observers_.RemoveObserver(obs);
}
brightray::InspectableWebContents* inspectable_web_contents() const {
return inspectable_web_contents_;
}
bool has_frame() const { return has_frame_; }
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
bool transparent() const { return transparent_; }
SkRegion* draggable_region() const { return draggable_region_.get(); }
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
NativeWindow* parent() const { return parent_; }
bool is_modal() const { return is_modal_; }
2013-04-12 07:04:46 +00:00
protected:
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options,
NativeWindow* parent);
2013-04-12 07:04:46 +00:00
// Convert draggable regions in raw format to SkRegion format. Caller is
// responsible for deleting the returned SkRegion instance.
2016-05-23 01:59:39 +00:00
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions);
// Converts between content bounds and window bounds.
virtual gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) = 0;
virtual gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) = 0;
// Called when the window needs to update its draggable region.
virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions);
2015-06-25 04:30:04 +00:00
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override;
2016-06-13 12:19:56 +00:00
void DidFirstVisuallyNonEmptyPaint() override;
bool OnMessageReceived(const IPC::Message& message) override;
2014-03-04 09:08:30 +00:00
2013-04-12 07:04:46 +00:00
private:
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
2016-06-13 12:19:56 +00:00
// Dispatch ReadyToShow event to observers.
void NotifyReadyToShow();
// Whether window has standard frame.
bool has_frame_;
// Whether window is transparent.
bool transparent_;
// For custom drag, the whole window is non-draggable and the draggable region
// has to been explicitly provided.
2016-05-23 01:59:39 +00:00
std::unique_ptr<SkRegion> draggable_region_; // used in custom drag.
// Minimum and maximum size, stored as content size.
extensions::SizeConstraints size_constraints_;
// Whether window can be resized larger than screen.
bool enable_larger_than_screen_;
// The windows has been closed.
bool is_closed_;
// Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_;
// Used to display sheets at the appropriate horizontal and vertical offsets
2016-06-18 13:26:26 +00:00
// on macOS.
double sheet_offset_x_;
double sheet_offset_y_;
2015-07-16 18:26:48 +00:00
// Used to maintain the aspect ratio of a view which is inside of the
// content view.
double aspect_ratio_;
gfx::Size aspect_ratio_extraSize_;
// The parent window, it is guaranteed to be valid during this window's life.
NativeWindow* parent_;
// Is this a modal window.
bool is_modal_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;
// Observers of this window.
2015-09-02 07:16:49 +00:00
base::ObserverList<NativeWindowObserver> observers_;
base::WeakPtrFactory<NativeWindow> weak_factory_;
2013-04-12 07:04:46 +00:00
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
// This class provides a hook to get a NativeWindow from a WebContents.
class NativeWindowRelay :
public content::WebContentsUserData<NativeWindowRelay> {
public:
explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window)
: key(UserDataKey()), window(window) {}
void* key;
base::WeakPtr<NativeWindow> window;
private:
friend class content::WebContentsUserData<NativeWindow>;
};
2013-04-12 07:04:46 +00:00
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_WINDOW_H_