Adds a method to WindowCapturer to bring a window to the front.
BUG=3071 R=sergeyu@chromium.org Review URL: https://webrtc-codereview.appspot.com/10079004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5718 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
e9793ab8b8
commit
886c94f07c
@ -71,7 +71,7 @@
|
||||
"win/scoped_thread_desktop.h",
|
||||
"window_capturer.cc",
|
||||
"window_capturer.h",
|
||||
"window_capturer_mac.cc",
|
||||
"window_capturer_mac.mm",
|
||||
"window_capturer_win.cc",
|
||||
"window_capturer_x11.cc",
|
||||
"x11/shared_x_display.h",
|
||||
|
@ -49,6 +49,14 @@ class WindowCapturer : public DesktopCapturer {
|
||||
// Select window to be captured. Returns false in case of a failure (e.g. if
|
||||
// there is no window with the specified id).
|
||||
virtual bool SelectWindow(WindowId id) = 0;
|
||||
|
||||
// Bring the selected window to the front. Returns false in case of a
|
||||
// failure or no window selected.
|
||||
// TODO(jiayl): remove the default impl when FakeWindowCapturer is updated in
|
||||
// Chromium.
|
||||
virtual bool BringSelectedWindowToFront() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
39
webrtc/modules/desktop_capture/window_capturer_mac.cc → webrtc/modules/desktop_capture/window_capturer_mac.mm
Executable file → Normal file
39
webrtc/modules/desktop_capture/window_capturer_mac.cc → webrtc/modules/desktop_capture/window_capturer_mac.mm
Executable file → Normal file
@ -12,6 +12,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_frame.h"
|
||||
@ -49,6 +50,7 @@ class WindowCapturerMac : public WindowCapturer {
|
||||
// WindowCapturer interface.
|
||||
virtual bool GetWindowList(WindowList* windows) OVERRIDE;
|
||||
virtual bool SelectWindow(WindowId id) OVERRIDE;
|
||||
virtual bool BringSelectedWindowToFront() OVERRIDE;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
virtual void Start(Callback* callback) OVERRIDE;
|
||||
@ -133,6 +135,43 @@ bool WindowCapturerMac::SelectWindow(WindowId id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerMac::BringSelectedWindowToFront() {
|
||||
if (!window_id_)
|
||||
return false;
|
||||
|
||||
CGWindowID ids[1];
|
||||
ids[0] = window_id_;
|
||||
CFArrayRef window_id_array =
|
||||
CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL);
|
||||
|
||||
CFArrayRef window_array =
|
||||
CGWindowListCreateDescriptionFromArray(window_id_array);
|
||||
if (window_array == NULL || 0 == CFArrayGetCount(window_array)) {
|
||||
// Could not find the window. It might have been closed.
|
||||
LOG(LS_INFO) << "Window not found";
|
||||
CFRelease(window_id_array);
|
||||
return false;
|
||||
}
|
||||
|
||||
CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
|
||||
CFArrayGetValueAtIndex(window_array, 0));
|
||||
CFNumberRef pid_ref = reinterpret_cast<CFNumberRef>(
|
||||
CFDictionaryGetValue(window, kCGWindowOwnerPID));
|
||||
|
||||
int pid;
|
||||
CFNumberGetValue(pid_ref, kCFNumberIntType, &pid);
|
||||
|
||||
// TODO(jiayl): this will bring the process main window to the front. We
|
||||
// should find a way to bring only the window to the front.
|
||||
bool result =
|
||||
[[NSRunningApplication runningApplicationWithProcessIdentifier: pid]
|
||||
activateWithOptions: NSApplicationActivateIgnoringOtherApps];
|
||||
|
||||
CFRelease(window_id_array);
|
||||
CFRelease(window_array);
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowCapturerMac::Start(Callback* callback) {
|
||||
assert(!callback_);
|
||||
assert(callback);
|
@ -26,6 +26,7 @@ class WindowCapturerNull : public WindowCapturer {
|
||||
// WindowCapturer interface.
|
||||
virtual bool GetWindowList(WindowList* windows) OVERRIDE;
|
||||
virtual bool SelectWindow(WindowId id) OVERRIDE;
|
||||
virtual bool BringSelectedWindowToFront() OVERRIDE;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
virtual void Start(Callback* callback) OVERRIDE;
|
||||
@ -54,6 +55,11 @@ bool WindowCapturerNull::SelectWindow(WindowId id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WindowCapturerNull::BringSelectedWindowToFront() {
|
||||
// Not implemented yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
void WindowCapturerNull::Start(Callback* callback) {
|
||||
assert(!callback_);
|
||||
assert(callback);
|
||||
|
@ -89,6 +89,7 @@ class WindowCapturerWin : public WindowCapturer {
|
||||
// WindowCapturer interface.
|
||||
virtual bool GetWindowList(WindowList* windows) OVERRIDE;
|
||||
virtual bool SelectWindow(WindowId id) OVERRIDE;
|
||||
virtual bool BringSelectedWindowToFront() OVERRIDE;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
virtual void Start(Callback* callback) OVERRIDE;
|
||||
@ -157,6 +158,16 @@ bool WindowCapturerWin::SelectWindow(WindowId id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerWin::BringSelectedWindowToFront() {
|
||||
if (!window_)
|
||||
return false;
|
||||
|
||||
if (!IsWindow(window_) || !IsWindowVisible(window_) || IsIconic(window_))
|
||||
return false;
|
||||
|
||||
return SetForegroundWindow(window_) != 0;
|
||||
}
|
||||
|
||||
void WindowCapturerWin::Start(Callback* callback) {
|
||||
assert(!callback_);
|
||||
assert(callback);
|
||||
|
@ -94,6 +94,7 @@ class WindowCapturerLinux : public WindowCapturer,
|
||||
// WindowCapturer interface.
|
||||
virtual bool GetWindowList(WindowList* windows) OVERRIDE;
|
||||
virtual bool SelectWindow(WindowId id) OVERRIDE;
|
||||
virtual bool BringSelectedWindowToFront() OVERRIDE;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
virtual void Start(Callback* callback) OVERRIDE;
|
||||
@ -220,6 +221,55 @@ bool WindowCapturerLinux::SelectWindow(WindowId id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerLinux::BringSelectedWindowToFront() {
|
||||
if (!selected_window_)
|
||||
return false;
|
||||
|
||||
unsigned int num_children;
|
||||
::Window* children;
|
||||
::Window parent;
|
||||
::Window root;
|
||||
// Find the root window to pass event to.
|
||||
int status = XQueryTree(
|
||||
display(), selected_window_, &root, &parent, &children, &num_children);
|
||||
if (status == 0) {
|
||||
LOG(LS_ERROR) << "Failed to query for the root window.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (children)
|
||||
XFree(children);
|
||||
|
||||
XRaiseWindow(display(), selected_window_);
|
||||
|
||||
// Some window managers (e.g., metacity in GNOME) consider it illegal to
|
||||
// raise a window without also giving it input focus with
|
||||
// _NET_ACTIVE_WINDOW, so XRaiseWindow() on its own isn't enough.
|
||||
Atom atom = XInternAtom(display(), "_NET_ACTIVE_WINDOW", True);
|
||||
if (atom != None) {
|
||||
XEvent xev;
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.serial = 0;
|
||||
xev.xclient.send_event = True;
|
||||
xev.xclient.window = selected_window_;
|
||||
xev.xclient.message_type = atom;
|
||||
|
||||
// The format member is set to 8, 16, or 32 and specifies whether the
|
||||
// data should be viewed as a list of bytes, shorts, or longs.
|
||||
xev.xclient.format = 32;
|
||||
|
||||
memset(xev.xclient.data.l, 0, sizeof(xev.xclient.data.l));
|
||||
|
||||
XSendEvent(display(),
|
||||
root,
|
||||
False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
&xev);
|
||||
}
|
||||
XFlush(display());
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowCapturerLinux::Start(Callback* callback) {
|
||||
assert(!callback_);
|
||||
assert(callback);
|
||||
|
Loading…
x
Reference in New Issue
Block a user