Commit 74d064b2 authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

[XProto] Remove usage of XRRUpdateConfiguration and XRandR

Since we never initialize the libxrandr (by calling XRRQueryVersion),
Xlib cannot decode the incoming randr notify events.  This causes a
crash in XRRUpdateConfiguration.

This CL solves the issue by removing all calls to
XRRUpdateConfiguration, which updates the XDisplay screen dimensions.
This data is only used in the following APIs:

XDisplayWidth
XDisplayHeight
XDisplayCells
XDisplayWidthMM
XDisplayHeightMM
XWidthOfScreen
XHeightOfScreen
XWidthMMOfScreen
XHeightMMOfScreen
DisplayWidth
DisplayHeight
DisplayCells
DisplayWidthMM
DisplayHeightMM
WidthOfScreen
HeightOfScreen
WidthMMOfScreen
HeightMMOfScreen

Therefore, this CL also adds a PRESUBMIT check to ensure they aren't
being used.

Since this is the last usage of libxrandr, the build config for it is
removed.

R=nickdiego,sky

Bug: 1102059
Change-Id: Ib60811259ae23ffa8af9c50e0bb3d4ac2158e5af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2285068
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: default avatarNick Yamane <nickdiego@igalia.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarLambros Lambrou <lambroslambrou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786148}
parent def0fa3e
...@@ -452,6 +452,14 @@ _BANNED_CPP_FUNCTIONS = ( ...@@ -452,6 +452,14 @@ _BANNED_CPP_FUNCTIONS = (
r"^ui[\\/]base[\\/]x[\\/]xwmstartupcheck[\\/]xwmstartupcheck\.cc$", r"^ui[\\/]base[\\/]x[\\/]xwmstartupcheck[\\/]xwmstartupcheck\.cc$",
), ),
), ),
(
r'/\WX?(((Width|Height)(MM)?OfScreen)|(Display(Width|Height)))\(',
(
'Use the corresponding fields in x11::Screen instead.',
),
True,
(),
),
( (
r'/XInternAtom|xcb_intern_atom', r'/XInternAtom|xcb_intern_atom',
( (
......
...@@ -60,10 +60,6 @@ config("xext") { ...@@ -60,10 +60,6 @@ config("xext") {
libs = [ "Xext" ] libs = [ "Xext" ]
} }
config("xrandr") {
libs = [ "Xrandr" ]
}
config("xfixes") { config("xfixes") {
libs = [ "Xfixes" ] libs = [ "Xfixes" ]
} }
......
...@@ -111,7 +111,8 @@ class ScreenResources { ...@@ -111,7 +111,8 @@ class ScreenResources {
std::unique_ptr<x11::RandR::GetScreenResourcesCurrentReply> resources_; std::unique_ptr<x11::RandR::GetScreenResourcesCurrentReply> resources_;
}; };
class DesktopResizerX11 : public DesktopResizer { class DesktopResizerX11 : public DesktopResizer,
public x11::Connection::Delegate {
public: public:
DesktopResizerX11(); DesktopResizerX11();
~DesktopResizerX11() override; ~DesktopResizerX11() override;
...@@ -124,6 +125,10 @@ class DesktopResizerX11 : public DesktopResizer { ...@@ -124,6 +125,10 @@ class DesktopResizerX11 : public DesktopResizer {
void RestoreResolution(const ScreenResolution& original) override; void RestoreResolution(const ScreenResolution& original) override;
private: private:
// x11::Connection::Delegate:
bool ShouldContinueStream() const override;
void DispatchXEvent(x11::Event* event) override;
// Add a mode matching the specified resolution and switch to it. // Add a mode matching the specified resolution and switch to it.
void SetResolutionNewMode(const ScreenResolution& resolution); void SetResolutionNewMode(const ScreenResolution& resolution);
...@@ -174,28 +179,14 @@ DesktopResizerX11::DesktopResizerX11() ...@@ -174,28 +179,14 @@ DesktopResizerX11::DesktopResizerX11()
DesktopResizerX11::~DesktopResizerX11() = default; DesktopResizerX11::~DesktopResizerX11() = default;
ScreenResolution DesktopResizerX11::GetCurrentResolution() { ScreenResolution DesktopResizerX11::GetCurrentResolution() {
// Xrandr requires that we process RRScreenChangeNotify events, otherwise // Process pending events so that the connection setup data is updated
// DisplayWidth and DisplayHeight do not return the current values. Normally, // with the correct display metrics.
// this would be done via a central X event loop, but we don't have one, hence if (has_randr_)
// this horrible hack. connection_.Dispatch(this);
//
// Note that the WatchFileDescriptor approach taken in XServerClipboard
// doesn't work here because resize events have already been read from the
// X server socket by the time the resize function returns, hence the
// file descriptor is never seen as readable.
if (has_randr_) {
while (XEventsQueued(connection_.display(), QueuedAlready)) {
XEvent event;
XNextEvent(connection_.display(), &event);
XRRUpdateConfiguration(&event);
}
}
ScreenResolution result( ScreenResolution result(
webrtc::DesktopSize(DisplayWidth(connection_.display(), webrtc::DesktopSize(connection_.default_screen().width_in_pixels,
DefaultScreen(connection_.display())), connection_.default_screen().height_in_pixels),
DisplayHeight(connection_.display(),
DefaultScreen(connection_.display()))),
webrtc::DesktopVector(kDefaultDPI, kDefaultDPI)); webrtc::DesktopVector(kDefaultDPI, kDefaultDPI));
return result; return result;
} }
...@@ -257,6 +248,12 @@ void DesktopResizerX11::RestoreResolution(const ScreenResolution& original) { ...@@ -257,6 +248,12 @@ void DesktopResizerX11::RestoreResolution(const ScreenResolution& original) {
SetResolution(original); SetResolution(original);
} }
bool DesktopResizerX11::ShouldContinueStream() const {
return true;
}
void DesktopResizerX11::DispatchXEvent(x11::Event* event) {}
void DesktopResizerX11::SetResolutionNewMode( void DesktopResizerX11::SetResolutionNewMode(
const ScreenResolution& resolution) { const ScreenResolution& resolution) {
// The name of the mode representing the current client view resolution and // The name of the mode representing the current client view resolution and
......
...@@ -65,8 +65,6 @@ jumbo_component("x") { ...@@ -65,8 +65,6 @@ jumbo_component("x") {
] ]
} }
public_configs = [ "//build/config/linux:xrandr" ]
defines = [ "IS_UI_BASE_X_IMPL" ] defines = [ "IS_UI_BASE_X_IMPL" ]
deps = [ deps = [
......
...@@ -64,12 +64,6 @@ void XDisplayManager::RemoveObserver(display::DisplayObserver* observer) { ...@@ -64,12 +64,6 @@ void XDisplayManager::RemoveObserver(display::DisplayObserver* observer) {
bool XDisplayManager::ProcessEvent(x11::Event* xev) { bool XDisplayManager::ProcessEvent(x11::Event* xev) {
DCHECK(xev); DCHECK(xev);
if (xev->As<x11::RandR::ScreenChangeNotifyEvent>()) {
// TODO(https://crbug.com/1102059): Remove this since the Xlib even is
// nullptr since we don't initialize the extension, which causes a crash.
XRRUpdateConfiguration(&xev->xlib_event());
return true;
}
auto* prop = xev->As<x11::PropertyNotifyEvent>(); auto* prop = xev->As<x11::PropertyNotifyEvent>();
if (xev->As<x11::RandR::NotifyEvent>() || if (xev->As<x11::RandR::NotifyEvent>() ||
(prop && prop->atom == gfx::GetAtom("_NET_WORKAREA"))) { (prop && prop->atom == gfx::GetAtom("_NET_WORKAREA"))) {
......
...@@ -1266,15 +1266,12 @@ bool IsX11WindowFullScreen(x11::Window window) { ...@@ -1266,15 +1266,12 @@ bool IsX11WindowFullScreen(x11::Window window) {
if (!ui::GetOuterWindowBounds(window, &window_rect)) if (!ui::GetOuterWindowBounds(window, &window_rect))
return false; return false;
// We can't use display::Screen here because we don't have an aura::Window. So // TODO(thomasanderson): We should use
// instead just look at the size of the default display. // display::Screen::GetDisplayNearestWindow() instead of using the
// // connection screen size, which encompasses all displays.
// TODO(erg): Actually doing this correctly would require pulling out xrandr, auto* connection = x11::Connection::Get();
// which we don't even do in the desktop screen yet. int width = connection->default_screen().width_in_pixels;
::XDisplay* display = gfx::GetXDisplay(); int height = connection->default_screen().height_in_pixels;
::Screen* screen = DefaultScreenOfDisplay(display);
int width = WidthOfScreen(screen);
int height = HeightOfScreen(screen);
return window_rect.size() == gfx::Size(width, height); return window_rect.size() == gfx::Size(width, height);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "ui/gfx/x/bigreq.h" #include "ui/gfx/x/bigreq.h"
#include "ui/gfx/x/event.h" #include "ui/gfx/x/event.h"
#include "ui/gfx/x/randr.h"
#include "ui/gfx/x/x11_switches.h" #include "ui/gfx/x/x11_switches.h"
#include "ui/gfx/x/xproto_internal.h" #include "ui/gfx/x/xproto_internal.h"
#include "ui/gfx/x/xproto_types.h" #include "ui/gfx/x/xproto_types.h"
...@@ -171,6 +172,7 @@ void Connection::Dispatch(Delegate* delegate) { ...@@ -171,6 +172,7 @@ void Connection::Dispatch(Delegate* delegate) {
Event event = std::move(events_.front()); Event event = std::move(events_.front());
events_.pop_front(); events_.pop_front();
PreDispatchEvent(event);
delegate->DispatchXEvent(&event); delegate->DispatchXEvent(&event);
}; };
...@@ -213,4 +215,40 @@ void Connection::AddRequest(unsigned int sequence, ...@@ -213,4 +215,40 @@ void Connection::AddRequest(unsigned int sequence,
requests_.emplace(sequence, std::move(callback)); requests_.emplace(sequence, std::move(callback));
} }
void Connection::PreDispatchEvent(const Event& event) {
// This is adapted from XRRUpdateConfiguration.
if (auto* configure = event.As<x11::ConfigureNotifyEvent>()) {
int index = ScreenIndexFromRootWindow(configure->window);
if (index != -1) {
setup_.roots[index].width_in_pixels = configure->width;
setup_.roots[index].height_in_pixels = configure->height;
}
} else if (auto* screen = event.As<x11::RandR::ScreenChangeNotifyEvent>()) {
int index = ScreenIndexFromRootWindow(configure->window);
DCHECK_GE(index, 0);
bool portrait = static_cast<bool>(
screen->rotation &
(x11::RandR::Rotation::Rotate_90 | x11::RandR::Rotation::Rotate_270));
if (portrait) {
setup_.roots[index].width_in_pixels = screen->height;
setup_.roots[index].height_in_pixels = screen->width;
setup_.roots[index].width_in_millimeters = screen->mheight;
setup_.roots[index].height_in_millimeters = screen->mwidth;
} else {
setup_.roots[index].width_in_pixels = screen->width;
setup_.roots[index].height_in_pixels = screen->height;
setup_.roots[index].width_in_millimeters = screen->mwidth;
setup_.roots[index].height_in_millimeters = screen->mheight;
}
}
}
int Connection::ScreenIndexFromRootWindow(x11::Window root) const {
for (size_t i = 0; i < setup_.roots.size(); i++) {
if (setup_.roots[i].root == root)
return i;
}
return -1;
}
} // namespace x11 } // namespace x11
...@@ -96,6 +96,10 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, ...@@ -96,6 +96,10 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
bool HasNextResponse() const; bool HasNextResponse() const;
void PreDispatchEvent(const Event& event);
int ScreenIndexFromRootWindow(x11::Window root) const;
XDisplay* const display_; XDisplay* const display_;
uint32_t extended_max_request_length_ = 0; uint32_t extended_max_request_length_ = 0;
......
...@@ -31,7 +31,6 @@ extern "C" { ...@@ -31,7 +31,6 @@ extern "C" {
#include <X11/extensions/XShm.h> #include <X11/extensions/XShm.h>
#include <X11/extensions/XTest.h> #include <X11/extensions/XTest.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/Xrender.h> #include <X11/extensions/Xrender.h>
#include <X11/extensions/record.h> #include <X11/extensions/record.h>
#include <X11/extensions/sync.h> #include <X11/extensions/sync.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment