1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/browser/renderer_host/gtk_window_utils.h" 6 7 #include <X11/Xlib.h> 8 #include <gdk/gdkx.h> 9 #include <gtk/gtk.h> 10 11 #include <vector> 12 13 #include "ui/base/gtk/gtk_compat.h" 14 #include "ui/base/x/x11_util.h" 15 #include "ui/gfx/rect.h" 16 #include "third_party/WebKit/public/web/WebScreenInfo.h" 17 18 namespace content { 19 20 namespace { 21 22 // Returns the region of |window|'s desktop that isn't occupied by docks or 23 // panels. Returns an empty rect on failure. 24 gfx::Rect GetWorkArea(Window window) { 25 Window root = ui::GetX11RootWindow(); 26 int desktop = -1; 27 if (!ui::GetIntProperty(window, "_NET_WM_DESKTOP", &desktop)) { 28 // Hack for ion3: _NET_WM_DESKTOP doesn't get set on individual windows, but 29 // _NET_CURRENT_DESKTOP and _NET_WORKAREA do get set. 30 ui::GetIntProperty(root, "_NET_CURRENT_DESKTOP", &desktop); 31 } 32 if (desktop < 0) 33 return gfx::Rect(); 34 35 std::vector<int> property; 36 if (!ui::GetIntArrayProperty(root, "_NET_WORKAREA", &property)) 37 return gfx::Rect(); 38 39 size_t start_index = 4 * desktop; 40 if (property.size() < start_index + 4) 41 return gfx::Rect(); 42 43 return gfx::Rect(property[start_index], property[start_index + 1], 44 property[start_index + 2], property[start_index + 3]); 45 } 46 47 WebKit::WebScreenInfo GetScreenInfo(Display* display, int screenNumber) { 48 // XDisplayWidth() and XDisplayHeight() return cached values. To ensure that 49 // we return the correct dimensions after the screen is resized, query the 50 // root window's geometry each time. 51 Window root = RootWindow(display, screenNumber); 52 Window root_ret; 53 int x, y; 54 unsigned int width, height, border, depth; 55 XGetGeometry( 56 display, root, &root_ret, &x, &y, &width, &height, &border, &depth); 57 58 WebKit::WebScreenInfo results; 59 results.depthPerComponent = 8; // Assume 8bpp, which is usually right. 60 results.depth = depth; 61 results.isMonochrome = depth == 1; 62 results.rect = WebKit::WebRect(x, y, width, height); 63 results.availableRect = results.rect; 64 return results; 65 } 66 67 } // namespace 68 69 void GetScreenInfoFromNativeWindow( 70 GdkWindow* gdk_window, WebKit::WebScreenInfo* results) { 71 GdkScreen* screen = gdk_window_get_screen(gdk_window); 72 *results = GetScreenInfo(gdk_x11_drawable_get_xdisplay(gdk_window), 73 gdk_x11_screen_get_screen_number(screen)); 74 75 int monitor_number = gdk_screen_get_monitor_at_window(screen, gdk_window); 76 GdkRectangle monitor_rect; 77 gdk_screen_get_monitor_geometry(screen, monitor_number, &monitor_rect); 78 results->rect = WebKit::WebRect(monitor_rect.x, monitor_rect.y, 79 monitor_rect.width, monitor_rect.height); 80 81 gfx::Rect available_rect = results->rect; 82 gfx::Rect work_area = GetWorkArea(GDK_WINDOW_XID(gdk_window)); 83 if (!work_area.IsEmpty()) 84 available_rect.Intersect(work_area); 85 results->availableRect = available_rect; 86 } 87 88 } // namespace content 89