summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-24 00:35:12 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-24 00:35:12 +0000
commit6bcd5f36cd94649887eff0c87df4f4496001984a (patch)
tree28de74fe181e53fec448173bb1445062a30ec1e2
parent0704a97d5caa9b7d90d2d9ed39b3db91557a3cb0 (diff)
downloadchromium_src-6bcd5f36cd94649887eff0c87df4f4496001984a.zip
chromium_src-6bcd5f36cd94649887eff0c87df4f4496001984a.tar.gz
chromium_src-6bcd5f36cd94649887eff0c87df4f4496001984a.tar.bz2
The bug is "screen.width/availWidth returns different value with FireFox in Linux dual monitor environment", FireFox uses Xinerama to get screen width/height information. If we cannot use Xinerama, return the same width/height info as before.
BUG=28560 TEST=1, Prepare dual monitor Linux system which can use Xinerama. 2, Launch browser and run javascript "document.write("screen.witdh = " + screen.width + "<br>");". 3, Make sure the width is in single monitor width size. Patch by Takano.Naoki@gmail.com. Original Review: http://codereview.chromium.org/6714036/ Review URL: http://codereview.chromium.org/6725024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79226 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/render_message_filter_gtk.cc115
1 files changed, 89 insertions, 26 deletions
diff --git a/content/browser/renderer_host/render_message_filter_gtk.cc b/content/browser/renderer_host/render_message_filter_gtk.cc
index 8d91b57..163285a 100644
--- a/content/browser/renderer_host/render_message_filter_gtk.cc
+++ b/content/browser/renderer_host/render_message_filter_gtk.cc
@@ -2,35 +2,45 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <dlfcn.h>
+
#include "content/browser/renderer_host/render_message_filter.h"
#include "chrome/common/render_messages.h"
#include "content/browser/browser_thread.h"
#include "content/common/view_messages.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/gtk_native_view_id_manager.h"
+// We want to obey the alphabetical order for including header files, but
+// #define macros in X11 header files affect chrome header files
+// (e.g. Success), so include Xinerama.h here.
+#include <X11/extensions/Xinerama.h>
+
using WebKit::WebScreenInfo;
using WebKit::WebScreenInfoFactory;
-// We get null window_ids passed into the two functions below; please see
-// http://crbug.com/9060 for more details.
+namespace {
-void RenderMessageFilter::DoOnGetScreenInfo(gfx::NativeViewId view,
- IPC::Message* reply_msg) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11));
- Display* display = ui::GetSecondaryDisplay();
- int screen = ui::GetDefaultScreen(display);
- WebScreenInfo results = WebScreenInfoFactory::screenInfo(display, screen);
- ViewHostMsg_GetScreenInfo::WriteReplyParams(reply_msg, results);
- Send(reply_msg);
+// Return the top-level parent of the given window. Called on the
+// BACKGROUND_X11 thread.
+XID GetTopLevelWindow(XID window) {
+ bool parent_is_root;
+ XID parent_window;
+
+ if (!ui::GetWindowParent(&parent_window, &parent_is_root, window))
+ return 0;
+ if (parent_is_root)
+ return window;
+
+ return GetTopLevelWindow(parent_window);
}
-void RenderMessageFilter::DoOnGetWindowRect(gfx::NativeViewId view,
- IPC::Message* reply_msg) {
+gfx::Rect GetWindowRectFromView(gfx::NativeViewId view) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11));
// This is called to get the x, y offset (in screen coordinates) of the given
// view and its width and height.
@@ -46,23 +56,77 @@ void RenderMessageFilter::DoOnGetWindowRect(gfx::NativeViewId view,
rect = gfx::Rect(x, y, width, height);
}
}
-
- ViewHostMsg_GetWindowRect::WriteReplyParams(reply_msg, rect);
- Send(reply_msg);
+ return rect;
}
-// Return the top-level parent of the given window. Called on the
-// BACKGROUND_X11 thread.
-static XID GetTopLevelWindow(XID window) {
- bool parent_is_root;
- XID parent_window;
+} // namespace
- if (!ui::GetWindowParent(&parent_window, &parent_is_root, window))
- return 0;
- if (parent_is_root)
- return window;
+// We get null window_ids passed into the two functions below; please see
+// http://crbug.com/9060 for more details.
- return GetTopLevelWindow(parent_window);
+void RenderMessageFilter::DoOnGetScreenInfo(gfx::NativeViewId view,
+ IPC::Message* reply_msg) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11));
+ Display* display = ui::GetSecondaryDisplay();
+
+ WebScreenInfo results = WebScreenInfoFactory::screenInfo(display,
+ ui::GetDefaultScreen(display));
+
+ // First check if we can use Xinerama.
+ XineramaScreenInfo* screen_info = NULL;
+ int screen_num = 0;
+ void* xinerama_lib = dlopen("libXinerama.so.1", RTLD_LAZY);
+ if (xinerama_lib) {
+ // Prototypes for Xinerama functions.
+ typedef Bool (*XineramaIsActiveFunction)(Display* display);
+ typedef XineramaScreenInfo*
+ (*XineramaQueryScreensFunction)(Display* display, int* num);
+
+ XineramaIsActiveFunction is_active = (XineramaIsActiveFunction)
+ dlsym(xinerama_lib, "XineramaIsActive");
+
+ XineramaQueryScreensFunction query_screens = (XineramaQueryScreensFunction)
+ dlsym(xinerama_lib, "XineramaQueryScreens");
+
+ // Get the number of screens via Xinerama
+ if (is_active && query_screens && is_active(display))
+ screen_info = query_screens(display, &screen_num);
+
+ if (screen_info) {
+ // We can use Xinerama information. Calculate the intersect rect size
+ // between window rect and screen rect, and choose the biggest size.
+ gfx::Rect rect = GetWindowRectFromView(view);
+ int max_intersect_index = 0;
+ for (int i = 0, max_intersect_size = 0; i < screen_num; ++i) {
+ gfx::Rect screen_rect(screen_info[i].x_org, screen_info[i].y_org,
+ screen_info[i].width, screen_info[i].height);
+ gfx::Rect intersect_rect = screen_rect.Intersect(rect);
+ int intersect_size = intersect_rect.width() * intersect_rect.height();
+ if (intersect_size > max_intersect_size) {
+ max_intersect_size = intersect_size;
+ max_intersect_index = i;
+ }
+ }
+ XineramaScreenInfo& target_screen = screen_info[max_intersect_index];
+ results.rect = WebKit::WebRect(target_screen.x_org,
+ target_screen.y_org,
+ target_screen.width,
+ target_screen.height);
+ results.availableRect = results.rect;
+
+ XFree(screen_info);
+ }
+ }
+
+ ViewHostMsg_GetScreenInfo::WriteReplyParams(reply_msg, results);
+ Send(reply_msg);
+}
+
+void RenderMessageFilter::DoOnGetWindowRect(gfx::NativeViewId view,
+ IPC::Message* reply_msg) {
+ ViewHostMsg_GetWindowRect::WriteReplyParams(reply_msg,
+ GetWindowRectFromView(view));
+ Send(reply_msg);
}
void RenderMessageFilter::DoOnGetRootWindowRect(gfx::NativeViewId view,
@@ -116,4 +180,3 @@ void RenderMessageFilter::OnGetRootWindowRect(gfx::NativeViewId view,
NewRunnableMethod(
this, &RenderMessageFilter::DoOnGetRootWindowRect, view, reply_msg));
}
-