Skip to content

Commit

Permalink
feat: implement BrowserWindow.moveTop on X11
Browse files Browse the repository at this point in the history
It was implemented on Mac and Win but not on X11.
Tested on Ubuntu 16.04 and 18.04.

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

#12516
  • Loading branch information
Julien Isorce authored and Julien Isorce committed Jan 31, 2019
1 parent c7677b2 commit 9e643f1
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 13 deletions.
4 changes: 0 additions & 4 deletions atom/browser/api/atom_api_top_level_window.cc
Expand Up @@ -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);
Expand Down Expand Up @@ -1062,9 +1060,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)
Expand Down
2 changes: 0 additions & 2 deletions atom/browser/api/atom_api_top_level_window.h
Expand Up @@ -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();
Expand Down
2 changes: 0 additions & 2 deletions atom/browser/native_window.h
Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions atom/browser/native_window_views.cc
Expand Up @@ -635,15 +635,18 @@ void NativeWindowViews::SetResizable(bool resizable) {
resizable_ = resizable;
}

#if defined(OS_WIN)
void NativeWindowViews::MoveTop() {
// TODO: 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)
Expand Down
2 changes: 0 additions & 2 deletions atom/browser/native_window_views.h
Expand Up @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions atom/browser/ui/x/x_window_utils.cc
Expand Up @@ -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
3 changes: 3 additions & 0 deletions atom/browser/ui/x/x_window_utils.h
Expand Up @@ -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_
2 changes: 1 addition & 1 deletion docs/api/browser-window.md
Expand Up @@ -1089,7 +1089,7 @@ can not be focused on.

Returns `Boolean` - Whether the window is always on top of other windows.

#### `win.moveTop()` _macOS_ _Windows_
#### `win.moveTop()`

Moves window to top(z-order) regardless of focus

Expand Down

0 comments on commit 9e643f1

Please sign in to comment.