Make WindowCapturerLinux handling window resize events.

We need to re-initialize the XServerPixelBuffer to the new size
when a window resize event is received.

BUG=https://code.google.com/p/chromium/issues/detail?id=339953
R=sergeyu@chromium.org, wez@chromium.org

Review URL: https://webrtc-codereview.appspot.com/8679004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5578 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
jiayl@webrtc.org 2014-02-19 17:28:41 +00:00
parent 242102517d
commit 97e7a640d8

View File

@ -84,7 +84,8 @@ class XWindowProperty {
DISALLOW_COPY_AND_ASSIGN(XWindowProperty); DISALLOW_COPY_AND_ASSIGN(XWindowProperty);
}; };
class WindowCapturerLinux : public WindowCapturer { class WindowCapturerLinux : public WindowCapturer,
public SharedXDisplay::XEventHandler {
public: public:
WindowCapturerLinux(const DesktopCaptureOptions& options); WindowCapturerLinux(const DesktopCaptureOptions& options);
virtual ~WindowCapturerLinux(); virtual ~WindowCapturerLinux();
@ -97,6 +98,9 @@ class WindowCapturerLinux : public WindowCapturer {
virtual void Start(Callback* callback) OVERRIDE; virtual void Start(Callback* callback) OVERRIDE;
virtual void Capture(const DesktopRegion& region) OVERRIDE; virtual void Capture(const DesktopRegion& region) OVERRIDE;
// SharedXDisplay::XEventHandler interface.
virtual bool HandleXEvent(const XEvent& event) OVERRIDE;
private: private:
Display* display() { return x_display_->display(); } Display* display() { return x_display_->display(); }
@ -146,9 +150,13 @@ WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
} else { } else {
LOG(LS_INFO) << "Xcomposite extension not available or too old."; LOG(LS_INFO) << "Xcomposite extension not available or too old.";
} }
x_display_->AddEventHandler(ConfigureNotify, this);
} }
WindowCapturerLinux::~WindowCapturerLinux() {} WindowCapturerLinux::~WindowCapturerLinux() {
x_display_->RemoveEventHandler(ConfigureNotify, this);
}
bool WindowCapturerLinux::GetWindowList(WindowList* windows) { bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
WindowList result; WindowList result;
@ -194,6 +202,9 @@ bool WindowCapturerLinux::SelectWindow(WindowId id) {
if (!x_server_pixel_buffer_.Init(display(), id)) if (!x_server_pixel_buffer_.Init(display(), id))
return false; return false;
// Tell the X server to send us window resizing events.
XSelectInput(display(), id, StructureNotifyMask);
selected_window_ = id; selected_window_ = id;
// In addition to needing X11 server-side support for Xcomposite, it actually // In addition to needing X11 server-side support for Xcomposite, it actually
@ -216,6 +227,8 @@ void WindowCapturerLinux::Start(Callback* callback) {
} }
void WindowCapturerLinux::Capture(const DesktopRegion& region) { void WindowCapturerLinux::Capture(const DesktopRegion& region) {
x_display_->ProcessPendingXEvents();
if (!has_composite_extension_) { if (!has_composite_extension_) {
// Without the Xcomposite extension we capture when the whole window is // Without the Xcomposite extension we capture when the whole window is
// visible on screen and not covered by any other window. This is not // visible on screen and not covered by any other window. This is not
@ -235,6 +248,20 @@ void WindowCapturerLinux::Capture(const DesktopRegion& region) {
callback_->OnCaptureCompleted(frame); callback_->OnCaptureCompleted(frame);
} }
bool WindowCapturerLinux::HandleXEvent(const XEvent& event) {
if (event.type == ConfigureNotify) {
XConfigureEvent xce = event.xconfigure;
if (!DesktopSize(xce.width, xce.height).equals(
x_server_pixel_buffer_.window_size())) {
if (!x_server_pixel_buffer_.Init(display(), selected_window_)) {
LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing.";
}
return true;
}
}
return false;
}
::Window WindowCapturerLinux::GetApplicationWindow(::Window window) { ::Window WindowCapturerLinux::GetApplicationWindow(::Window window) {
// Get WM_STATE property of the window. // Get WM_STATE property of the window.
XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_); XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_);