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);
};
class WindowCapturerLinux : public WindowCapturer {
class WindowCapturerLinux : public WindowCapturer,
public SharedXDisplay::XEventHandler {
public:
WindowCapturerLinux(const DesktopCaptureOptions& options);
virtual ~WindowCapturerLinux();
@ -97,6 +98,9 @@ class WindowCapturerLinux : public WindowCapturer {
virtual void Start(Callback* callback) OVERRIDE;
virtual void Capture(const DesktopRegion& region) OVERRIDE;
// SharedXDisplay::XEventHandler interface.
virtual bool HandleXEvent(const XEvent& event) OVERRIDE;
private:
Display* display() { return x_display_->display(); }
@ -146,9 +150,13 @@ WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
} else {
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) {
WindowList result;
@ -194,6 +202,9 @@ bool WindowCapturerLinux::SelectWindow(WindowId id) {
if (!x_server_pixel_buffer_.Init(display(), id))
return false;
// Tell the X server to send us window resizing events.
XSelectInput(display(), id, StructureNotifyMask);
selected_window_ = id;
// 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) {
x_display_->ProcessPendingXEvents();
if (!has_composite_extension_) {
// Without the Xcomposite extension we capture when the whole window is
// 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);
}
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) {
// Get WM_STATE property of the window.
XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_);