10000 feat: implement BrowserWindow.moveTop on X11 by CapOM · Pull Request #16629 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: implement BrowserWindow.moveTop on X11 #16629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions atom/browser/api/atom_api_top_level_window.cc
Original file line number Diff line number Diff line change
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 @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions atom/browser/api/atom_api_top_level_window.h
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
8 changes: 6 additions & 2 deletions atom/browser/native_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions atom/browser/native_window_views.h
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
42 changes: 42 additions & 0 deletions spec/api-browser-window-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,48 @@ describe('BrowserWindow module', () => {
})
})

describe('BrowserWindow.moveTop()', () => {
it('should not steal focus', async () => {
const posDelta = 50
const wShownInactive = emittedOnce(w, 'show')
w.showInactive()
await wShownInactive
assert(!w.isFocused())

const otherWindow = new BrowserWindow({ show: false, title: 'otherWindow' })
const otherWindowShown = emittedOnce(otherWindow, 'show')
otherWindow.loadURL('data:text/html,<html><body background-color: rgba(255,255,255,0)></body></html>')
otherWindow.show()
await otherWindowShown
assert(otherWindow.isFocused())

w.moveTop()
const wPos = w.getPosition()
const wMoving = emittedOnce(w, 'move')
w.setPosition(wPos[0] + posDelta, wPos[1] + posDelta)
await wMoving
assert(!w.isFocused())
assert(otherWindow.isFocused())

const wFocused = emittedOnce(w, 'focus')
w.focus()
await wFocused
assert(w.isFocused())

otherWindow.moveTop()
const otherWindowPos = otherWindow.getPosition()
const otherWindowMoving = emittedOnce(otherWindow, 'move')
otherWindow.setPosition(otherWindowPos[0] + posDelta, otherWindowPos[1] + posDelta)
await otherWindowMoving
assert(!otherWindow.isFocused())
assert(w.isFocused())

await closeWindow(otherWindow, { assertSingleWindow: false }).then(() => {
assert.strictEqual(BrowserWindow.getAllWindows().length, 2) // Test window + w
})
})
})

describe('BrowserWindow.capturePage(rect)', (done) => {
it('returns a Promise with a Buffer', async () => {
const image = await w.capturePage({
Expand Down
0