feat: Implement BrowserWindow.getMediaSourceId() and BrowserWindow.moveAbove(mediaSourceId) (#18926)

* feat: Implement BrowserWindow.moveAbove(mediaSourceId)

BrowserWindow.{focus,blur,moveTop}() are not enough in some
situations. For example when implementing an overlay that
follows another window that can lose focus. In that case
it is useful to move the overlay above the tracked window.

sourceId is a string in the format of DesktopCapturerSource.id,
for example "window:1869:0".

Notes: Added BrowserWindow.moveAbove(mediaSourceId)

https://github.com/electron/electron/issues/18922

* feat: Implement BrowserWindow.getMediaSourceId

Return the Window id in the format of DesktopCapturerSource's id.
For example "window🔢0".

https://github.com/electron/electron/issues/16460

Notes: Added BrowserWindow.getMediaSourceId
This commit is contained in:
Julien Isorce 2019-08-14 23:51:15 -07:00 committed by Cheng Zhao
parent d0c7a91a50
commit 680399f476
12 changed files with 320 additions and 4 deletions

View file

@ -17,6 +17,7 @@
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "native_mate/dictionary.h"
#include "shell/browser/api/atom_api_web_contents.h"
#include "shell/browser/native_browser_view_views.h"
@ -647,6 +648,31 @@ void NativeWindowViews::SetResizable(bool resizable) {
resizable_ = resizable;
}
bool NativeWindowViews::MoveAbove(const std::string& sourceId) {
const content::DesktopMediaID id = content::DesktopMediaID::Parse(sourceId);
if (id.type != content::DesktopMediaID::TYPE_WINDOW)
return false;
#if defined(OS_WIN)
const HWND otherWindow = reinterpret_cast<HWND>(id.id);
if (!::IsWindow(otherWindow))
return false;
gfx::Point pos = GetPosition();
gfx::Size size = GetSize();
::SetWindowPos(GetAcceleratedWidget(), otherWindow, pos.x(), pos.y(),
size.width(), size.height(),
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
#elif defined(USE_X11)
if (!IsWindowValid(id.id))
return false;
electron::MoveWindowAbove(GetAcceleratedWidget(), id.id);
#endif
return true;
}
void NativeWindowViews::MoveTop() {
// TODO(julien.isorce): fix chromium in order to use existing
// widget()->StackAtTop().
@ -1117,6 +1143,37 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() {
return false;
}
content::DesktopMediaID NativeWindowViews::GetDesktopMediaID() const {
const gfx::AcceleratedWidget accelerated_widget = GetAcceleratedWidget();
content::DesktopMediaID::Id window_handle = content::DesktopMediaID::kNullId;
content::DesktopMediaID::Id aura_id = content::DesktopMediaID::kNullId;
#if defined(OS_WIN)
window_handle =
reinterpret_cast<content::DesktopMediaID::Id>(accelerated_widget);
#elif defined(USE_X11)
window_handle = accelerated_widget;
#endif
aura::WindowTreeHost* const host =
aura::WindowTreeHost::GetForAcceleratedWidget(accelerated_widget);
aura::Window* const aura_window = host ? host->window() : nullptr;
if (aura_window) {
aura_id = content::DesktopMediaID::RegisterNativeWindow(
content::DesktopMediaID::TYPE_WINDOW, aura_window)
.window_id;
}
// No constructor to pass the aura_id. Make sure to not use the other
// constructor that has a third parameter, it is for yet another purpose.
content::DesktopMediaID result = content::DesktopMediaID(
content::DesktopMediaID::TYPE_WINDOW, window_handle);
// Confusing but this is how content::DesktopMediaID is designed. The id
// property is the window handle whereas the window_id property is an id
// given by a map containing all aura instances.
result.window_id = aura_id;
return result;
}
gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() const {
if (GetNativeWindow() && GetNativeWindow()->GetHost())
return GetNativeWindow()->GetHost()->GetAcceleratedWidget();