diff --git a/webrtc/modules/desktop_capture/window_capturer_x11.cc b/webrtc/modules/desktop_capture/window_capturer_x11.cc index 5a14356fd1..3d51794176 100755 --- a/webrtc/modules/desktop_capture/window_capturer_x11.cc +++ b/webrtc/modules/desktop_capture/window_capturer_x11.cc @@ -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 window_state(display(), window, wm_state_atom_);