| 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 // This file defines utility functions for X11 (Linux only). This code has been | 5 // This file defines utility functions for X11 (Linux only). This code has been |
| 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support | 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support |
| 7 // remains woefully incomplete. | 7 // remains woefully incomplete. |
| 8 | 8 |
| 9 #include "ui/base/x/x11_util.h" | 9 #include "ui/base/x/x11_util.h" |
| 10 | 10 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 int DefaultX11IOErrorHandler(XDisplay* d) { | 87 int DefaultX11IOErrorHandler(XDisplay* d) { |
| 88 // If there's an IO error it likely means the X server has gone away | 88 // If there's an IO error it likely means the X server has gone away |
| 89 LOG(ERROR) << "X IO error received (X server probably went away)"; | 89 LOG(ERROR) << "X IO error received (X server probably went away)"; |
| 90 _exit(1); | 90 _exit(1); |
| 91 } | 91 } |
| 92 | 92 |
| 93 // Note: The caller should free the resulting value data. | 93 // Note: The caller should free the resulting value data. |
| 94 bool GetProperty(XID window, const std::string& property_name, long max_length, | 94 bool GetProperty(XID window, const std::string& property_name, long max_length, |
| 95 XAtom* type, int* format, unsigned long* num_items, | 95 XAtom* type, int* format, unsigned long* num_items, |
| 96 unsigned char** property) { | 96 unsigned char** property) { |
| 97 XAtom property_atom = GetAtom(property_name.c_str()); | 97 XAtom property_atom = gfx::GetAtom(property_name.c_str()); |
| 98 unsigned long remaining_bytes = 0; | 98 unsigned long remaining_bytes = 0; |
| 99 return XGetWindowProperty(gfx::GetXDisplay(), | 99 return XGetWindowProperty(gfx::GetXDisplay(), |
| 100 window, | 100 window, |
| 101 property_atom, | 101 property_atom, |
| 102 0, // offset into property data to read | 102 0, // offset into property data to read |
| 103 max_length, // max length to get | 103 max_length, // max length to get |
| 104 False, // deleted | 104 False, // deleted |
| 105 AnyPropertyType, | 105 AnyPropertyType, |
| 106 type, | 106 type, |
| 107 format, | 107 format, |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 unsigned long status; | 435 unsigned long status; |
| 436 } MotifWmHints; | 436 } MotifWmHints; |
| 437 | 437 |
| 438 MotifWmHints motif_hints; | 438 MotifWmHints motif_hints; |
| 439 memset(&motif_hints, 0, sizeof(motif_hints)); | 439 memset(&motif_hints, 0, sizeof(motif_hints)); |
| 440 // Signals that the reader of the _MOTIF_WM_HINTS property should pay | 440 // Signals that the reader of the _MOTIF_WM_HINTS property should pay |
| 441 // attention to the value of |decorations|. | 441 // attention to the value of |decorations|. |
| 442 motif_hints.flags = (1L << 1); | 442 motif_hints.flags = (1L << 1); |
| 443 motif_hints.decorations = use_os_window_frame ? 1 : 0; | 443 motif_hints.decorations = use_os_window_frame ? 1 : 0; |
| 444 | 444 |
| 445 XAtom hint_atom = GetAtom("_MOTIF_WM_HINTS"); | 445 XAtom hint_atom = gfx::GetAtom("_MOTIF_WM_HINTS"); |
| 446 XChangeProperty(gfx::GetXDisplay(), | 446 XChangeProperty(gfx::GetXDisplay(), |
| 447 window, | 447 window, |
| 448 hint_atom, | 448 hint_atom, |
| 449 hint_atom, | 449 hint_atom, |
| 450 32, | 450 32, |
| 451 PropModeReplace, | 451 PropModeReplace, |
| 452 reinterpret_cast<unsigned char*>(&motif_hints), | 452 reinterpret_cast<unsigned char*>(&motif_hints), |
| 453 sizeof(MotifWmHints)/sizeof(long)); | 453 sizeof(MotifWmHints)/sizeof(long)); |
| 454 } | 454 } |
| 455 | 455 |
| 456 bool IsShapeExtensionAvailable() { | 456 bool IsShapeExtensionAvailable() { |
| 457 int dummy; | 457 int dummy; |
| 458 static bool is_shape_available = | 458 static bool is_shape_available = |
| 459 XShapeQueryExtension(gfx::GetXDisplay(), &dummy, &dummy); | 459 XShapeQueryExtension(gfx::GetXDisplay(), &dummy, &dummy); |
| 460 return is_shape_available; | 460 return is_shape_available; |
| 461 } | 461 } |
| 462 | 462 |
| 463 XID GetX11RootWindow() { | 463 XID GetX11RootWindow() { |
| 464 return DefaultRootWindow(gfx::GetXDisplay()); | 464 return DefaultRootWindow(gfx::GetXDisplay()); |
| 465 } | 465 } |
| 466 | 466 |
| 467 bool GetCurrentDesktop(int* desktop) { | 467 bool GetCurrentDesktop(int* desktop) { |
| 468 return GetIntProperty(GetX11RootWindow(), "_NET_CURRENT_DESKTOP", desktop); | 468 return GetIntProperty(GetX11RootWindow(), "_NET_CURRENT_DESKTOP", desktop); |
| 469 } | 469 } |
| 470 | 470 |
| 471 void SetHideTitlebarWhenMaximizedProperty(XID window, | 471 void SetHideTitlebarWhenMaximizedProperty(XID window, |
| 472 HideTitlebarWhenMaximized property) { | 472 HideTitlebarWhenMaximized property) { |
| 473 // XChangeProperty() expects "hide" to be long. | 473 // XChangeProperty() expects "hide" to be long. |
| 474 unsigned long hide = property; | 474 unsigned long hide = property; |
| 475 XChangeProperty(gfx::GetXDisplay(), | 475 XChangeProperty(gfx::GetXDisplay(), window, |
| 476 window, | 476 gfx::GetAtom("_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"), |
| 477 GetAtom("_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"), | 477 XA_CARDINAL, |
| 478 XA_CARDINAL, | 478 32, // size in bits |
| 479 32, // size in bits | 479 PropModeReplace, reinterpret_cast<unsigned char*>(&hide), 1); |
| 480 PropModeReplace, | |
| 481 reinterpret_cast<unsigned char*>(&hide), | |
| 482 1); | |
| 483 } | 480 } |
| 484 | 481 |
| 485 void ClearX11DefaultRootWindow() { | 482 void ClearX11DefaultRootWindow() { |
| 486 XDisplay* display = gfx::GetXDisplay(); | 483 XDisplay* display = gfx::GetXDisplay(); |
| 487 XID root_window = GetX11RootWindow(); | 484 XID root_window = GetX11RootWindow(); |
| 488 gfx::Rect root_bounds; | 485 gfx::Rect root_bounds; |
| 489 if (!GetOuterWindowBounds(root_window, &root_bounds)) { | 486 if (!GetOuterWindowBounds(root_window, &root_bounds)) { |
| 490 LOG(ERROR) << "Failed to get the bounds of the X11 root window"; | 487 LOG(ERROR) << "Failed to get the bounds of the X11 root window"; |
| 491 return; | 488 return; |
| 492 } | 489 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 507 | 504 |
| 508 XWindowAttributes win_attributes; | 505 XWindowAttributes win_attributes; |
| 509 if (!XGetWindowAttributes(gfx::GetXDisplay(), window, &win_attributes)) | 506 if (!XGetWindowAttributes(gfx::GetXDisplay(), window, &win_attributes)) |
| 510 return false; | 507 return false; |
| 511 if (win_attributes.map_state != IsViewable) | 508 if (win_attributes.map_state != IsViewable) |
| 512 return false; | 509 return false; |
| 513 | 510 |
| 514 // Minimized windows are not visible. | 511 // Minimized windows are not visible. |
| 515 std::vector<XAtom> wm_states; | 512 std::vector<XAtom> wm_states; |
| 516 if (GetAtomArrayProperty(window, "_NET_WM_STATE", &wm_states)) { | 513 if (GetAtomArrayProperty(window, "_NET_WM_STATE", &wm_states)) { |
| 517 XAtom hidden_atom = GetAtom("_NET_WM_STATE_HIDDEN"); | 514 XAtom hidden_atom = gfx::GetAtom("_NET_WM_STATE_HIDDEN"); |
| 518 if (base::ContainsValue(wm_states, hidden_atom)) | 515 if (base::ContainsValue(wm_states, hidden_atom)) |
| 519 return false; | 516 return false; |
| 520 } | 517 } |
| 521 | 518 |
| 522 // Some compositing window managers (notably kwin) do not actually unmap | 519 // Some compositing window managers (notably kwin) do not actually unmap |
| 523 // windows on desktop switch, so we also must check the current desktop. | 520 // windows on desktop switch, so we also must check the current desktop. |
| 524 int window_desktop, current_desktop; | 521 int window_desktop, current_desktop; |
| 525 return (!GetWindowDesktop(window, &window_desktop) || | 522 return (!GetWindowDesktop(window, &window_desktop) || |
| 526 !GetCurrentDesktop(¤t_desktop) || | 523 !GetCurrentDesktop(¤t_desktop) || |
| 527 window_desktop == kAllDesktops || | 524 window_desktop == kAllDesktops || |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 int value) { | 815 int value) { |
| 819 std::vector<int> values(1, value); | 816 std::vector<int> values(1, value); |
| 820 return SetIntArrayProperty(window, name, type, values); | 817 return SetIntArrayProperty(window, name, type, values); |
| 821 } | 818 } |
| 822 | 819 |
| 823 bool SetIntArrayProperty(XID window, | 820 bool SetIntArrayProperty(XID window, |
| 824 const std::string& name, | 821 const std::string& name, |
| 825 const std::string& type, | 822 const std::string& type, |
| 826 const std::vector<int>& value) { | 823 const std::vector<int>& value) { |
| 827 DCHECK(!value.empty()); | 824 DCHECK(!value.empty()); |
| 828 XAtom name_atom = GetAtom(name.c_str()); | 825 XAtom name_atom = gfx::GetAtom(name.c_str()); |
| 829 XAtom type_atom = GetAtom(type.c_str()); | 826 XAtom type_atom = gfx::GetAtom(type.c_str()); |
| 830 | 827 |
| 831 // XChangeProperty() expects values of type 32 to be longs. | 828 // XChangeProperty() expects values of type 32 to be longs. |
| 832 std::unique_ptr<long[]> data(new long[value.size()]); | 829 std::unique_ptr<long[]> data(new long[value.size()]); |
| 833 for (size_t i = 0; i < value.size(); ++i) | 830 for (size_t i = 0; i < value.size(); ++i) |
| 834 data[i] = value[i]; | 831 data[i] = value[i]; |
| 835 | 832 |
| 836 gfx::X11ErrorTracker err_tracker; | 833 gfx::X11ErrorTracker err_tracker; |
| 837 XChangeProperty(gfx::GetXDisplay(), | 834 XChangeProperty(gfx::GetXDisplay(), |
| 838 window, | 835 window, |
| 839 name_atom, | 836 name_atom, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 851 XAtom value) { | 848 XAtom value) { |
| 852 std::vector<XAtom> values(1, value); | 849 std::vector<XAtom> values(1, value); |
| 853 return SetAtomArrayProperty(window, name, type, values); | 850 return SetAtomArrayProperty(window, name, type, values); |
| 854 } | 851 } |
| 855 | 852 |
| 856 bool SetAtomArrayProperty(XID window, | 853 bool SetAtomArrayProperty(XID window, |
| 857 const std::string& name, | 854 const std::string& name, |
| 858 const std::string& type, | 855 const std::string& type, |
| 859 const std::vector<XAtom>& value) { | 856 const std::vector<XAtom>& value) { |
| 860 DCHECK(!value.empty()); | 857 DCHECK(!value.empty()); |
| 861 XAtom name_atom = GetAtom(name.c_str()); | 858 XAtom name_atom = gfx::GetAtom(name.c_str()); |
| 862 XAtom type_atom = GetAtom(type.c_str()); | 859 XAtom type_atom = gfx::GetAtom(type.c_str()); |
| 863 | 860 |
| 864 // XChangeProperty() expects values of type 32 to be longs. | 861 // XChangeProperty() expects values of type 32 to be longs. |
| 865 std::unique_ptr<XAtom[]> data(new XAtom[value.size()]); | 862 std::unique_ptr<XAtom[]> data(new XAtom[value.size()]); |
| 866 for (size_t i = 0; i < value.size(); ++i) | 863 for (size_t i = 0; i < value.size(); ++i) |
| 867 data[i] = value[i]; | 864 data[i] = value[i]; |
| 868 | 865 |
| 869 gfx::X11ErrorTracker err_tracker; | 866 gfx::X11ErrorTracker err_tracker; |
| 870 XChangeProperty(gfx::GetXDisplay(), | 867 XChangeProperty(gfx::GetXDisplay(), |
| 871 window, | 868 window, |
| 872 name_atom, | 869 name_atom, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 887 window, | 884 window, |
| 888 property, | 885 property, |
| 889 type, | 886 type, |
| 890 8, | 887 8, |
| 891 PropModeReplace, | 888 PropModeReplace, |
| 892 reinterpret_cast<const unsigned char*>(value.c_str()), | 889 reinterpret_cast<const unsigned char*>(value.c_str()), |
| 893 value.size()); | 890 value.size()); |
| 894 return !err_tracker.FoundNewError(); | 891 return !err_tracker.FoundNewError(); |
| 895 } | 892 } |
| 896 | 893 |
| 897 XAtom GetAtom(const char* name) { | |
| 898 return X11AtomCache::GetInstance()->GetAtom(name); | |
| 899 } | |
| 900 | |
| 901 void SetWindowClassHint(XDisplay* display, | 894 void SetWindowClassHint(XDisplay* display, |
| 902 XID window, | 895 XID window, |
| 903 const std::string& res_name, | 896 const std::string& res_name, |
| 904 const std::string& res_class) { | 897 const std::string& res_class) { |
| 905 XClassHint class_hints; | 898 XClassHint class_hints; |
| 906 // const_cast is safe because XSetClassHint does not modify the strings. | 899 // const_cast is safe because XSetClassHint does not modify the strings. |
| 907 // Just to be safe, the res_name and res_class parameters are local copies, | 900 // Just to be safe, the res_name and res_class parameters are local copies, |
| 908 // not const references. | 901 // not const references. |
| 909 class_hints.res_name = const_cast<char*>(res_name.c_str()); | 902 class_hints.res_name = const_cast<char*>(res_name.c_str()); |
| 910 class_hints.res_class = const_cast<char*>(res_class.c_str()); | 903 class_hints.res_class = const_cast<char*>(res_class.c_str()); |
| 911 XSetClassHint(display, window, &class_hints); | 904 XSetClassHint(display, window, &class_hints); |
| 912 } | 905 } |
| 913 | 906 |
| 914 void SetWindowRole(XDisplay* display, XID window, const std::string& role) { | 907 void SetWindowRole(XDisplay* display, XID window, const std::string& role) { |
| 915 if (role.empty()) { | 908 if (role.empty()) { |
| 916 XDeleteProperty(display, window, GetAtom("WM_WINDOW_ROLE")); | 909 XDeleteProperty(display, window, gfx::GetAtom("WM_WINDOW_ROLE")); |
| 917 } else { | 910 } else { |
| 918 char* role_c = const_cast<char*>(role.c_str()); | 911 char* role_c = const_cast<char*>(role.c_str()); |
| 919 XChangeProperty(display, window, GetAtom("WM_WINDOW_ROLE"), XA_STRING, 8, | 912 XChangeProperty(display, window, gfx::GetAtom("WM_WINDOW_ROLE"), XA_STRING, |
| 920 PropModeReplace, | 913 8, PropModeReplace, |
| 921 reinterpret_cast<unsigned char*>(role_c), | 914 reinterpret_cast<unsigned char*>(role_c), role.size()); |
| 922 role.size()); | |
| 923 } | 915 } |
| 924 } | 916 } |
| 925 | 917 |
| 926 bool GetCustomFramePrefDefault() { | 918 bool GetCustomFramePrefDefault() { |
| 927 // If the window manager doesn't support enough of EWMH to tell us its name, | 919 // If the window manager doesn't support enough of EWMH to tell us its name, |
| 928 // assume that it doesn't want custom frames. For example, _NET_WM_MOVERESIZE | 920 // assume that it doesn't want custom frames. For example, _NET_WM_MOVERESIZE |
| 929 // is needed for frame-drag-initiated window movement. | 921 // is needed for frame-drag-initiated window movement. |
| 930 std::string wm_name; | 922 std::string wm_name; |
| 931 if (!GetWindowManagerName(&wm_name)) | 923 if (!GetWindowManagerName(&wm_name)) |
| 932 return false; | 924 return false; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 | 1170 |
| 1179 std::string GuessWindowManagerName() { | 1171 std::string GuessWindowManagerName() { |
| 1180 std::string name; | 1172 std::string name; |
| 1181 if (GetWindowManagerName(&name)) | 1173 if (GetWindowManagerName(&name)) |
| 1182 return name; | 1174 return name; |
| 1183 return "Unknown"; | 1175 return "Unknown"; |
| 1184 } | 1176 } |
| 1185 | 1177 |
| 1186 bool IsCompositingManagerPresent() { | 1178 bool IsCompositingManagerPresent() { |
| 1187 static bool is_compositing_manager_present = | 1179 static bool is_compositing_manager_present = |
| 1188 XGetSelectionOwner(gfx::GetXDisplay(), GetAtom("_NET_WM_CM_S0")) != None; | 1180 XGetSelectionOwner(gfx::GetXDisplay(), gfx::GetAtom("_NET_WM_CM_S0")) != |
| 1181 None; |
| 1189 return is_compositing_manager_present; | 1182 return is_compositing_manager_present; |
| 1190 } | 1183 } |
| 1191 | 1184 |
| 1192 void SetDefaultX11ErrorHandlers() { | 1185 void SetDefaultX11ErrorHandlers() { |
| 1193 SetX11ErrorHandlers(NULL, NULL); | 1186 SetX11ErrorHandlers(NULL, NULL); |
| 1194 } | 1187 } |
| 1195 | 1188 |
| 1196 bool IsX11WindowFullScreen(XID window) { | 1189 bool IsX11WindowFullScreen(XID window) { |
| 1197 // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or | 1190 // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or |
| 1198 // absence of _NET_WM_STATE_FULLSCREEN in _NET_WM_STATE to determine | 1191 // absence of _NET_WM_STATE_FULLSCREEN in _NET_WM_STATE to determine |
| 1199 // whether we're fullscreen. | 1192 // whether we're fullscreen. |
| 1200 XAtom fullscreen_atom = GetAtom("_NET_WM_STATE_FULLSCREEN"); | 1193 XAtom fullscreen_atom = gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"); |
| 1201 if (WmSupportsHint(fullscreen_atom)) { | 1194 if (WmSupportsHint(fullscreen_atom)) { |
| 1202 std::vector<XAtom> atom_properties; | 1195 std::vector<XAtom> atom_properties; |
| 1203 if (GetAtomArrayProperty(window, | 1196 if (GetAtomArrayProperty(window, |
| 1204 "_NET_WM_STATE", | 1197 "_NET_WM_STATE", |
| 1205 &atom_properties)) { | 1198 &atom_properties)) { |
| 1206 return std::find(atom_properties.begin(), | 1199 return std::find(atom_properties.begin(), |
| 1207 atom_properties.end(), | 1200 atom_properties.end(), |
| 1208 fullscreen_atom) != | 1201 fullscreen_atom) != |
| 1209 atom_properties.end(); | 1202 atom_properties.end(); |
| 1210 } | 1203 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1384 using_software_rendering_(false), | 1377 using_software_rendering_(false), |
| 1385 have_gpu_argb_visual_(false) { | 1378 have_gpu_argb_visual_(false) { |
| 1386 int visuals_len = 0; | 1379 int visuals_len = 0; |
| 1387 XVisualInfo visual_template; | 1380 XVisualInfo visual_template; |
| 1388 visual_template.screen = DefaultScreen(display_); | 1381 visual_template.screen = DefaultScreen(display_); |
| 1389 gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo( | 1382 gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo( |
| 1390 display_, VisualScreenMask, &visual_template, &visuals_len)); | 1383 display_, VisualScreenMask, &visual_template, &visuals_len)); |
| 1391 for (int i = 0; i < visuals_len; ++i) | 1384 for (int i = 0; i < visuals_len; ++i) |
| 1392 visuals_[visual_list[i].visualid].reset(new XVisualData(visual_list[i])); | 1385 visuals_[visual_list[i].visualid].reset(new XVisualData(visual_list[i])); |
| 1393 | 1386 |
| 1394 XAtom NET_WM_CM_S0 = GetAtom("_NET_WM_CM_S0"); | 1387 XAtom NET_WM_CM_S0 = gfx::GetAtom("_NET_WM_CM_S0"); |
| 1395 using_compositing_wm_ = XGetSelectionOwner(display_, NET_WM_CM_S0) != None; | 1388 using_compositing_wm_ = XGetSelectionOwner(display_, NET_WM_CM_S0) != None; |
| 1396 | 1389 |
| 1397 // Choose the opaque visual. | 1390 // Choose the opaque visual. |
| 1398 default_visual_id_ = | 1391 default_visual_id_ = |
| 1399 XVisualIDFromVisual(DefaultVisual(display_, DefaultScreen(display_))); | 1392 XVisualIDFromVisual(DefaultVisual(display_, DefaultScreen(display_))); |
| 1400 system_visual_id_ = default_visual_id_; | 1393 system_visual_id_ = default_visual_id_; |
| 1401 DCHECK(system_visual_id_); | 1394 DCHECK(system_visual_id_); |
| 1402 DCHECK(visuals_.find(system_visual_id_) != visuals_.end()); | 1395 DCHECK(visuals_.find(system_visual_id_) != visuals_.end()); |
| 1403 | 1396 |
| 1404 // Choose the transparent visual. | 1397 // Choose the transparent visual. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 visual_info.visual, AllocNone); | 1474 visual_info.visual, AllocNone); |
| 1482 } | 1475 } |
| 1483 return colormap_; | 1476 return colormap_; |
| 1484 } | 1477 } |
| 1485 | 1478 |
| 1486 // ---------------------------------------------------------------------------- | 1479 // ---------------------------------------------------------------------------- |
| 1487 // End of x11_util_internal.h | 1480 // End of x11_util_internal.h |
| 1488 | 1481 |
| 1489 | 1482 |
| 1490 } // namespace ui | 1483 } // namespace ui |
| OLD | NEW |