Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(586)

Side by Side Diff: window_manager.cc

Issue 6902072: wm: Update a lot of code to use structs from geometry.h. (Closed) Base URL: ssh://gitrw.chromium.org:9222/window_manager.git@master
Patch Set: move override-redirect stacking and visibility into Window Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS 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 "window_manager/window_manager.h" 5 #include "window_manager/window_manager.h"
6 6
7 #include <cstring> 7 #include <cstring>
8 #include <ctime> 8 #include <ctime>
9 #include <list> 9 #include <list>
10 #include <queue> 10 #include <queue>
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 201
202 WindowManager::WindowManager(EventLoop* event_loop, 202 WindowManager::WindowManager(EventLoop* event_loop,
203 XConnection* xconn, 203 XConnection* xconn,
204 Compositor* compositor, 204 Compositor* compositor,
205 DBusInterface* dbus) 205 DBusInterface* dbus)
206 : event_loop_(event_loop), 206 : event_loop_(event_loop),
207 xconn_(xconn), 207 xconn_(xconn),
208 compositor_(compositor), 208 compositor_(compositor),
209 dbus_(dbus), 209 dbus_(dbus),
210 root_(0), 210 root_(0),
211 width_(0),
212 height_(0),
213 wm_xid_(0), 211 wm_xid_(0),
214 stage_(NULL), 212 stage_(NULL),
215 stage_xid_(0), 213 stage_xid_(0),
216 overlay_xid_(0), 214 overlay_xid_(0),
217 startup_pixmap_(0), 215 startup_pixmap_(0),
218 mapped_xids_(new Stacker<XWindow>), 216 mapped_xids_(new Stacker<XWindow>),
219 stacked_xids_(new Stacker<XWindow>), 217 stacked_xids_(new Stacker<XWindow>),
220 damage_debugging_enabled_(false), 218 damage_debugging_enabled_(false),
221 active_window_xid_(0), 219 active_window_xid_(0),
222 query_keyboard_state_timeout_id_(-1), 220 query_keyboard_state_timeout_id_(-1),
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 // DisableCompositing callback, which does the actual disabling. 315 // DisableCompositing callback, which does the actual disabling.
318 unredirected_fullscreen_xid_ = window_to_unredirect; 316 unredirected_fullscreen_xid_ = window_to_unredirect;
319 if (!disable_compositing_task_is_pending_) { 317 if (!disable_compositing_task_is_pending_) {
320 event_loop_->PostTask( 318 event_loop_->PostTask(
321 NewPermanentCallback(this, &WindowManager::DisableCompositing)); 319 NewPermanentCallback(this, &WindowManager::DisableCompositing));
322 disable_compositing_task_is_pending_ = true; 320 disable_compositing_task_is_pending_ = true;
323 } 321 }
324 } 322 }
325 323
326 if (!was_compositing && should_composite) { 324 if (!was_compositing && should_composite) {
327 xconn_->SetWindowBoundingRegionToRect(overlay_xid_, 325 xconn_->SetWindowBoundingRegionToRect(overlay_xid_, root_bounds_);
328 Rect(0, 0, width_, height_));
329 DLOG(INFO) << "Turned compositing on"; 326 DLOG(INFO) << "Turned compositing on";
330 compositor_->set_should_draw_frame(true); 327 compositor_->set_should_draw_frame(true);
331 } 328 }
332 } 329 }
333 330
334 bool WindowManager::Init() { 331 bool WindowManager::Init() {
335 CHECK(!root_) << "Init() may only be called once"; 332 CHECK(!root_) << "Init() may only be called once";
336 root_ = xconn_->GetRootWindow(); 333 root_ = xconn_->GetRootWindow();
337 xconn_->SelectRandREventsOnWindow(root_); 334 xconn_->SelectRandREventsOnWindow(root_);
338 xconn_->SelectInputOnWindow(root_, StructureNotifyMask, true); 335 xconn_->SelectInputOnWindow(root_, StructureNotifyMask, true);
339 XConnection::WindowGeometry root_geometry; 336 XConnection::WindowGeometry root_geometry;
340 CHECK(xconn_->GetWindowGeometry(root_, &root_geometry)); 337 CHECK(xconn_->GetWindowGeometry(root_, &root_geometry));
341 width_ = root_geometry.bounds.width; 338 root_bounds_ = root_geometry.bounds;
342 height_ = root_geometry.bounds.height;
343 root_depth_ = root_geometry.depth; 339 root_depth_ = root_geometry.depth;
344 340
345 if (FLAGS_unredirect_fullscreen_window) { 341 if (FLAGS_unredirect_fullscreen_window) {
346 // Disable automatic background painting for the root window. It 342 // Disable automatic background painting for the root window. It
347 // should never be visible, and the automatic updates cause flickering 343 // should never be visible, and the automatic updates cause flickering
348 // when enabling and disabling compositing. 344 // when enabling and disabling compositing.
349 xconn_->SetWindowBackgroundPixmap(root_, None); 345 xconn_->SetWindowBackgroundPixmap(root_, None);
350 } 346 }
351 347
352 // Create the atom cache first; RegisterExistence() needs it. 348 // Create the atom cache first; RegisterExistence() needs it.
353 atom_cache_.reset(new AtomCache(xconn_)); 349 atom_cache_.reset(new AtomCache(xconn_));
354 350
355 CHECK(RegisterExistence()); 351 CHECK(RegisterExistence());
356 SetEwmhGeneralProperties(); 352 SetEwmhGeneralProperties();
357 SetEwmhSizeProperties(); 353 SetEwmhSizeProperties();
358 354
359 // First make sure that we'll get notified if the login state changes 355 // First make sure that we'll get notified if the login state changes
360 // and then query its current value. 356 // and then query its current value.
361 CHECK(xconn_->SelectInputOnWindow(root_, PropertyChangeMask, true)); 357 CHECK(xconn_->SelectInputOnWindow(root_, PropertyChangeMask, true));
362 int logged_in_value = 0; 358 int logged_in_value = 0;
363 xconn_->GetIntProperty( 359 xconn_->GetIntProperty(
364 root_, GetXAtom(ATOM_CHROME_LOGGED_IN), &logged_in_value); 360 root_, GetXAtom(ATOM_CHROME_LOGGED_IN), &logged_in_value);
365 logged_in_ = logged_in_value; 361 logged_in_ = logged_in_value;
366 362
367 stage_ = compositor_->GetDefaultStage(); 363 stage_ = compositor_->GetDefaultStage();
368 stage_xid_ = stage_->GetStageXWindow(); 364 stage_xid_ = stage_->GetStageXWindow();
369 stage_->SetName("stage"); 365 stage_->SetName("stage");
370 stage_->SetSize(width_, height_); 366 stage_->SetSize(root_bounds_.width, root_bounds_.height);
371 stage_->SetStageColor(Compositor::Color(FLAGS_background_color)); 367 stage_->SetStageColor(Compositor::Color(FLAGS_background_color));
372 stage_->Show(); 368 stage_->Show();
373 369
374 wm_ipc_.reset(new WmIpc(xconn_, atom_cache_.get())); 370 wm_ipc_.reset(new WmIpc(xconn_, atom_cache_.get()));
375 371
376 stacking_manager_.reset( 372 stacking_manager_.reset(
377 new StackingManager(xconn_, compositor_, atom_cache_.get())); 373 new StackingManager(xconn_, compositor_, atom_cache_.get()));
378 focus_manager_.reset(new FocusManager(this)); 374 focus_manager_.reset(new FocusManager(this));
379 375
380 if (FLAGS_report_metrics) { 376 if (FLAGS_report_metrics) {
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 root_, GetXAtom(ATOM_NET_SUPPORTED), XA_ATOM, supported); 1040 root_, GetXAtom(ATOM_NET_SUPPORTED), XA_ATOM, supported);
1045 1041
1046 return success; 1042 return success;
1047 } 1043 }
1048 1044
1049 bool WindowManager::SetEwmhSizeProperties() { 1045 bool WindowManager::SetEwmhSizeProperties() {
1050 bool success = true; 1046 bool success = true;
1051 1047
1052 // We don't use pseudo-large desktops, so this is just the screen size. 1048 // We don't use pseudo-large desktops, so this is just the screen size.
1053 vector<int> geometry; 1049 vector<int> geometry;
1054 geometry.push_back(width_); 1050 geometry.push_back(root_bounds_.width);
1055 geometry.push_back(height_); 1051 geometry.push_back(root_bounds_.height);
1056 success &= xconn_->SetIntArrayProperty( 1052 success &= xconn_->SetIntArrayProperty(
1057 root_, GetXAtom(ATOM_NET_DESKTOP_GEOMETRY), XA_CARDINAL, geometry); 1053 root_, GetXAtom(ATOM_NET_DESKTOP_GEOMETRY), XA_CARDINAL, geometry);
1058 1054
1059 // The viewport (top-left corner of the desktop) is just (0, 0) for us. 1055 // The viewport (top-left corner of the desktop) is just (0, 0) for us.
1060 vector<int> viewport(2, 0); 1056 vector<int> viewport(2, 0);
1061 success &= xconn_->SetIntArrayProperty( 1057 success &= xconn_->SetIntArrayProperty(
1062 root_, GetXAtom(ATOM_NET_DESKTOP_VIEWPORT), XA_CARDINAL, viewport); 1058 root_, GetXAtom(ATOM_NET_DESKTOP_VIEWPORT), XA_CARDINAL, viewport);
1063 1059
1064 success &= SetEwmhWorkareaProperty(); 1060 success &= SetEwmhWorkareaProperty();
1065 1061
1066 return success; 1062 return success;
1067 } 1063 }
1068 1064
1069 bool WindowManager::SetEwmhWorkareaProperty() { 1065 bool WindowManager::SetEwmhWorkareaProperty() {
1070 // _NET_WORKAREA describes the region of the screen "minus space occupied 1066 // _NET_WORKAREA describes the region of the screen "minus space occupied
1071 // by dock and panel windows", so we subtract out the space used by panel 1067 // by dock and panel windows", so we subtract out the space used by panel
1072 // docks. :-P Chrome can use this to guess the initial size for new 1068 // docks. :-P Chrome can use this to guess the initial size for new
1073 // windows. 1069 // windows.
1074 int panel_manager_left_width = 0, panel_manager_right_width = 0; 1070 int panel_manager_left_width = 0, panel_manager_right_width = 0;
1075 if (panel_manager_.get()) { 1071 if (panel_manager_.get()) {
1076 // We invoke this before the panel manager has been created to try to 1072 // We invoke this before the panel manager has been created to try to
1077 // get the hints set as soon as possible. 1073 // get the hints set as soon as possible.
1078 panel_manager_->GetArea(&panel_manager_left_width, 1074 panel_manager_->GetArea(&panel_manager_left_width,
1079 &panel_manager_right_width); 1075 &panel_manager_right_width);
1080 } 1076 }
1081 vector<int> workarea; 1077 vector<int> workarea;
1082 workarea.push_back(panel_manager_left_width); // x 1078 workarea.push_back(panel_manager_left_width); // x
1083 workarea.push_back(0); // y 1079 workarea.push_back(0); // y
1084 workarea.push_back( 1080 workarea.push_back(
1085 width_ - panel_manager_left_width - panel_manager_right_width); 1081 root_bounds_.width -
1086 workarea.push_back(height_); 1082 panel_manager_left_width -
1083 panel_manager_right_width);
1084 workarea.push_back(root_bounds_.height);
1087 return xconn_->SetIntArrayProperty( 1085 return xconn_->SetIntArrayProperty(
1088 root_, GetXAtom(ATOM_NET_WORKAREA), XA_CARDINAL, workarea); 1086 root_, GetXAtom(ATOM_NET_WORKAREA), XA_CARDINAL, workarea);
1089 } 1087 }
1090 1088
1091 void WindowManager::RegisterKeyBindings() { 1089 void WindowManager::RegisterKeyBindings() {
1092 #ifndef NDEBUG 1090 #ifndef NDEBUG
1093 static const uint32_t kCtrlAltShiftMask = 1091 static const uint32_t kCtrlAltShiftMask =
1094 KeyBindings::kControlMask | 1092 KeyBindings::kControlMask |
1095 KeyBindings::kAltMask | 1093 KeyBindings::kAltMask |
1096 KeyBindings::kShiftMask; 1094 KeyBindings::kShiftMask;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 for (vector<XAtom>::const_iterator it = 1243 for (vector<XAtom>::const_iterator it =
1246 win->wm_window_type_xatoms().begin(); 1244 win->wm_window_type_xatoms().begin();
1247 it != win->wm_window_type_xatoms().end(); ++it) { 1245 it != win->wm_window_type_xatoms().end(); ++it) {
1248 if (*it == combo_xatom || *it == dropdown_xatom || *it == menu_xatom || 1246 if (*it == combo_xatom || *it == dropdown_xatom || *it == menu_xatom ||
1249 *it == popup_xatom) { 1247 *it == popup_xatom) {
1250 win->SetShadowType(Shadow::TYPE_RECTANGULAR); 1248 win->SetShadowType(Shadow::TYPE_RECTANGULAR);
1251 break; 1249 break;
1252 } 1250 }
1253 } 1251 }
1254 } 1252 }
1255
1256 win->ShowComposited();
1257 return; 1253 return;
1258 } 1254 }
1259 1255
1260 if (mapped_xids_->Contains(win->xid())) { 1256 if (mapped_xids_->Contains(win->xid())) {
1261 LOG(WARNING) << "Handling mapped window " << win->xid_str() 1257 LOG(WARNING) << "Handling mapped window " << win->xid_str()
1262 << ", which is already listed in |mapped_xids_|"; 1258 << ", which is already listed in |mapped_xids_|";
1263 } else { 1259 } else {
1264 mapped_xids_->AddOnTop(win->xid()); 1260 mapped_xids_->AddOnTop(win->xid());
1265 UpdateClientListProperty(); 1261 UpdateClientListProperty();
1266 // This only includes mapped windows, so we need to update it now. 1262 // This only includes mapped windows, so we need to update it now.
1267 UpdateClientListStackingProperty(); 1263 UpdateClientListStackingProperty();
1268 } 1264 }
1269 1265
1270 SetWmStateProperty(win->xid(), 1); // NormalState 1266 SetWmStateProperty(win->xid(), 1); // NormalState
1271 } 1267 }
1272 1268
1273 void WindowManager::HandleScreenResize(int new_width, int new_height) { 1269 void WindowManager::HandleScreenResize(const Size& new_size) {
1274 // We move windows offscreen to prevent them from receiving input. 1270 // We move windows offscreen to prevent them from receiving input.
1275 // Check that the screen doesn't get so huge that they end up onscreen. 1271 // Check that the screen doesn't get so huge that they end up onscreen.
1276 DCHECK_LE(new_width, Window::kOffscreenX); 1272 DCHECK_LE(new_size.width, Window::kOffscreenX);
1277 DCHECK_LE(new_height, Window::kOffscreenY); 1273 DCHECK_LE(new_size.height, Window::kOffscreenY);
1278 1274
1279 // The window manager sometimes tries to fetch an updated 1275 // The window manager sometimes tries to fetch an updated
1280 // pixmap for a resized window while the window is unredirected, resulting 1276 // pixmap for a resized window while the window is unredirected, resulting
1281 // in a black screen until compositing is toggled on and off again. 1277 // in a black screen until compositing is toggled on and off again.
1282 // To avoid this, disable compositing while resizing. 1278 // To avoid this, disable compositing while resizing.
1283 scoped_ptr<ScopedCompositingRequest> comp_request( 1279 scoped_ptr<ScopedCompositingRequest> comp_request(
1284 CreateScopedCompositingRequest()); 1280 CreateScopedCompositingRequest());
1285 1281
1286 width_ = new_width; 1282 root_bounds_.resize(new_size, GRAVITY_NORTHWEST);
1287 height_ = new_height;
1288 SetEwmhSizeProperties(); 1283 SetEwmhSizeProperties();
1289 stage_->SetSize(width_, height_); 1284 stage_->SetSize(root_bounds_.width, root_bounds_.height);
1290 FOR_EACH_EVENT_CONSUMER(event_consumers_, HandleScreenResize()); 1285 FOR_EACH_EVENT_CONSUMER(event_consumers_, HandleScreenResize());
1291 } 1286 }
1292 1287
1293 bool WindowManager::SetWmStateProperty(XWindow xid, int state) { 1288 bool WindowManager::SetWmStateProperty(XWindow xid, int state) {
1294 vector<int> values; 1289 vector<int> values;
1295 values.push_back(state); 1290 values.push_back(state);
1296 values.push_back(0); // we don't use icons 1291 values.push_back(0); // we don't use icons
1297 XAtom xatom = GetXAtom(ATOM_WM_STATE); 1292 XAtom xatom = GetXAtom(ATOM_WM_STATE);
1298 return xconn_->SetIntArrayProperty(xid, xatom, xatom, values); 1293 return xconn_->SetIntArrayProperty(xid, xatom, xatom, values);
1299 } 1294 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 } 1341 }
1347 1342
1348 void WindowManager::HandleButtonPress(const XButtonEvent& e) { 1343 void WindowManager::HandleButtonPress(const XButtonEvent& e) {
1349 DLOG(INFO) << "Handling button press in window " << XidStr(e.window) 1344 DLOG(INFO) << "Handling button press in window " << XidStr(e.window)
1350 << " at relative (" << e.x << ", " << e.y << "), absolute (" 1345 << " at relative (" << e.x << ", " << e.y << "), absolute ("
1351 << e.x_root << ", " << e.y_root << ") with button " << e.button; 1346 << e.x_root << ", " << e.y_root << ") with button " << e.button;
1352 Window* win = GetWindow(e.window); 1347 Window* win = GetWindow(e.window);
1353 if (win) 1348 if (win)
1354 focus_manager_->HandleButtonPressInWindow(win, e.time); 1349 focus_manager_->HandleButtonPressInWindow(win, e.time);
1355 1350
1351 const Point relative_pos(e.x, e.y);
1352 const Point absolute_pos(e.x_root, e.y_root);
1356 FOR_EACH_INTERESTED_EVENT_CONSUMER( 1353 FOR_EACH_INTERESTED_EVENT_CONSUMER(
1357 window_event_consumers_, 1354 window_event_consumers_,
1358 e.window, 1355 e.window,
1359 HandleButtonPress(e.window, e.x, e.y, e.x_root, 1356 HandleButtonPress(
1360 e.y_root, e.button, e.time)); 1357 e.window, relative_pos, absolute_pos, e.button, e.time));
1361 } 1358 }
1362 1359
1363 void WindowManager::HandleButtonRelease(const XButtonEvent& e) { 1360 void WindowManager::HandleButtonRelease(const XButtonEvent& e) {
1364 DLOG(INFO) << "Handling button release in window " << XidStr(e.window) 1361 DLOG(INFO) << "Handling button release in window " << XidStr(e.window)
1365 << " at relative (" << e.x << ", " << e.y << "), absolute (" 1362 << " at relative (" << e.x << ", " << e.y << "), absolute ("
1366 << e.x_root << ", " << e.y_root << ") with button " << e.button; 1363 << e.x_root << ", " << e.y_root << ") with button " << e.button;
1364
1365 const Point relative_pos(e.x, e.y);
1366 const Point absolute_pos(e.x_root, e.y_root);
1367 FOR_EACH_INTERESTED_EVENT_CONSUMER( 1367 FOR_EACH_INTERESTED_EVENT_CONSUMER(
1368 window_event_consumers_, 1368 window_event_consumers_,
1369 e.window, 1369 e.window,
1370 HandleButtonRelease(e.window, e.x, e.y, e.x_root, 1370 HandleButtonRelease(
1371 e.y_root, e.button, e.time)); 1371 e.window, relative_pos, absolute_pos, e.button, e.time));
1372 } 1372 }
1373 1373
1374 void WindowManager::HandleClientMessage(const XClientMessageEvent& e) { 1374 void WindowManager::HandleClientMessage(const XClientMessageEvent& e) {
1375 // _NET_WM_PING responses are spammy; don't log them. 1375 // _NET_WM_PING responses are spammy; don't log them.
1376 if (!(e.message_type == GetXAtom(ATOM_WM_PROTOCOLS) && 1376 if (!(e.message_type == GetXAtom(ATOM_WM_PROTOCOLS) &&
1377 e.format == XConnection::kLongFormat && 1377 e.format == XConnection::kLongFormat &&
1378 static_cast<XAtom>(e.data.l[0]) == GetXAtom(ATOM_NET_WM_PING))) { 1378 static_cast<XAtom>(e.data.l[0]) == GetXAtom(ATOM_NET_WM_PING))) {
1379 DLOG(INFO) << "Handling client message for window " << XidStr(e.window) 1379 DLOG(INFO) << "Handling client message for window " << XidStr(e.window)
1380 << " with type " << XidStr(e.message_type) << " (" 1380 << " with type " << XidStr(e.message_type) << " ("
1381 << GetXAtomName(e.message_type) << ") and format " << e.format; 1381 << GetXAtomName(e.message_type) << ") and format " << e.format;
(...skipping 30 matching lines...) Expand all
1412 e.window, 1412 e.window,
1413 HandleClientMessage(e.window, e.message_type, e.data.l)); 1413 HandleClientMessage(e.window, e.message_type, e.data.l));
1414 } else { 1414 } else {
1415 LOG(WARNING) << "Ignoring client message event with unsupported format " 1415 LOG(WARNING) << "Ignoring client message event with unsupported format "
1416 << e.format << " (we only handle 32-bit data currently)"; 1416 << e.format << " (we only handle 32-bit data currently)";
1417 } 1417 }
1418 } 1418 }
1419 } 1419 }
1420 1420
1421 void WindowManager::HandleConfigureNotify(const XConfigureEvent& e) { 1421 void WindowManager::HandleConfigureNotify(const XConfigureEvent& e) {
1422 if (e.window == root_ && (e.width != width_ || e.height != height_)) { 1422 const Rect bounds(e.x, e.y, e.width, e.height);
1423
1424 if (e.window == root_ && bounds.size() != root_bounds_.size()) {
1423 DLOG(INFO) << "Got configure notify saying that root window has been " 1425 DLOG(INFO) << "Got configure notify saying that root window has been "
1424 << "resized to " << e.width << "x" << e.height; 1426 << "resized to " << bounds.size();
1425 HandleScreenResize(e.width, e.height); 1427 HandleScreenResize(bounds.size());
1426 return; 1428 return;
1427 } 1429 }
1428 1430
1429 // Even though _NET_CLIENT_LIST_STACKING only contains client windows 1431 // Even though _NET_CLIENT_LIST_STACKING only contains client windows
1430 // that we're managing, we also need to keep track of other (e.g. 1432 // that we're managing, we also need to keep track of other (e.g.
1431 // override-redirect, or even untracked) windows: we receive 1433 // override-redirect, or even untracked) windows: we receive
1432 // notifications of the form "X is on top of Y", so we need to know where 1434 // notifications of the form "X is on top of Y", so we need to know where
1433 // Y is even if we're not managing it so that we can stack X correctly. 1435 // Y is even if we're not managing it so that we can stack X correctly.
1434 1436
1435 // If this isn't an immediate child of the root window, ignore the 1437 // If this isn't an immediate child of the root window, ignore the
(...skipping 25 matching lines...) Expand all
1461 << " said that it's stacked above " << XidStr(e.above) 1463 << " said that it's stacked above " << XidStr(e.above)
1462 << ", which we don't know about"; 1464 << ", which we don't know about";
1463 } 1465 }
1464 stacked_xids_->AddOnBottom(e.window); 1466 stacked_xids_->AddOnBottom(e.window);
1465 } 1467 }
1466 } 1468 }
1467 1469
1468 Window* win = GetWindow(e.window); 1470 Window* win = GetWindow(e.window);
1469 if (!win) 1471 if (!win)
1470 return; 1472 return;
1471 DLOG(INFO) << "Handling configure notify for " << XidStr(e.window) 1473 DLOG(INFO) << "Handling configure notify for " << win->xid_str()
1472 << " to pos (" << e.x << ", " << e.y << ") and size " 1474 << " to " << bounds << ", above " << XidStr(e.above);
1473 << e.width << "x" << e.height << ", above " << XidStr(e.above);
1474 1475
1475 // There are several cases to consider here: 1476 if (!win->override_redirect() && restacked) {
1476 // 1477 // _NET_CLIENT_LIST_STACKING only includes managed (i.e.
1477 // - Override-redirect windows' calls to configure themselves are honored 1478 // non-override-redirect) windows, so we only update it when a
1478 // by the X server without any intervention on our part, so we only 1479 // managed window's stacking position changed.
1479 // need to update their composited positions here. 1480 UpdateClientListStackingProperty();
1480 // - Regular non-override-redirect windows' configuration calls are
1481 // passed to us as ConfigureRequest events, so we would've already
1482 // updated both their X and composited configuration in
1483 // HandleConfigureRequest(). We don't need to do anything here.
1484 // - For both types of window, we may have decided to move or resize the
1485 // window ourselves earlier through a direct call to Window::Move() or
1486 // Resize(). In that case, we would've already updated their
1487 // composited position (or at least started the animation) then.
1488
1489 if (win->override_redirect()) {
1490 win->MoveComposited(e.x, e.y, 0);
1491 win->SaveClientPosition(e.x, e.y);
1492 win->SaveClientSize(e.width, e.height);
1493
1494 // When we see a stacking change for an override-redirect window, we
1495 // attempt to restack its actor correspondingly. If we don't have an
1496 // actor for the X window directly under it, we walk down the stack
1497 // until we find one.
1498 XWindow above_xid = e.above;
1499 while (above_xid) {
1500 Window* above_win = GetWindow(above_xid);
1501 Compositor::Actor* above_actor =
1502 above_win ? above_win->actor() :
1503 stacking_manager_->GetActorIfLayerXid(above_xid);
1504
1505 if (above_actor) {
1506 DLOG(INFO) << "Stacking override-redirect window " << win->xid_str()
1507 << "'s actor above window " << XidStr(above_xid) << "'s";
1508 win->StackCompositedAbove(above_actor, NULL, false);
1509 break;
1510 }
1511 const XWindow* above_ptr = stacked_xids_->GetUnder(above_xid);
1512 above_xid = above_ptr ? *above_ptr : 0;
1513 }
1514 } else {
1515 if (restacked) {
1516 // _NET_CLIENT_LIST_STACKING only includes managed (i.e.
1517 // non-override-redirect) windows, so we only update it when a
1518 // managed window's stacking position changed.
1519 UpdateClientListStackingProperty();
1520 }
1521 } 1481 }
1522 1482
1523 win->HandleConfigureNotify(e.width, e.height); 1483 // Notify the window so it can reset its pixmap if the size changed, or update
1484 // its actor's position and stacking if it's an override-redirect window.
1485 win->HandleConfigureNotify(bounds, e.above);
1524 } 1486 }
1525 1487
1526 void WindowManager::HandleConfigureRequest(const XConfigureRequestEvent& e) { 1488 void WindowManager::HandleConfigureRequest(const XConfigureRequestEvent& e) {
1527 Window* win = GetWindow(e.window); 1489 Window* win = GetWindow(e.window);
1528 if (!win) 1490 if (!win)
1529 return; 1491 return;
1530 1492
1531 DLOG(INFO) 1493 DLOG(INFO)
1532 << "Handling configure request for " << XidStr(e.window) 1494 << "Handling configure request for " << XidStr(e.window)
1533 << " to pos (" 1495 << " to pos ("
1534 << ((e.value_mask & CWX) ? StringPrintf("%d", e.x) : string("undef")) 1496 << ((e.value_mask & CWX) ? StringPrintf("%d", e.x) : string("undef"))
1535 << ", " 1497 << ", "
1536 << ((e.value_mask & CWY) ? StringPrintf("%d", e.y) : string("undef")) 1498 << ((e.value_mask & CWY) ? StringPrintf("%d", e.y) : string("undef"))
1537 << ") and size " 1499 << ") and size "
1538 << ((e.value_mask & CWWidth) ? 1500 << ((e.value_mask & CWWidth) ?
1539 StringPrintf("%d", e.width) : string("undef ")) 1501 StringPrintf("%d", e.width) : string("undef "))
1540 << "x" 1502 << "x"
1541 << ((e.value_mask & CWHeight) ? 1503 << ((e.value_mask & CWHeight) ?
1542 StringPrintf("%d", e.height) : string(" undef")); 1504 StringPrintf("%d", e.height) : string(" undef"));
1543 if (win->override_redirect()) { 1505 if (win->override_redirect()) {
1544 LOG(WARNING) << "Huh? Got a ConfigureRequest event for override-redirect " 1506 LOG(WARNING) << "Huh? Got a ConfigureRequest event for override-redirect "
1545 << "window " << win->xid_str(); 1507 << "window " << win->xid_str();
1546 } 1508 }
1547 1509
1548 const int req_x = (e.value_mask & CWX) ? e.x : win->client_x(); 1510 const Rect requested_bounds(
1549 const int req_y = (e.value_mask & CWY) ? e.y : win->client_y(); 1511 (e.value_mask & CWX) ? e.x : win->client_x(),
1550 const int req_width = 1512 (e.value_mask & CWY) ? e.y : win->client_y(),
1551 (e.value_mask & CWWidth) ? e.width : win->client_width(); 1513 (e.value_mask & CWWidth) ? e.width : win->client_width(),
1552 const int req_height = 1514 (e.value_mask & CWHeight) ? e.height : win->client_height());
1553 (e.value_mask & CWHeight) ? e.height : win->client_height();
1554 1515
1555 // The X server should reject bogus requests before they get to us, but 1516 // The X server should reject bogus requests before they get to us, but
1556 // just in case... 1517 // just in case...
1557 if (req_width <= 0 || req_height <= 0) { 1518 if (requested_bounds.width <= 0 || requested_bounds.height <= 0) {
1558 LOG(WARNING) << "Ignoring request to resize window " << win->xid_str() 1519 LOG(WARNING) << "Ignoring request to resize window " << win->xid_str()
1559 << " to " << req_width << "x" << req_height; 1520 << " to " << requested_bounds.size();
1560 return; 1521 return;
1561 } 1522 }
1562 1523
1563 if (!win->mapped()) { 1524 if (!win->mapped()) {
1564 // If the window is unmapped, it's unlikely that any event consumers 1525 // If the window is unmapped, it's unlikely that any event consumers
1565 // will know what to do with it. Do whatever we were asked to do. 1526 // will know what to do with it. Do whatever we were asked to do.
1566 if (req_x != win->client_x() || req_y != win->client_y()) { 1527 if (requested_bounds.position() != win->client_origin()) {
1567 win->MoveClient(req_x, req_y); 1528 win->MoveClient(requested_bounds.x, requested_bounds.y);
1568 win->MoveComposited(req_x, req_y, 0); 1529 win->MoveComposited(requested_bounds.x, requested_bounds.y, 0);
1569 } 1530 }
1570 if (req_width != win->client_width() || req_height != win->client_height()) 1531 if (requested_bounds.size() != win->client_size())
1571 win->ResizeClient(req_width, req_height, GRAVITY_NORTHWEST); 1532 win->Resize(requested_bounds.size(), GRAVITY_NORTHWEST);
1572 } else { 1533 } else {
1573 FOR_EACH_INTERESTED_EVENT_CONSUMER( 1534 FOR_EACH_INTERESTED_EVENT_CONSUMER(
1574 window_event_consumers_, 1535 window_event_consumers_,
1575 e.window, 1536 e.window,
1576 HandleWindowConfigureRequest(win, req_x, req_y, req_width, req_height)); 1537 HandleWindowConfigureRequest(win, requested_bounds));
1577 } 1538 }
1578 } 1539 }
1579 1540
1580 void WindowManager::HandleCreateNotify(const XCreateWindowEvent& e) { 1541 void WindowManager::HandleCreateNotify(const XCreateWindowEvent& e) {
1581 if (GetWindow(e.window)) { 1542 if (GetWindow(e.window)) {
1582 LOG(WARNING) << "Ignoring create notify for already-known window " 1543 LOG(WARNING) << "Ignoring create notify for already-known window "
1583 << XidStr(e.window); 1544 << XidStr(e.window);
1584 return; 1545 return;
1585 } 1546 }
1586 1547
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 ec_it->second->OwnDestroyedWindow(destroyed_win, e.window); 1624 ec_it->second->OwnDestroyedWindow(destroyed_win, e.window);
1664 destroyed_window_event_consumers_.erase(ec_it); 1625 destroyed_window_event_consumers_.erase(ec_it);
1665 } 1626 }
1666 1627
1667 client_windows_.erase(e.window); 1628 client_windows_.erase(e.window);
1668 win = NULL; // erasing from client_windows_ deletes window. 1629 win = NULL; // erasing from client_windows_ deletes window.
1669 } 1630 }
1670 1631
1671 void WindowManager::HandleEnterNotify(const XEnterWindowEvent& e) { 1632 void WindowManager::HandleEnterNotify(const XEnterWindowEvent& e) {
1672 DLOG(INFO) << "Handling enter notify for " << XidStr(e.window); 1633 DLOG(INFO) << "Handling enter notify for " << XidStr(e.window);
1634 const Point relative_pos(e.x, e.y);
1635 const Point absolute_pos(e.x_root, e.y_root);
1673 FOR_EACH_INTERESTED_EVENT_CONSUMER( 1636 FOR_EACH_INTERESTED_EVENT_CONSUMER(
1674 window_event_consumers_, 1637 window_event_consumers_,
1675 e.window, 1638 e.window,
1676 HandlePointerEnter(e.window, e.x, e.y, e.x_root, e.y_root, e.time)); 1639 HandlePointerEnter(e.window, relative_pos, absolute_pos, e.time));
1677 } 1640 }
1678 1641
1679 void WindowManager::HandleKeyPress(const XKeyEvent& e) { 1642 void WindowManager::HandleKeyPress(const XKeyEvent& e) {
1680 // We grab the keyboard while shutting down or signing out; ignore any events 1643 // We grab the keyboard while shutting down or signing out; ignore any events
1681 // that we get. 1644 // that we get.
1682 if (IsSessionEnding()) 1645 if (IsSessionEnding())
1683 return; 1646 return;
1684 key_bindings_->HandleKeyPress(e.keycode, e.state, e.time); 1647 key_bindings_->HandleKeyPress(e.keycode, e.state, e.time);
1685 } 1648 }
1686 1649
1687 void WindowManager::HandleKeyRelease(const XKeyEvent& e) { 1650 void WindowManager::HandleKeyRelease(const XKeyEvent& e) {
1688 if (IsSessionEnding()) 1651 if (IsSessionEnding())
1689 return; 1652 return;
1690 key_bindings_->HandleKeyRelease(e.keycode, e.state, e.time); 1653 key_bindings_->HandleKeyRelease(e.keycode, e.state, e.time);
1691 } 1654 }
1692 1655
1693 void WindowManager::HandleLeaveNotify(const XLeaveWindowEvent& e) { 1656 void WindowManager::HandleLeaveNotify(const XLeaveWindowEvent& e) {
1694 DLOG(INFO) << "Handling leave notify for " << XidStr(e.window); 1657 DLOG(INFO) << "Handling leave notify for " << XidStr(e.window);
1658 const Point relative_pos(e.x, e.y);
1659 const Point absolute_pos(e.x_root, e.y_root);
1695 FOR_EACH_INTERESTED_EVENT_CONSUMER( 1660 FOR_EACH_INTERESTED_EVENT_CONSUMER(
1696 window_event_consumers_, 1661 window_event_consumers_,
1697 e.window, 1662 e.window,
1698 HandlePointerLeave(e.window, e.x, e.y, e.x_root, e.y_root, e.time)); 1663 HandlePointerLeave(e.window, relative_pos, absolute_pos, e.time));
1699 } 1664 }
1700 1665
1701 void WindowManager::HandleMapNotify(const XMapEvent& e) { 1666 void WindowManager::HandleMapNotify(const XMapEvent& e) {
1702 DLOG(INFO) << "Handling map notify for " << XidStr(e.window); 1667 DLOG(INFO) << "Handling map notify for " << XidStr(e.window);
1703 Window* win = GetWindow(e.window); 1668 Window* win = GetWindow(e.window);
1704 if (!win || win->mapped()) 1669 if (!win || win->mapped())
1705 return; 1670 return;
1706 HandleMappedWindow(win); 1671 HandleMappedWindow(win);
1707 } 1672 }
1708 1673
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 << win->type(); 1716 << win->type();
1752 } 1717 }
1753 1718
1754 void WindowManager::HandleMappingNotify(const XMappingEvent& e) { 1719 void WindowManager::HandleMappingNotify(const XMappingEvent& e) {
1755 DLOG(INFO) << "Handling (keyboard) mapping notify"; 1720 DLOG(INFO) << "Handling (keyboard) mapping notify";
1756 xconn()->RefreshKeyboardMap(e.request, e.first_keycode, e.count); 1721 xconn()->RefreshKeyboardMap(e.request, e.first_keycode, e.count);
1757 key_bindings_->RefreshKeyMappings(); 1722 key_bindings_->RefreshKeyMappings();
1758 } 1723 }
1759 1724
1760 void WindowManager::HandleMotionNotify(const XMotionEvent& e) { 1725 void WindowManager::HandleMotionNotify(const XMotionEvent& e) {
1726 const Point relative_pos(e.x, e.y);
1727 const Point absolute_pos(e.x_root, e.y_root);
1761 FOR_EACH_INTERESTED_EVENT_CONSUMER( 1728 FOR_EACH_INTERESTED_EVENT_CONSUMER(
1762 window_event_consumers_, 1729 window_event_consumers_,
1763 e.window, 1730 e.window,
1764 HandlePointerMotion(e.window, e.x, e.y, e.x_root, e.y_root, e.time)); 1731 HandlePointerMotion(e.window, relative_pos, absolute_pos, e.time));
1765 } 1732 }
1766 1733
1767 void WindowManager::HandlePropertyNotify(const XPropertyEvent& e) { 1734 void WindowManager::HandlePropertyNotify(const XPropertyEvent& e) {
1768 if (e.window == root_ && e.atom == GetXAtom(ATOM_CHROME_LOGGED_IN)) { 1735 if (e.window == root_ && e.atom == GetXAtom(ATOM_CHROME_LOGGED_IN)) {
1769 int value = 0; 1736 int value = 0;
1770 bool logged_in = xconn_->GetIntProperty(root_, e.atom, &value) && value; 1737 bool logged_in = xconn_->GetIntProperty(root_, e.atom, &value) && value;
1771 SetLoggedInState(logged_in, false); // initial=false 1738 SetLoggedInState(logged_in, false); // initial=false
1772 return; 1739 return;
1773 } 1740 }
1774 1741
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 1877
1911 void WindowManager::HandleUnmapNotify(const XUnmapEvent& e) { 1878 void WindowManager::HandleUnmapNotify(const XUnmapEvent& e) {
1912 DLOG(INFO) << "Handling unmap notify for " << XidStr(e.window); 1879 DLOG(INFO) << "Handling unmap notify for " << XidStr(e.window);
1913 Window* win = GetWindow(e.window); 1880 Window* win = GetWindow(e.window);
1914 if (!win || !win->mapped()) 1881 if (!win || !win->mapped())
1915 return; 1882 return;
1916 1883
1917 win->HandleUnmapNotify(); 1884 win->HandleUnmapNotify();
1918 FOR_EACH_EVENT_CONSUMER(event_consumers_, HandleWindowUnmap(win)); 1885 FOR_EACH_EVENT_CONSUMER(event_consumers_, HandleWindowUnmap(win));
1919 1886
1920 if (win->override_redirect()) { 1887 if (!win->override_redirect()) {
1921 win->HideComposited(); 1888 SetWmStateProperty(e.window, 0); // WithdrawnState
1922 return;
1923 }
1924 1889
1925 SetWmStateProperty(e.window, 0); // WithdrawnState 1890 // Notify the focus manager last in case any event consumers need to do
1891 // something special when they see the focused window getting unmapped.
1892 focus_manager_->HandleWindowUnmap(win);
1926 1893
1927 // Notify the focus manager last in case any event consumers need to do 1894 if (mapped_xids_->Contains(win->xid())) {
1928 // something special when they see the focused window getting unmapped. 1895 mapped_xids_->Remove(win->xid());
1929 focus_manager_->HandleWindowUnmap(win); 1896 UpdateClientListProperty();
1930 1897 UpdateClientListStackingProperty();
1931 if (mapped_xids_->Contains(win->xid())) { 1898 }
1932 mapped_xids_->Remove(win->xid());
1933 UpdateClientListProperty();
1934 UpdateClientListStackingProperty();
1935 } 1899 }
1936 } 1900 }
1937 1901
1938 XWindow WindowManager::GetArbitraryChromeWindow() { 1902 XWindow WindowManager::GetArbitraryChromeWindow() {
1939 for (WindowMap::const_iterator i = client_windows_.begin(); 1903 for (WindowMap::const_iterator i = client_windows_.begin();
1940 i != client_windows_.end(); ++i) { 1904 i != client_windows_.end(); ++i) {
1941 if (WmIpcWindowTypeIsChrome(i->second->type())) 1905 if (WmIpcWindowTypeIsChrome(i->second->type()))
1942 return i->first; 1906 return i->first;
1943 } 1907 }
1944 return 0; 1908 return 0;
(...skipping 26 matching lines...) Expand all
1971 1935
1972 if (system(command.c_str()) < 0) { 1936 if (system(command.c_str()) < 0) {
1973 LOG(ERROR) << "Taking screenshot via \"" << command << "\" failed"; 1937 LOG(ERROR) << "Taking screenshot via \"" << command << "\" failed";
1974 } else { 1938 } else {
1975 LOG(INFO) << "Saved screenshot to " << filename; 1939 LOG(INFO) << "Saved screenshot to " << filename;
1976 } 1940 }
1977 } 1941 }
1978 1942
1979 void WindowManager::CreateStartupBackground() { 1943 void WindowManager::CreateStartupBackground() {
1980 startup_pixmap_ = 1944 startup_pixmap_ =
1981 xconn_->CreatePixmap(root_, Size(width_, height_), root_depth_); 1945 xconn_->CreatePixmap(root_, root_bounds_.size(), root_depth_);
1982 xconn_->CopyArea(root_, // src 1946 xconn_->CopyArea(root_, // src
1983 startup_pixmap_, // dest 1947 startup_pixmap_, // dest
1984 Point(0, 0), // src_pos 1948 Point(0, 0), // src_pos
1985 Point(0, 0), // dest_pos 1949 Point(0, 0), // dest_pos
1986 Size(width_, height_)); 1950 root_bounds_.size());
1987 Compositor::TexturePixmapActor* pixmap_actor = 1951 Compositor::TexturePixmapActor* pixmap_actor =
1988 compositor_->CreateTexturePixmap(); 1952 compositor_->CreateTexturePixmap();
1989 pixmap_actor->SetPixmap(startup_pixmap_); 1953 pixmap_actor->SetPixmap(startup_pixmap_);
1990 startup_background_.reset(pixmap_actor); 1954 startup_background_.reset(pixmap_actor);
1991 startup_background_->SetName("startup background"); 1955 startup_background_->SetName("startup background");
1992 stage_->AddActor(startup_background_.get()); 1956 stage_->AddActor(startup_background_.get());
1993 stacking_manager_->StackActorAtTopOfLayer( 1957 stacking_manager_->StackActorAtTopOfLayer(
1994 startup_background_.get(), StackingManager::LAYER_BACKGROUND); 1958 startup_background_.get(), StackingManager::LAYER_BACKGROUND);
1995 startup_background_->Show(); 1959 startup_background_->Show();
1996 } 1960 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 event_consumers_.erase(login_controller_.get()); 1992 event_consumers_.erase(login_controller_.get());
2029 login_controller_.reset(); 1993 login_controller_.reset();
2030 } 1994 }
2031 1995
2032 void WindowManager::PingChrome() { 1996 void WindowManager::PingChrome() {
2033 chrome_watchdog_->SendPingToChrome(GetCurrentTimeFromServer(), 1997 chrome_watchdog_->SendPingToChrome(GetCurrentTimeFromServer(),
2034 kPingChromeTimeoutMs); 1998 kPingChromeTimeoutMs);
2035 } 1999 }
2036 2000
2037 } // namespace window_manager 2001 } // namespace window_manager
OLDNEW
« window.cc ('K') | « window_manager.h ('k') | window_manager_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698