OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
6 | 6 |
7 #include <X11/extensions/shape.h> | 7 #include <X11/extensions/shape.h> |
8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
10 #include <X11/Xregion.h> | 10 #include <X11/Xregion.h> |
11 #include <X11/Xutil.h> | 11 #include <X11/Xutil.h> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/command_line.h" |
14 #include "base/debug/trace_event.h" | 15 #include "base/debug/trace_event.h" |
15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
17 #include "third_party/skia/include/core/SkPath.h" | 18 #include "third_party/skia/include/core/SkPath.h" |
18 #include "ui/aura/client/cursor_client.h" | 19 #include "ui/aura/client/cursor_client.h" |
19 #include "ui/aura/client/focus_client.h" | 20 #include "ui/aura/client/focus_client.h" |
20 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
21 #include "ui/aura/window_event_dispatcher.h" | 22 #include "ui/aura/window_event_dispatcher.h" |
22 #include "ui/aura/window_property.h" | 23 #include "ui/aura/window_property.h" |
23 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | 24 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
24 #include "ui/base/hit_test.h" | 25 #include "ui/base/hit_test.h" |
25 #include "ui/base/x/x11_util.h" | 26 #include "ui/base/x/x11_util.h" |
26 #include "ui/events/event_utils.h" | 27 #include "ui/events/event_utils.h" |
27 #include "ui/events/platform/platform_event_source.h" | 28 #include "ui/events/platform/platform_event_source.h" |
28 #include "ui/events/platform/x11/x11_event_source.h" | 29 #include "ui/events/platform/x11/x11_event_source.h" |
29 #include "ui/events/x/device_data_manager.h" | 30 #include "ui/events/x/device_data_manager.h" |
30 #include "ui/events/x/device_list_cache_x.h" | 31 #include "ui/events/x/device_list_cache_x.h" |
31 #include "ui/events/x/touch_factory_x11.h" | 32 #include "ui/events/x/touch_factory_x11.h" |
32 #include "ui/gfx/image/image_skia.h" | 33 #include "ui/gfx/image/image_skia.h" |
33 #include "ui/gfx/image/image_skia_rep.h" | 34 #include "ui/gfx/image/image_skia_rep.h" |
34 #include "ui/gfx/insets.h" | 35 #include "ui/gfx/insets.h" |
35 #include "ui/gfx/path.h" | 36 #include "ui/gfx/path.h" |
36 #include "ui/gfx/path_x11.h" | 37 #include "ui/gfx/path_x11.h" |
37 #include "ui/gfx/screen.h" | 38 #include "ui/gfx/screen.h" |
38 #include "ui/native_theme/native_theme.h" | 39 #include "ui/native_theme/native_theme.h" |
39 #include "ui/views/corewm/tooltip_aura.h" | 40 #include "ui/views/corewm/tooltip_aura.h" |
40 #include "ui/views/ime/input_method.h" | 41 #include "ui/views/ime/input_method.h" |
41 #include "ui/views/linux_ui/linux_ui.h" | 42 #include "ui/views/linux_ui/linux_ui.h" |
42 #include "ui/views/views_delegate.h" | 43 #include "ui/views/views_delegate.h" |
| 44 #include "ui/views/views_switches.h" |
43 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" | 45 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" |
44 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 46 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
45 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 47 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
46 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 48 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
47 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" | 49 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" |
48 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" | 50 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" |
49 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h" | 51 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h" |
50 #include "ui/views/widget/desktop_aura/x11_scoped_capture.h" | 52 #include "ui/views/widget/desktop_aura/x11_scoped_capture.h" |
51 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" | 53 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" |
52 #include "ui/wm/core/compound_event_filter.h" | 54 #include "ui/wm/core/compound_event_filter.h" |
(...skipping 15 matching lines...) Expand all Loading... |
68 | 70 |
69 // Constants that are part of EWMH. | 71 // Constants that are part of EWMH. |
70 const int k_NET_WM_STATE_ADD = 1; | 72 const int k_NET_WM_STATE_ADD = 1; |
71 const int k_NET_WM_STATE_REMOVE = 0; | 73 const int k_NET_WM_STATE_REMOVE = 0; |
72 | 74 |
73 const char* kAtomsToCache[] = { | 75 const char* kAtomsToCache[] = { |
74 "UTF8_STRING", | 76 "UTF8_STRING", |
75 "WM_DELETE_WINDOW", | 77 "WM_DELETE_WINDOW", |
76 "WM_PROTOCOLS", | 78 "WM_PROTOCOLS", |
77 "WM_S0", | 79 "WM_S0", |
| 80 "_NET_WM_CM_S0", |
78 "_NET_WM_ICON", | 81 "_NET_WM_ICON", |
79 "_NET_WM_NAME", | 82 "_NET_WM_NAME", |
80 "_NET_WM_PID", | 83 "_NET_WM_PID", |
81 "_NET_WM_PING", | 84 "_NET_WM_PING", |
82 "_NET_WM_STATE", | 85 "_NET_WM_STATE", |
83 "_NET_WM_STATE_ABOVE", | 86 "_NET_WM_STATE_ABOVE", |
84 "_NET_WM_STATE_FULLSCREEN", | 87 "_NET_WM_STATE_FULLSCREEN", |
85 "_NET_WM_STATE_HIDDEN", | 88 "_NET_WM_STATE_HIDDEN", |
86 "_NET_WM_STATE_MAXIMIZED_HORZ", | 89 "_NET_WM_STATE_MAXIMIZED_HORZ", |
87 "_NET_WM_STATE_MAXIMIZED_VERT", | 90 "_NET_WM_STATE_MAXIMIZED_VERT", |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 DesktopNativeWidgetAura* desktop_native_widget_aura) | 127 DesktopNativeWidgetAura* desktop_native_widget_aura) |
125 : close_widget_factory_(this), | 128 : close_widget_factory_(this), |
126 xdisplay_(gfx::GetXDisplay()), | 129 xdisplay_(gfx::GetXDisplay()), |
127 xwindow_(0), | 130 xwindow_(0), |
128 x_root_window_(DefaultRootWindow(xdisplay_)), | 131 x_root_window_(DefaultRootWindow(xdisplay_)), |
129 atom_cache_(xdisplay_, kAtomsToCache), | 132 atom_cache_(xdisplay_, kAtomsToCache), |
130 window_mapped_(false), | 133 window_mapped_(false), |
131 is_fullscreen_(false), | 134 is_fullscreen_(false), |
132 is_always_on_top_(false), | 135 is_always_on_top_(false), |
133 use_native_frame_(false), | 136 use_native_frame_(false), |
| 137 use_argb_visual_(false), |
134 drag_drop_client_(NULL), | 138 drag_drop_client_(NULL), |
135 current_cursor_(ui::kCursorNull), | 139 current_cursor_(ui::kCursorNull), |
136 native_widget_delegate_(native_widget_delegate), | 140 native_widget_delegate_(native_widget_delegate), |
137 desktop_native_widget_aura_(desktop_native_widget_aura), | 141 desktop_native_widget_aura_(desktop_native_widget_aura), |
138 content_window_(NULL), | 142 content_window_(NULL), |
139 window_parent_(NULL), | 143 window_parent_(NULL), |
140 custom_window_shape_(NULL), | 144 custom_window_shape_(NULL), |
141 urgency_hint_set_(false) { | 145 urgency_hint_set_(false) { |
142 } | 146 } |
143 | 147 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // TODO(erg): Unify this code once the other consumer goes away. | 244 // TODO(erg): Unify this code once the other consumer goes away. |
241 x11_window_event_filter_.reset(new X11WindowEventFilter(this)); | 245 x11_window_event_filter_.reset(new X11WindowEventFilter(this)); |
242 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && | 246 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && |
243 !params.remove_standard_frame); | 247 !params.remove_standard_frame); |
244 desktop_native_widget_aura_->root_window_event_filter()->AddHandler( | 248 desktop_native_widget_aura_->root_window_event_filter()->AddHandler( |
245 x11_window_event_filter_.get()); | 249 x11_window_event_filter_.get()); |
246 | 250 |
247 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); | 251 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); |
248 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); | 252 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); |
249 | 253 |
| 254 SetWindowTransparency(); |
| 255 |
250 native_widget_delegate_->OnNativeWidgetCreated(true); | 256 native_widget_delegate_->OnNativeWidgetCreated(true); |
251 } | 257 } |
252 | 258 |
253 scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostX11::CreateTooltip() { | 259 scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostX11::CreateTooltip() { |
254 return scoped_ptr<corewm::Tooltip>( | 260 return scoped_ptr<corewm::Tooltip>( |
255 new corewm::TooltipAura(gfx::SCREEN_TYPE_NATIVE)); | 261 new corewm::TooltipAura(gfx::SCREEN_TYPE_NATIVE)); |
256 } | 262 } |
257 | 263 |
258 scoped_ptr<aura::client::DragDropClient> | 264 scoped_ptr<aura::client::DragDropClient> |
259 DesktopWindowTreeHostX11::CreateDragDropClient( | 265 DesktopWindowTreeHostX11::CreateDragDropClient( |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 swa.override_redirect = True; | 947 swa.override_redirect = True; |
942 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_DND"); | 948 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_DND"); |
943 break; | 949 break; |
944 default: | 950 default: |
945 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); | 951 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); |
946 break; | 952 break; |
947 } | 953 } |
948 if (swa.override_redirect) | 954 if (swa.override_redirect) |
949 attribute_mask |= CWOverrideRedirect; | 955 attribute_mask |= CWOverrideRedirect; |
950 | 956 |
| 957 // Detect whether we're running inside a compositing manager. If so, try to |
| 958 // use the ARGB visual. Otherwise, just use our parent's visual. |
| 959 Visual* visual = CopyFromParent; |
| 960 int depth = CopyFromParent; |
| 961 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 962 switches::kEnableTransparentVisuals) && |
| 963 XGetSelectionOwner(xdisplay_, |
| 964 atom_cache_.GetAtom("_NET_WM_CM_S0")) != None) { |
| 965 Visual* rgba_visual = GetARGBVisual(); |
| 966 if (rgba_visual) { |
| 967 visual = rgba_visual; |
| 968 depth = 32; |
| 969 |
| 970 attribute_mask |= CWColormap; |
| 971 swa.colormap = XCreateColormap(xdisplay_, x_root_window_, visual, |
| 972 AllocNone); |
| 973 |
| 974 // x.org will BadMatch if we don't set a border when the depth isn't the |
| 975 // same as the parent depth. |
| 976 attribute_mask |= CWBorderPixel; |
| 977 swa.border_pixel = 0; |
| 978 |
| 979 use_argb_visual_ = true; |
| 980 } |
| 981 } |
| 982 |
951 bounds_ = params.bounds; | 983 bounds_ = params.bounds; |
952 xwindow_ = XCreateWindow( | 984 xwindow_ = XCreateWindow( |
953 xdisplay_, x_root_window_, | 985 xdisplay_, x_root_window_, |
954 bounds_.x(), bounds_.y(), | 986 bounds_.x(), bounds_.y(), |
955 bounds_.width(), bounds_.height(), | 987 bounds_.width(), bounds_.height(), |
956 0, // border width | 988 0, // border width |
957 CopyFromParent, // depth | 989 depth, |
958 InputOutput, | 990 InputOutput, |
959 CopyFromParent, // visual | 991 visual, |
960 attribute_mask, | 992 attribute_mask, |
961 &swa); | 993 &swa); |
962 if (ui::PlatformEventSource::GetInstance()) | 994 if (ui::PlatformEventSource::GetInstance()) |
963 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | 995 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
964 open_windows().push_back(xwindow_); | 996 open_windows().push_back(xwindow_); |
965 | 997 |
966 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). | 998 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). |
967 | 999 |
968 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | | 1000 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
969 KeyPressMask | KeyReleaseMask | | 1001 KeyPressMask | KeyReleaseMask | |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 data->push_back(height); | 1263 data->push_back(height); |
1232 | 1264 |
1233 const SkBitmap& bitmap = rep.sk_bitmap(); | 1265 const SkBitmap& bitmap = rep.sk_bitmap(); |
1234 SkAutoLockPixels locker(bitmap); | 1266 SkAutoLockPixels locker(bitmap); |
1235 | 1267 |
1236 for (int y = 0; y < height; ++y) | 1268 for (int y = 0; y < height; ++y) |
1237 for (int x = 0; x < width; ++x) | 1269 for (int x = 0; x < width; ++x) |
1238 data->push_back(bitmap.getColor(x, y)); | 1270 data->push_back(bitmap.getColor(x, y)); |
1239 } | 1271 } |
1240 | 1272 |
| 1273 Visual* DesktopWindowTreeHostX11::GetARGBVisual() { |
| 1274 XVisualInfo visual_template; |
| 1275 visual_template.screen = 0; |
| 1276 Visual* to_return = NULL; |
| 1277 |
| 1278 int visuals_len; |
| 1279 XVisualInfo* visual_list = XGetVisualInfo(xdisplay_, |
| 1280 VisualScreenMask, |
| 1281 &visual_template, &visuals_len); |
| 1282 for (int i = 0; i < visuals_len; ++i) { |
| 1283 // Why support only 8888 ARGB? Because it's all that GTK+ supports. In |
| 1284 // gdkvisual-x11.cc, they look for this specific visual and use it for all |
| 1285 // their alpha channel using needs. |
| 1286 // |
| 1287 // TODO(erg): While the following does find a valid visual, some GL drivers |
| 1288 // don't believe that this has an alpha channel. According to marcheu@, |
| 1289 // this should work on open source driver though. (It doesn't work with |
| 1290 // NVidia's binaries currently.) http://crbug.com/369209 |
| 1291 if (visual_list[i].depth == 32 && |
| 1292 visual_list[i].visual->red_mask == 0xff0000 && |
| 1293 visual_list[i].visual->green_mask == 0x00ff00 && |
| 1294 visual_list[i].visual->blue_mask == 0x0000ff) { |
| 1295 to_return = visual_list[i].visual; |
| 1296 break; |
| 1297 } |
| 1298 } |
| 1299 |
| 1300 if (visual_list) |
| 1301 XFree(visual_list); |
| 1302 |
| 1303 return to_return; |
| 1304 } |
| 1305 |
1241 std::list<XID>& DesktopWindowTreeHostX11::open_windows() { | 1306 std::list<XID>& DesktopWindowTreeHostX11::open_windows() { |
1242 if (!open_windows_) | 1307 if (!open_windows_) |
1243 open_windows_ = new std::list<XID>(); | 1308 open_windows_ = new std::list<XID>(); |
1244 return *open_windows_; | 1309 return *open_windows_; |
1245 } | 1310 } |
1246 | 1311 |
1247 void DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState show_state) { | 1312 void DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState show_state) { |
1248 if (show_state != ui::SHOW_STATE_DEFAULT && | 1313 if (show_state != ui::SHOW_STATE_DEFAULT && |
1249 show_state != ui::SHOW_STATE_NORMAL && | 1314 show_state != ui::SHOW_STATE_NORMAL && |
1250 show_state != ui::SHOW_STATE_INACTIVE) { | 1315 show_state != ui::SHOW_STATE_INACTIVE) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 XMapWindow(xdisplay_, xwindow_); | 1349 XMapWindow(xdisplay_, xwindow_); |
1285 | 1350 |
1286 // We now block until our window is mapped. Some X11 APIs will crash and | 1351 // We now block until our window is mapped. Some X11 APIs will crash and |
1287 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | 1352 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is |
1288 // asynchronous. | 1353 // asynchronous. |
1289 if (ui::X11EventSource::GetInstance()) | 1354 if (ui::X11EventSource::GetInstance()) |
1290 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); | 1355 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); |
1291 window_mapped_ = true; | 1356 window_mapped_ = true; |
1292 } | 1357 } |
1293 | 1358 |
| 1359 void DesktopWindowTreeHostX11::SetWindowTransparency() { |
| 1360 compositor()->SetHostHasTransparentBackground(use_argb_visual_); |
| 1361 window()->SetTransparent(use_argb_visual_); |
| 1362 content_window_->SetTransparent(use_argb_visual_); |
| 1363 } |
| 1364 |
1294 //////////////////////////////////////////////////////////////////////////////// | 1365 //////////////////////////////////////////////////////////////////////////////// |
1295 // DesktopWindowTreeHostX11, ui::PlatformEventDispatcher implementation: | 1366 // DesktopWindowTreeHostX11, ui::PlatformEventDispatcher implementation: |
1296 | 1367 |
1297 bool DesktopWindowTreeHostX11::CanDispatchEvent( | 1368 bool DesktopWindowTreeHostX11::CanDispatchEvent( |
1298 const ui::PlatformEvent& event) { | 1369 const ui::PlatformEvent& event) { |
1299 return event->xany.window == xwindow_ || | 1370 return event->xany.window == xwindow_ || |
1300 (event->type == GenericEvent && | 1371 (event->type == GenericEvent && |
1301 static_cast<XIDeviceEvent*>(event->xcookie.data)->event == xwindow_); | 1372 static_cast<XIDeviceEvent*>(event->xcookie.data)->event == xwindow_); |
1302 } | 1373 } |
1303 | 1374 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 if (linux_ui) { | 1683 if (linux_ui) { |
1613 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 1684 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
1614 if (native_theme) | 1685 if (native_theme) |
1615 return native_theme; | 1686 return native_theme; |
1616 } | 1687 } |
1617 | 1688 |
1618 return ui::NativeTheme::instance(); | 1689 return ui::NativeTheme::instance(); |
1619 } | 1690 } |
1620 | 1691 |
1621 } // namespace views | 1692 } // namespace views |
OLD | NEW |