feat: implement BrowserWindow.moveTop on X11 (#16629)

It was implemented on Mac and Win but not on X11.
Tested on Ubuntu 16.04 and 18.04.

Also added a unit test in spec/api-browser-window-spec.js.
This test BrowserWindow.moveTop verifies that calling moveTop
on a window does not give the focus to this window.

notes: BrowserWindow.moveTop is now available on Linux/x11

https://github.com/electron/electron/issues/12516
This commit is contained in:
Julien Isorce 2019-02-07 12:48:19 -08:00 committed by Shelley Vohr
parent db11b9b13b
commit 27bd47a333
9 changed files with 73 additions and 13 deletions

View file

@ -548,11 +548,9 @@ std::vector<int> TopLevelWindow::GetPosition() {
return result;
}
#if defined(OS_WIN) || defined(OS_MACOSX)
void TopLevelWindow::MoveTop() {
window_->MoveTop();
}
#endif
void TopLevelWindow::SetTitle(const std::string& title) {
window_->SetTitle(title);
@ -1067,9 +1065,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setResizable", &TopLevelWindow::SetResizable)
.SetMethod("isResizable", &TopLevelWindow::IsResizable)
.SetMethod("setMovable", &TopLevelWindow::SetMovable)
#if defined(OS_WIN) || defined(OS_MACOSX)
.SetMethod("moveTop", &TopLevelWindow::MoveTop)
#endif
.SetMethod("isMovable", &TopLevelWindow::IsMovable)
.SetMethod("setMinimizable", &TopLevelWindow::SetMinimizable)
.SetMethod("isMinimizable", &TopLevelWindow::IsMinimizable)

View file

@ -126,9 +126,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
void SetResizable(bool resizable);
bool IsResizable();
void SetMovable(bool movable);
#if defined(OS_WIN) || defined(OS_MACOSX)
void MoveTop();
#endif
bool IsMovable();
void SetMinimizable(bool minimizable);
bool IsMinimizable();

View file

@ -113,9 +113,7 @@ class NativeWindow : public base::SupportsUserData,
virtual double GetSheetOffsetX();
virtual double GetSheetOffsetY();
virtual void SetResizable(bool resizable) = 0;
#if defined(OS_WIN) || defined(OS_MACOSX)
virtual void MoveTop() = 0;
#endif
virtual bool IsResizable() = 0;
virtual void SetMovable(bool movable) = 0;
virtual bool IsMovable() = 0;

View file

@ -657,15 +657,19 @@ void NativeWindowViews::SetResizable(bool resizable) {
resizable_ = resizable;
}
#if defined(OS_WIN)
void NativeWindowViews::MoveTop() {
// TODO(julien.isorce): fix chromium in order to use existing
// widget()->StackAtTop().
#if defined(OS_WIN)
gfx::Point pos = GetPosition();
gfx::Size size = GetSize();
::SetWindowPos(GetAcceleratedWidget(), HWND_TOP, pos.x(), pos.y(),
size.width(), size.height(),
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
#elif defined(USE_X11)
atom::MoveWindowToForeground(GetAcceleratedWidget());
#endif
}
bool NativeWindowViews::IsResizable() {
#if defined(OS_WIN)

View file

@ -74,9 +74,7 @@ class NativeWindowViews : public NativeWindow,
void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) override;
void SetResizable(bool resizable) override;
#if defined(OS_WIN)
void MoveTop() override;
#endif
bool IsResizable() override;
void SetMovable(bool movable) override;
bool IsMovable() override;

View file

@ -88,4 +88,25 @@ bool ShouldUseGlobalMenuBar() {
return false;
}
void MoveWindowToForeground(::Window xwindow) {
XDisplay* xdisplay = gfx::GetXDisplay();
XEvent xclient;
memset(&xclient, 0, sizeof(xclient));
xclient.type = ClientMessage;
xclient.xclient.display = xdisplay;
xclient.xclient.window = xwindow;
xclient.xclient.message_type = GetAtom("_NET_RESTACK_WINDOW");
xclient.xclient.format = 32;
xclient.xclient.data.l[0] = 2;
xclient.xclient.data.l[1] = 0;
xclient.xclient.data.l[2] = Above;
xclient.xclient.data.l[3] = 0;
xclient.xclient.data.l[4] = 0;
XSendEvent(xdisplay, DefaultRootWindow(xdisplay), x11::False,
SubstructureRedirectMask | SubstructureNotifyMask, &xclient);
XFlush(xdisplay);
}
} // namespace atom

View file

@ -23,6 +23,9 @@ void SetWindowType(::Window xwindow, const std::string& type);
// Returns true if the bus name "com.canonical.AppMenu.Registrar" is available.
bool ShouldUseGlobalMenuBar();
// Bring the given window to the front and give it the focus.
void MoveWindowToForeground(::Window xwindow);
} // namespace atom
#endif // ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_