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

Side by Side Diff: chrome/browser/gtk/browser_window_gtk.cc

Issue 400012: Refactor the keyboard events handling code related to RenderViewHostDelegate:... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "chrome/browser/gtk/browser_window_gtk.h" 5 #include "chrome/browser/gtk/browser_window_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <X11/XF86keysym.h> 8 #include <X11/XF86keysym.h>
9 9
10 #include <string> 10 #include <string>
11 11
12 #include "app/gfx/color_utils.h" 12 #include "app/gfx/color_utils.h"
13 #include "app/gfx/gtk_util.h" 13 #include "app/gfx/gtk_util.h"
14 #include "app/l10n_util.h" 14 #include "app/l10n_util.h"
15 #include "app/resource_bundle.h" 15 #include "app/resource_bundle.h"
16 #include "app/theme_provider.h" 16 #include "app/theme_provider.h"
17 #include "base/base_paths.h" 17 #include "base/base_paths.h"
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/gfx/rect.h" 19 #include "base/gfx/rect.h"
20 #include "base/keyboard_codes.h"
20 #include "base/logging.h" 21 #include "base/logging.h"
21 #include "base/message_loop.h" 22 #include "base/message_loop.h"
22 #include "base/path_service.h" 23 #include "base/path_service.h"
23 #include "base/scoped_ptr.h" 24 #include "base/scoped_ptr.h"
24 #include "base/string_util.h" 25 #include "base/string_util.h"
25 #include "base/time.h" 26 #include "base/time.h"
26 #include "chrome/app/chrome_dll_resource.h" 27 #include "chrome/app/chrome_dll_resource.h"
27 #include "chrome/browser/app_modal_dialog_queue.h" 28 #include "chrome/browser/app_modal_dialog_queue.h"
28 #include "chrome/browser/autocomplete/autocomplete_edit_view.h" 29 #include "chrome/browser/autocomplete/autocomplete_edit_view.h"
29 #include "chrome/browser/bookmarks/bookmark_utils.h" 30 #include "chrome/browser/bookmarks/bookmark_utils.h"
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 { XF86XK_Go, IDC_FOCUS_LOCATION, GdkModifierType(0) }, 198 { XF86XK_Go, IDC_FOCUS_LOCATION, GdkModifierType(0) },
198 199
199 // Tab/window controls. 200 // Tab/window controls.
200 { GDK_Page_Down, IDC_SELECT_NEXT_TAB, GDK_CONTROL_MASK }, 201 { GDK_Page_Down, IDC_SELECT_NEXT_TAB, GDK_CONTROL_MASK },
201 { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK }, 202 { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK },
202 { GDK_Page_Down, IDC_MOVE_TAB_NEXT, 203 { GDK_Page_Down, IDC_MOVE_TAB_NEXT,
203 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, 204 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
204 { GDK_Page_Up, IDC_MOVE_TAB_PREVIOUS, 205 { GDK_Page_Up, IDC_MOVE_TAB_PREVIOUS,
205 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, 206 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
206 { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK }, 207 { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK },
207 { GDK_t, IDC_NEW_TAB, GDK_CONTROL_MASK },
208 { GDK_n, IDC_NEW_WINDOW, GDK_CONTROL_MASK },
209 { GDK_n, IDC_NEW_INCOGNITO_WINDOW,
210 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
211 { GDK_w, IDC_CLOSE_TAB, GDK_CONTROL_MASK }, 208 { GDK_w, IDC_CLOSE_TAB, GDK_CONTROL_MASK },
212 { GDK_t, IDC_RESTORE_TAB, 209 { GDK_t, IDC_RESTORE_TAB,
213 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, 210 GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
214 211
215 { GDK_1, IDC_SELECT_TAB_0, GDK_CONTROL_MASK }, 212 { GDK_1, IDC_SELECT_TAB_0, GDK_CONTROL_MASK },
216 { GDK_2, IDC_SELECT_TAB_1, GDK_CONTROL_MASK }, 213 { GDK_2, IDC_SELECT_TAB_1, GDK_CONTROL_MASK },
217 { GDK_3, IDC_SELECT_TAB_2, GDK_CONTROL_MASK }, 214 { GDK_3, IDC_SELECT_TAB_2, GDK_CONTROL_MASK },
218 { GDK_4, IDC_SELECT_TAB_3, GDK_CONTROL_MASK }, 215 { GDK_4, IDC_SELECT_TAB_3, GDK_CONTROL_MASK },
219 { GDK_5, IDC_SELECT_TAB_4, GDK_CONTROL_MASK }, 216 { GDK_5, IDC_SELECT_TAB_4, GDK_CONTROL_MASK },
220 { GDK_6, IDC_SELECT_TAB_5, GDK_CONTROL_MASK }, 217 { GDK_6, IDC_SELECT_TAB_5, GDK_CONTROL_MASK },
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 { GDK_f, IDC_FULLSCREEN, 307 { GDK_f, IDC_FULLSCREEN,
311 GdkModifierType(GDK_CONTROL_MASK | GDK_MOD1_MASK) }, 308 GdkModifierType(GDK_CONTROL_MASK | GDK_MOD1_MASK) },
312 { GDK_Delete, IDC_TASK_MANAGER, 309 { GDK_Delete, IDC_TASK_MANAGER,
313 GdkModifierType(GDK_CONTROL_MASK | GDK_MOD1_MASK) }, 310 GdkModifierType(GDK_CONTROL_MASK | GDK_MOD1_MASK) },
314 { GDK_comma, IDC_CONTROL_PANEL, GdkModifierType(GDK_CONTROL_MASK) }, 311 { GDK_comma, IDC_CONTROL_PANEL, GdkModifierType(GDK_CONTROL_MASK) },
315 #endif 312 #endif
316 }; 313 };
317 314
318 #if defined(OS_CHROMEOS) 315 #if defined(OS_CHROMEOS)
319 316
320 namespace {
321
322 // This draws the spacer below the tab strip when we're using the compact 317 // This draws the spacer below the tab strip when we're using the compact
323 // location bar (i.e. no location bar). This basically duplicates the painting 318 // location bar (i.e. no location bar). This basically duplicates the painting
324 // that the tab strip would have done for this region so that it blends 319 // that the tab strip would have done for this region so that it blends
325 // nicely in with the bottom of the tabs. 320 // nicely in with the bottom of the tabs.
326 gboolean OnCompactNavSpacerExpose(GtkWidget* widget, 321 gboolean OnCompactNavSpacerExpose(GtkWidget* widget,
327 GdkEventExpose* e, 322 GdkEventExpose* e,
328 BrowserWindowGtk* window) { 323 BrowserWindowGtk* window) {
329 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); 324 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
330 cairo_rectangle(cr, e->area.x, e->area.y, e->area.width, e->area.height); 325 cairo_rectangle(cr, e->area.x, e->area.y, e->area.width, e->area.height);
331 cairo_clip(cr); 326 cairo_clip(cr);
(...skipping 13 matching lines...) Expand all
345 tabstrip_origin.x(), 340 tabstrip_origin.x(),
346 tabstrip_origin.y(), 341 tabstrip_origin.y(),
347 e->area.x + e->area.width - tabstrip_origin.x(), 342 e->area.x + e->area.width - tabstrip_origin.x(),
348 e->area.y + e->area.height - tabstrip_origin.y()); 343 e->area.y + e->area.height - tabstrip_origin.y());
349 cairo_fill(cr); 344 cairo_fill(cr);
350 cairo_destroy(cr); 345 cairo_destroy(cr);
351 346
352 return FALSE; 347 return FALSE;
353 } 348 }
354 349
355 } // namespace
356
357 // Callback from GTK when the user clicks the main menu button. 350 // Callback from GTK when the user clicks the main menu button.
358 static void OnMainMenuButtonClicked(GtkWidget* widget, 351 static void OnMainMenuButtonClicked(GtkWidget* widget,
359 BrowserWindowGtk* browser) { 352 BrowserWindowGtk* browser) {
360 chromeos::MainMenu::Show(browser->browser()); 353 chromeos::MainMenu::Show(browser->browser());
361 } 354 }
362 355
363 #endif // OS_CHROMEOS 356 #endif // OS_CHROMEOS
364 357
365 int GetCommandId(guint accel_key, GdkModifierType modifier) { 358 // Get the command ids of the key combinations that are not valid gtk
366 // Bug 9806: If capslock is on, we will get a capital letter as accel_key. 359 // accelerators.
367 accel_key = gdk_keyval_to_lower(accel_key); 360 int GetCustomCommandId(GdkEventKey* event) {
368 // Filter modifier to only include accelerator modifiers. 361 // Filter modifier to only include accelerator modifiers.
369 modifier = static_cast<GdkModifierType>( 362 guint modifier = event->state & gtk_accelerator_get_default_mod_mask();
370 modifier & gtk_accelerator_get_default_mod_mask()); 363 switch (event->keyval) {
371 for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) {
372 if (kAcceleratorMap[i].keyval == accel_key &&
373 kAcceleratorMap[i].modifier_type == modifier)
374 return kAcceleratorMap[i].command_id;
375 }
376
377 return -1;
378 }
379
380 int GetCustomCommandId(guint keyval, GdkModifierType modifier) {
381 // Filter modifier to only include accelerator modifiers.
382 modifier = static_cast<GdkModifierType>(
383 modifier & gtk_accelerator_get_default_mod_mask());
384
385 switch (keyval) {
386 // Gtk doesn't allow GDK_Tab or GDK_ISO_Left_Tab to be an accelerator (see 364 // Gtk doesn't allow GDK_Tab or GDK_ISO_Left_Tab to be an accelerator (see
387 // gtk_accelerator_valid), so we need to handle these accelerators 365 // gtk_accelerator_valid), so we need to handle these accelerators
388 // manually. 366 // manually.
389 // Some X clients (e.g. cygwin, NX client, etc.) also send GDK_KP_Tab when 367 // Some X clients (e.g. cygwin, NX client, etc.) also send GDK_KP_Tab when
390 // typing a tab key. We should also handle GDK_KP_Tab for such X clients as 368 // typing a tab key. We should also handle GDK_KP_Tab for such X clients as
391 // Firefox does. 369 // Firefox does.
392 case GDK_Tab: 370 case GDK_Tab:
393 case GDK_ISO_Left_Tab: 371 case GDK_ISO_Left_Tab:
394 case GDK_KP_Tab: 372 case GDK_KP_Tab:
395 if (GDK_CONTROL_MASK == modifier) { 373 if (GDK_CONTROL_MASK == modifier) {
396 return IDC_SELECT_NEXT_TAB; 374 return IDC_SELECT_NEXT_TAB;
397 } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { 375 } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) {
398 return IDC_SELECT_PREVIOUS_TAB; 376 return IDC_SELECT_PREVIOUS_TAB;
399 } 377 }
400 break; 378 break;
401 379
402 default: 380 default:
403 break; 381 break;
404 } 382 }
405 return -1; 383 return -1;
406 } 384 }
407 385
408 // An event handler for key press events. We need to special case key 386 // Get the command ids of the accelerators that we don't want the native widget
409 // combinations that are not valid gtk accelerators. This function returns 387 // to be able to override.
410 // TRUE if it can handle the key press. 388 int GetPreHandleCommandId(GdkEventKey* event) {
411 gboolean HandleCustomAccelerator(guint keyval, GdkModifierType modifier,
412 Browser* browser) {
413 int command = GetCustomCommandId(keyval, modifier);
414 if (command == -1)
415 return FALSE;
416
417 browser->ExecuteCommand(command);
418 return TRUE;
419 }
420
421 // Handle accelerators that we don't want the native widget to be able to
422 // override.
423 gboolean PreHandleAccelerator(guint keyval, GdkModifierType modifier,
424 Browser* browser) {
425 // Filter modifier to only include accelerator modifiers. 389 // Filter modifier to only include accelerator modifiers.
426 modifier = static_cast<GdkModifierType>( 390 guint modifier = event->state & gtk_accelerator_get_default_mod_mask();
427 modifier & gtk_accelerator_get_default_mod_mask()); 391 switch (event->keyval) {
428 switch (keyval) {
429 case GDK_Page_Down: 392 case GDK_Page_Down:
430 if (GDK_CONTROL_MASK == modifier) { 393 if (GDK_CONTROL_MASK == modifier) {
431 browser->ExecuteCommand(IDC_SELECT_NEXT_TAB); 394 return IDC_SELECT_NEXT_TAB;
432 return TRUE;
433 } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { 395 } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) {
434 browser->ExecuteCommand(IDC_MOVE_TAB_NEXT); 396 return IDC_MOVE_TAB_NEXT;
435 return TRUE;
436 } 397 }
437 break; 398 break;
438 399
439 case GDK_Page_Up: 400 case GDK_Page_Up:
440 if (GDK_CONTROL_MASK == modifier) { 401 if (GDK_CONTROL_MASK == modifier) {
441 browser->ExecuteCommand(IDC_SELECT_PREVIOUS_TAB); 402 return IDC_SELECT_PREVIOUS_TAB;
442 return TRUE;
443 } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { 403 } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) {
444 browser->ExecuteCommand(IDC_MOVE_TAB_PREVIOUS); 404 return IDC_MOVE_TAB_PREVIOUS;
445 return TRUE;
446 } 405 }
447 break; 406 break;
448 407
449 default: 408 default:
450 break; 409 break;
451 } 410 }
452 return FALSE; 411 return -1;
453 }
454
455 // Let the focused widget have first crack at the key event so we don't
456 // override their accelerators.
457 gboolean OnKeyPress(GtkWindow* window, GdkEventKey* event, Browser* browser) {
458 // If a widget besides the native view is focused, we have to try to handle
459 // the custom accelerators before letting it handle them.
460 TabContents* current_tab_contents =
461 browser->tabstrip_model()->GetSelectedTabContents();
462 // The current tab might not have a render view if it crashed.
463 if (!current_tab_contents || !current_tab_contents->GetContentNativeView() ||
464 !gtk_widget_is_focus(current_tab_contents->GetContentNativeView())) {
465 if (HandleCustomAccelerator(event->keyval,
466 GdkModifierType(event->state), browser) ||
467 PreHandleAccelerator(event->keyval,
468 GdkModifierType(event->state), browser)) {
469 return TRUE;
470 }
471
472 // Propagate the key event to child widget first, so we don't override their
473 // accelerators.
474 if (!gtk_window_propagate_key_event(window, event)) {
475 if (!gtk_window_activate_key(window, event)) {
476 gtk_bindings_activate_event(GTK_OBJECT(window), event);
477 }
478 }
479 } else {
480 bool rv = gtk_window_propagate_key_event(window, event);
481 DCHECK(rv);
482 }
483
484 // Prevents the default handler from handling this event.
485 return TRUE;
486 } 412 }
487 413
488 GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) { 414 GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) {
489 switch (edge) { 415 switch (edge) {
490 case GDK_WINDOW_EDGE_NORTH_WEST: 416 case GDK_WINDOW_EDGE_NORTH_WEST:
491 return GDK_TOP_LEFT_CORNER; 417 return GDK_TOP_LEFT_CORNER;
492 case GDK_WINDOW_EDGE_NORTH: 418 case GDK_WINDOW_EDGE_NORTH:
493 return GDK_TOP_SIDE; 419 return GDK_TOP_SIDE;
494 case GDK_WINDOW_EDGE_NORTH_EAST: 420 case GDK_WINDOW_EDGE_NORTH_EAST:
495 return GDK_TOP_RIGHT_CORNER; 421 return GDK_TOP_RIGHT_CORNER;
(...skipping 25 matching lines...) Expand all
521 GdkScreen* screen = gdk_screen_get_default(); 447 GdkScreen* screen = gdk_screen_get_default();
522 if (width == gdk_screen_get_width(screen) && 448 if (width == gdk_screen_get_width(screen) &&
523 height == gdk_screen_get_height(screen)) { 449 height == gdk_screen_get_height(screen)) {
524 // Adjust the height so we don't trigger the WM feature. 450 // Adjust the height so we don't trigger the WM feature.
525 gtk_window_resize(window, width, height - 1); 451 gtk_window_resize(window, width, height - 1);
526 } else { 452 } else {
527 gtk_window_resize(window, width, height); 453 gtk_window_resize(window, width, height);
528 } 454 }
529 } 455 }
530 456
457 GQuark GetBrowserWindowQuarkKey() {
458 static GQuark quark = g_quark_from_static_string(kBrowserWindowKey);
459 return quark;
460 }
461
462 // Checks if a reserved accelerator key should be processed immediately, rather
463 // than being sent to the renderer first.
464 bool ShouldExecuteReservedCommandImmediately(
465 const NativeWebKeyboardEvent& event, int command_id) {
466 // IDC_EXIT is now only bound to Ctrl+Shift+q, so we should always execute it
467 // immediately.
468 if (command_id == IDC_EXIT)
469 return true;
470
471 // Keys like Ctrl+w, Ctrl+n, etc. should always be sent to the renderer first,
472 // otherwise some web apps or the Emacs key bindings may not work correctly.
473 int vkey = event.windowsKeyCode;
474 if ((vkey >= base::VKEY_0 && vkey <= base::VKEY_9) ||
475 (vkey >= base::VKEY_A && vkey <= base::VKEY_Z))
476 return false;
477
478 // All other reserved accelerators should be processed immediately.
479 return true;
480 }
481
531 } // namespace 482 } // namespace
532 483
533 std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_; 484 std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_;
534 485
535 #if defined(OS_CHROMEOS) 486 #if defined(OS_CHROMEOS)
536 // Default to using the regular window style. 487 // Default to using the regular window style.
537 bool BrowserWindowGtk::next_window_should_use_compact_nav_ = false; 488 bool BrowserWindowGtk::next_window_should_use_compact_nav_ = false;
538 #endif 489 #endif
539 490
540 BrowserWindowGtk::BrowserWindowGtk(Browser* browser) 491 BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
541 : browser_(browser), 492 : browser_(browser),
542 state_(GDK_WINDOW_STATE_WITHDRAWN), 493 state_(GDK_WINDOW_STATE_WITHDRAWN),
543 #if defined(OS_CHROMEOS) 494 #if defined(OS_CHROMEOS)
544 drag_active_(false), 495 drag_active_(false),
545 panel_controller_(NULL), 496 panel_controller_(NULL),
546 compact_navigation_bar_(NULL), 497 compact_navigation_bar_(NULL),
547 status_area_(NULL), 498 status_area_(NULL),
548 main_menu_button_(NULL), 499 main_menu_button_(NULL),
549 compact_navbar_hbox_(NULL), 500 compact_navbar_hbox_(NULL),
550 #endif 501 #endif
551 frame_cursor_(NULL), 502 frame_cursor_(NULL),
552 is_active_(true), 503 is_active_(true),
553 last_click_time_(0), 504 last_click_time_(0),
554 maximize_after_show_(false), 505 maximize_after_show_(false),
555 accel_group_(NULL) { 506 accel_group_(NULL) {
556 use_custom_frame_pref_.Init(prefs::kUseCustomChromeFrame, 507 use_custom_frame_pref_.Init(prefs::kUseCustomChromeFrame,
557 browser_->profile()->GetPrefs(), this); 508 browser_->profile()->GetPrefs(), this);
558 509
559 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); 510 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
560 g_object_set_data(G_OBJECT(window_), kBrowserWindowKey, this); 511 g_object_set_qdata(G_OBJECT(window_), GetBrowserWindowQuarkKey(), this);
561 gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK | 512 gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK |
562 GDK_POINTER_MOTION_MASK); 513 GDK_POINTER_MOTION_MASK);
563 514
564 // Add this window to its own unique window group to allow for 515 // Add this window to its own unique window group to allow for
565 // window-to-parent modality. 516 // window-to-parent modality.
566 gtk_window_group_add_window(gtk_window_group_new(), window_); 517 gtk_window_group_add_window(gtk_window_group_new(), window_);
567 g_object_unref(gtk_window_get_group(window_)); 518 g_object_unref(gtk_window_get_group(window_));
568 519
569 // For popups, we initialize widgets then set the window geometry, because 520 // For popups, we initialize widgets then set the window geometry, because
570 // popups need the widgets inited before they can set the window size 521 // popups need the widgets inited before they can set the window size
(...skipping 23 matching lines...) Expand all
594 ActiveWindowWatcherX::RemoveObserver(this); 545 ActiveWindowWatcherX::RemoveObserver(this);
595 546
596 browser_->tabstrip_model()->RemoveObserver(this); 547 browser_->tabstrip_model()->RemoveObserver(this);
597 548
598 if (frame_cursor_) { 549 if (frame_cursor_) {
599 gdk_cursor_unref(frame_cursor_); 550 gdk_cursor_unref(frame_cursor_);
600 frame_cursor_ = NULL; 551 frame_cursor_ = NULL;
601 } 552 }
602 } 553 }
603 554
604 bool BrowserWindowGtk::HandleKeyboardEvent(GdkEventKey* event) {
605 // Handles a key event in following sequence:
606 // 1. Our special key accelerators, such as ctrl-tab, etc.
607 // 2. Gtk mnemonics and accelerators.
608 // This sequence matches the default key press handler of GtkWindow.
609 //
610 // It's not necessary to care about the keyboard layout, as
611 // gtk_window_activate_key() takes care of it automatically.
612 if (!HandleCustomAccelerator(event->keyval, GdkModifierType(event->state),
613 browser_.get())) {
614 return gtk_window_activate_key(window_, event);
615 }
616 return true;
617 }
618
619 gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget, 555 gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget,
620 GdkEventExpose* event, 556 GdkEventExpose* event,
621 BrowserWindowGtk* window) { 557 BrowserWindowGtk* window) {
622 GtkThemeProvider* theme_provider = GtkThemeProvider::GetFrom( 558 GtkThemeProvider* theme_provider = GtkThemeProvider::GetFrom(
623 window->browser()->profile()); 559 window->browser()->profile());
624 560
625 // Draw the default background. 561 // Draw the default background.
626 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); 562 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
627 cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, 563 cairo_rectangle(cr, event->area.x, event->area.y, event->area.width,
628 event->area.height); 564 event->area.height);
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 // (Alt+e). We connect the accelerator directly to the widget in 1138 // (Alt+e). We connect the accelerator directly to the widget in
1203 // BrowserToolbarGtk. 1139 // BrowserToolbarGtk.
1204 } 1140 }
1205 1141
1206 void BrowserWindowGtk::ShowAppMenu() { 1142 void BrowserWindowGtk::ShowAppMenu() {
1207 // On Windows, this is used to show the page menu for a keyboard accelerator 1143 // On Windows, this is used to show the page menu for a keyboard accelerator
1208 // (Alt+f). We connect the accelerator directly to the widget in 1144 // (Alt+f). We connect the accelerator directly to the widget in
1209 // BrowserToolbarGtk. 1145 // BrowserToolbarGtk.
1210 } 1146 }
1211 1147
1212 int BrowserWindowGtk::GetCommandId(const NativeWebKeyboardEvent& event) { 1148 bool BrowserWindowGtk::PreHandleKeyboardEvent(
1213 if (!event.os_event) 1149 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
1214 return -1; 1150 GdkEventKey* os_event = event.os_event;
1215 1151
1216 guint keyval = event.os_event->keyval; 1152 if (!os_event || event.type != WebKit::WebInputEvent::RawKeyDown)
1217 GdkModifierType modifier = GdkModifierType(event.os_event->state); 1153 return false;
1218 int command = ::GetCommandId(keyval, modifier); 1154
1219 if (command == -1) 1155 // We first find out the browser command associated to the |event|.
1220 command = GetCustomCommandId(keyval, modifier); 1156 // Then if the command is a reserved one, and should be processed immediately
1221 return command; 1157 // according to the |event|, the command will be executed immediately.
1158 // Otherwise we just set |*is_keyboard_shortcut| properly and return false.
1159
1160 // First check if it's a custom accelerator.
1161 int id = GetCustomCommandId(os_event);
1162
1163 // Then check if it's a predefined accelerator bound to the window.
1164 if (id == -1) {
1165 // This piece of code is based on the fact that calling
1166 // gtk_window_activate_key() method against |window_| may only trigger a
1167 // browser command execution, by matching either a global accelerator
1168 // defined in above |kAcceleratorMap| or the accelerator key of a menu
1169 // item defined in chrome/browser/gtk/standard_menus.cc.
1170 //
1171 // Here we need to retrieve the command id (if any) associated to the
1172 // keyboard event. Instead of looking up the command id in above
1173 // |kAcceleratorMap| table by ourselves, we block the command execution of
1174 // the |browser_| object then send the keyboard event to the |window_| by
1175 // calling gtk_window_activate_key() method, as if we are activating an
1176 // accelerator key. Then we can retrieve the command id from the
1177 // |browser_| object.
1178 //
1179 // Pros of this approach:
1180 // 1. We can handle accelerators defined not only in above
1181 // |kAcceleratorMap| table, but also those in standard_menus.cc.
1182 // 2. We don't need to care about keyboard layout problem, as
1183 // gtk_window_activate_key() method handles it for us.
1184 //
1185 // Cons:
1186 // 1. The logic is a little complicated.
1187 // 2. We should be careful not to introduce any accelerators that trigger
1188 // customized code instead of browser commands.
1189 browser_->SetBlockCommandExecution(true);
1190 gtk_window_activate_key(window_, os_event);
1191 // We don't need to care about the WindowOpenDisposition value,
1192 // because all commands executed in this path use the default value.
1193 id = browser_->GetLastBlockedCommand(NULL);
1194 browser_->SetBlockCommandExecution(false);
1195 }
1196
1197 if (id == -1)
1198 return false;
1199
1200 if (browser_->IsReservedCommand(id) &&
1201 ShouldExecuteReservedCommandImmediately(event, id)) {
1202 // Executing the command may cause |this| object to be destroyed.
1203 return ExecuteBrowserCommand(id);
1204 }
1205
1206 // The |event| is a keyboard shortcut.
1207 DCHECK(is_keyboard_shortcut != NULL);
1208 *is_keyboard_shortcut = true;
1209
1210 return false;
1211 }
1212
1213 void BrowserWindowGtk::HandleKeyboardEvent(
1214 const NativeWebKeyboardEvent& event) {
1215 GdkEventKey* os_event = event.os_event;
1216
1217 if (!os_event || event.type != WebKit::WebInputEvent::RawKeyDown)
1218 return;
1219
1220 // Handles a key event in following sequence:
1221 // 1. Our special key accelerators, such as ctrl-tab, etc.
1222 // 2. Gtk accelerators.
1223 // This sequence matches the default key press handler of GtkWindow.
1224 //
1225 // It's not necessary to care about the keyboard layout, as
1226 // gtk_window_activate_key() takes care of it automatically.
1227 int id = GetCustomCommandId(os_event);
1228 if (id != -1)
1229 ExecuteBrowserCommand(id);
1230 else
1231 gtk_window_activate_key(window_, os_event);
1222 } 1232 }
1223 1233
1224 void BrowserWindowGtk::ShowCreateShortcutsDialog(TabContents* tab_contents) { 1234 void BrowserWindowGtk::ShowCreateShortcutsDialog(TabContents* tab_contents) {
1225 SkBitmap bitmap; 1235 SkBitmap bitmap;
1226 if (tab_contents->FavIconIsValid()) 1236 if (tab_contents->FavIconIsValid())
1227 bitmap = tab_contents->GetFavIcon(); 1237 bitmap = tab_contents->GetFavIcon();
1228 CreateApplicationShortcutsDialogGtk::Show(window_, 1238 CreateApplicationShortcutsDialogGtk::Show(window_,
1229 tab_contents->GetURL(), 1239 tab_contents->GetURL(),
1230 tab_contents->GetTitle(), 1240 tab_contents->GetTitle(),
1231 bitmap); 1241 bitmap);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 gdk_cursor_unref(frame_cursor_); 1547 gdk_cursor_unref(frame_cursor_);
1538 frame_cursor_ = NULL; 1548 frame_cursor_ = NULL;
1539 gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL); 1549 gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL);
1540 } 1550 }
1541 1551
1542 // static 1552 // static
1543 BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow( 1553 BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow(
1544 gfx::NativeWindow window) { 1554 gfx::NativeWindow window) {
1545 if (window) { 1555 if (window) {
1546 return static_cast<BrowserWindowGtk*>( 1556 return static_cast<BrowserWindowGtk*>(
1547 g_object_get_data(G_OBJECT(window), kBrowserWindowKey)); 1557 g_object_get_qdata(G_OBJECT(window), GetBrowserWindowQuarkKey()));
1548 } 1558 }
1549 1559
1550 return NULL; 1560 return NULL;
1551 } 1561 }
1552 1562
1553 // static 1563 // static
1554 GtkWindow* BrowserWindowGtk::GetBrowserWindowForXID(XID xid) { 1564 GtkWindow* BrowserWindowGtk::GetBrowserWindowForXID(XID xid) {
1555 std::map<XID, GtkWindow*>::iterator iter = 1565 std::map<XID, GtkWindow*>::iterator iter =
1556 BrowserWindowGtk::xid_map_.find(xid); 1566 BrowserWindowGtk::xid_map_.find(xid);
1557 return (iter != BrowserWindowGtk::xid_map_.end()) ? iter->second : NULL; 1567 return (iter != BrowserWindowGtk::xid_map_.end()) ? iter->second : NULL;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 G_CALLBACK(MainWindowDestroy), this); 1631 G_CALLBACK(MainWindowDestroy), this);
1622 g_signal_connect(window_, "configure-event", 1632 g_signal_connect(window_, "configure-event",
1623 G_CALLBACK(MainWindowConfigured), this); 1633 G_CALLBACK(MainWindowConfigured), this);
1624 g_signal_connect(window_, "window-state-event", 1634 g_signal_connect(window_, "window-state-event",
1625 G_CALLBACK(MainWindowStateChanged), this); 1635 G_CALLBACK(MainWindowStateChanged), this);
1626 g_signal_connect(window_, "map", 1636 g_signal_connect(window_, "map",
1627 G_CALLBACK(MainWindowMapped), this); 1637 G_CALLBACK(MainWindowMapped), this);
1628 g_signal_connect(window_, "unmap", 1638 g_signal_connect(window_, "unmap",
1629 G_CALLBACK(MainWindowUnMapped), this); 1639 G_CALLBACK(MainWindowUnMapped), this);
1630 g_signal_connect(window_, "key-press-event", 1640 g_signal_connect(window_, "key-press-event",
1631 G_CALLBACK(OnKeyPress), browser_.get()); 1641 G_CALLBACK(OnKeyPress), this);
1632 g_signal_connect(window_, "motion-notify-event", 1642 g_signal_connect(window_, "motion-notify-event",
1633 G_CALLBACK(OnMouseMoveEvent), this); 1643 G_CALLBACK(OnMouseMoveEvent), this);
1634 g_signal_connect(window_, "button-press-event", 1644 g_signal_connect(window_, "button-press-event",
1635 G_CALLBACK(OnButtonPressEvent), this); 1645 G_CALLBACK(OnButtonPressEvent), this);
1636 g_signal_connect(window_, "focus-in-event", 1646 g_signal_connect(window_, "focus-in-event",
1637 G_CALLBACK(OnFocusIn), this); 1647 G_CALLBACK(OnFocusIn), this);
1638 g_signal_connect(window_, "focus-out-event", 1648 g_signal_connect(window_, "focus-out-event",
1639 G_CALLBACK(OnFocusOut), this); 1649 G_CALLBACK(OnFocusOut), this);
1640 } 1650 }
1641 1651
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 void BrowserWindowGtk::ConnectAccelerators() { 1949 void BrowserWindowGtk::ConnectAccelerators() {
1940 accel_group_ = gtk_accel_group_new(); 1950 accel_group_ = gtk_accel_group_new();
1941 gtk_window_add_accel_group(window_, accel_group_); 1951 gtk_window_add_accel_group(window_, accel_group_);
1942 1952
1943 for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) { 1953 for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) {
1944 gtk_accel_group_connect( 1954 gtk_accel_group_connect(
1945 accel_group_, 1955 accel_group_,
1946 kAcceleratorMap[i].keyval, 1956 kAcceleratorMap[i].keyval,
1947 kAcceleratorMap[i].modifier_type, 1957 kAcceleratorMap[i].modifier_type,
1948 GtkAccelFlags(0), 1958 GtkAccelFlags(0),
1949 g_cclosure_new(G_CALLBACK(OnGtkAccelerator), this, NULL)); 1959 g_cclosure_new(G_CALLBACK(OnGtkAccelerator),
1960 GINT_TO_POINTER(kAcceleratorMap[i].command_id), NULL));
1950 } 1961 }
1951 } 1962 }
1952 1963
1953 void BrowserWindowGtk::UpdateCustomFrame() { 1964 void BrowserWindowGtk::UpdateCustomFrame() {
1954 gtk_window_set_decorated(window_, !UseCustomFrame()); 1965 gtk_window_set_decorated(window_, !UseCustomFrame());
1955 titlebar_->UpdateCustomFrame(UseCustomFrame() && !IsFullscreen()); 1966 titlebar_->UpdateCustomFrame(UseCustomFrame() && !IsFullscreen());
1956 UpdateWindowShape(bounds_.width(), bounds_.height()); 1967 UpdateWindowShape(bounds_.width(), bounds_.height());
1957 } 1968 }
1958 1969
1959 void BrowserWindowGtk::SaveWindowPosition() { 1970 void BrowserWindowGtk::SaveWindowPosition() {
(...skipping 28 matching lines...) Expand all
1988 window_preferences->SetInteger(L"work_area_top", work_area.y()); 1999 window_preferences->SetInteger(L"work_area_top", work_area.y());
1989 window_preferences->SetInteger(L"work_area_right", work_area.right()); 2000 window_preferences->SetInteger(L"work_area_right", work_area.right());
1990 window_preferences->SetInteger(L"work_area_bottom", work_area.bottom()); 2001 window_preferences->SetInteger(L"work_area_bottom", work_area.bottom());
1991 } 2002 }
1992 2003
1993 // static 2004 // static
1994 gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group, 2005 gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group,
1995 GObject* acceleratable, 2006 GObject* acceleratable,
1996 guint keyval, 2007 guint keyval,
1997 GdkModifierType modifier, 2008 GdkModifierType modifier,
1998 BrowserWindowGtk* browser_window) { 2009 void* user_data) {
1999 int command_id = ::GetCommandId(keyval, modifier); 2010 int command_id = GPOINTER_TO_INT(user_data);
2000 DCHECK_NE(command_id, -1); 2011 BrowserWindowGtk* browser_window =
2001 browser_window->ExecuteBrowserCommand(command_id); 2012 GetBrowserWindowForNativeWindow(GTK_WINDOW(acceleratable));
2013 DCHECK(browser_window != NULL);
2014 return browser_window->ExecuteBrowserCommand(command_id);
2015 }
2002 2016
2017 // static
2018 // Let the focused widget have first crack at the key event so we don't
2019 // override their accelerators.
2020 gboolean BrowserWindowGtk::OnKeyPress(
2021 GtkWidget* widget, GdkEventKey* event, BrowserWindowGtk* window) {
2022 // If a widget besides the native view is focused, we have to try to handle
2023 // the custom accelerators before letting it handle them.
2024 TabContents* current_tab_contents =
2025 window->browser()->tabstrip_model()->GetSelectedTabContents();
2026 // The current tab might not have a render view if it crashed.
2027 if (!current_tab_contents || !current_tab_contents->GetContentNativeView() ||
2028 !gtk_widget_is_focus(current_tab_contents->GetContentNativeView())) {
2029 int command_id = GetCustomCommandId(event);
2030 if (command_id == -1)
2031 command_id = GetPreHandleCommandId(event);
2032
2033 if (command_id != -1 && window->ExecuteBrowserCommand(command_id))
2034 return TRUE;
2035
2036 // Propagate the key event to child widget first, so we don't override their
2037 // accelerators.
2038 if (!gtk_window_propagate_key_event(GTK_WINDOW(widget), event)) {
2039 if (!gtk_window_activate_key(GTK_WINDOW(widget), event)) {
2040 gtk_bindings_activate_event(GTK_OBJECT(widget), event);
2041 }
2042 }
2043 } else {
2044 bool rv = gtk_window_propagate_key_event(GTK_WINDOW(widget), event);
2045 DCHECK(rv);
2046 }
2047
2048 // Prevents the default handler from handling this event.
2003 return TRUE; 2049 return TRUE;
2004 } 2050 }
2005 2051
2006 // static 2052 // static
2007 gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget, 2053 gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget,
2008 GdkEventMotion* event, BrowserWindowGtk* browser) { 2054 GdkEventMotion* event, BrowserWindowGtk* window) {
2009 // This method is used to update the mouse cursor when over the edge of the 2055 // This method is used to update the mouse cursor when over the edge of the
2010 // custom frame. If the custom frame is off or we're over some other widget, 2056 // custom frame. If the custom frame is off or we're over some other widget,
2011 // do nothing. 2057 // do nothing.
2012 if (!browser->UseCustomFrame() || event->window != widget->window) { 2058 if (!window->UseCustomFrame() || event->window != widget->window) {
2013 // Reset the cursor. 2059 // Reset the cursor.
2014 if (browser->frame_cursor_) { 2060 if (window->frame_cursor_) {
2015 gdk_cursor_unref(browser->frame_cursor_); 2061 gdk_cursor_unref(window->frame_cursor_);
2016 browser->frame_cursor_ = NULL; 2062 window->frame_cursor_ = NULL;
2017 gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window, NULL); 2063 gdk_window_set_cursor(GTK_WIDGET(window->window_)->window, NULL);
2018 } 2064 }
2019 return FALSE; 2065 return FALSE;
2020 } 2066 }
2021 2067
2022 // Update the cursor if we're on the custom frame border. 2068 // Update the cursor if we're on the custom frame border.
2023 GdkWindowEdge edge; 2069 GdkWindowEdge edge;
2024 bool has_hit_edge = browser->GetWindowEdge(static_cast<int>(event->x), 2070 bool has_hit_edge = window->GetWindowEdge(static_cast<int>(event->x),
2025 static_cast<int>(event->y), &edge); 2071 static_cast<int>(event->y), &edge);
2026 GdkCursorType new_cursor = GDK_LAST_CURSOR; 2072 GdkCursorType new_cursor = GDK_LAST_CURSOR;
2027 if (has_hit_edge) 2073 if (has_hit_edge)
2028 new_cursor = GdkWindowEdgeToGdkCursorType(edge); 2074 new_cursor = GdkWindowEdgeToGdkCursorType(edge);
2029 2075
2030 GdkCursorType last_cursor = GDK_LAST_CURSOR; 2076 GdkCursorType last_cursor = GDK_LAST_CURSOR;
2031 if (browser->frame_cursor_) 2077 if (window->frame_cursor_)
2032 last_cursor = browser->frame_cursor_->type; 2078 last_cursor = window->frame_cursor_->type;
2033 2079
2034 if (last_cursor != new_cursor) { 2080 if (last_cursor != new_cursor) {
2035 if (browser->frame_cursor_) { 2081 if (window->frame_cursor_) {
2036 gdk_cursor_unref(browser->frame_cursor_); 2082 gdk_cursor_unref(window->frame_cursor_);
2037 browser->frame_cursor_ = NULL; 2083 window->frame_cursor_ = NULL;
2038 } 2084 }
2039 if (has_hit_edge) { 2085 if (has_hit_edge) {
2040 browser->frame_cursor_ = gtk_util::GetCursor(new_cursor); 2086 window->frame_cursor_ = gtk_util::GetCursor(new_cursor);
2041 gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window, 2087 gdk_window_set_cursor(GTK_WIDGET(window->window_)->window,
2042 browser->frame_cursor_); 2088 window->frame_cursor_);
2043 } else { 2089 } else {
2044 gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window, NULL); 2090 gdk_window_set_cursor(GTK_WIDGET(window->window_)->window, NULL);
2045 } 2091 }
2046 } 2092 }
2047 return FALSE; 2093 return FALSE;
2048 } 2094 }
2049 2095
2050 // static 2096 // static
2051 gboolean BrowserWindowGtk::OnButtonPressEvent(GtkWidget* widget, 2097 gboolean BrowserWindowGtk::OnButtonPressEvent(GtkWidget* widget,
2052 GdkEventButton* event, BrowserWindowGtk* browser) { 2098 GdkEventButton* event, BrowserWindowGtk* window) {
2053 // Handle back/forward. 2099 // Handle back/forward.
2054 // TODO(jhawkins): Investigate the possibility of the button numbers being 2100 // TODO(jhawkins): Investigate the possibility of the button numbers being
2055 // different for other mice. 2101 // different for other mice.
2056 if (event->button == 8) { 2102 if (event->button == 8) {
2057 browser->browser_->GoBack(CURRENT_TAB); 2103 window->browser_->GoBack(CURRENT_TAB);
2058 return TRUE; 2104 return TRUE;
2059 } else if (event->button == 9) { 2105 } else if (event->button == 9) {
2060 browser->browser_->GoForward(CURRENT_TAB); 2106 window->browser_->GoForward(CURRENT_TAB);
2061 return TRUE; 2107 return TRUE;
2062 } 2108 }
2063 2109
2064 // Handle left, middle and right clicks. In particular, we care about clicks 2110 // Handle left, middle and right clicks. In particular, we care about clicks
2065 // in the custom frame border and clicks in the titlebar. 2111 // in the custom frame border and clicks in the titlebar.
2066 2112
2067 // Make the button press coordinate relative to the browser window. 2113 // Make the button press coordinate relative to the browser window.
2068 int win_x, win_y; 2114 int win_x, win_y;
2069 gdk_window_get_origin(GTK_WIDGET(browser->window_)->window, &win_x, &win_y); 2115 gdk_window_get_origin(GTK_WIDGET(window->window_)->window, &win_x, &win_y);
2070 2116
2071 GdkWindowEdge edge; 2117 GdkWindowEdge edge;
2072 gfx::Point point(static_cast<int>(event->x_root - win_x), 2118 gfx::Point point(static_cast<int>(event->x_root - win_x),
2073 static_cast<int>(event->y_root - win_y)); 2119 static_cast<int>(event->y_root - win_y));
2074 bool has_hit_edge = browser->GetWindowEdge(point.x(), point.y(), &edge); 2120 bool has_hit_edge = window->GetWindowEdge(point.x(), point.y(), &edge);
2075 2121
2076 // Ignore clicks that are in/below the browser toolbar. 2122 // Ignore clicks that are in/below the browser toolbar.
2077 GtkWidget* toolbar = browser->toolbar_->widget(); 2123 GtkWidget* toolbar = window->toolbar_->widget();
2078 if (!GTK_WIDGET_VISIBLE(toolbar)) { 2124 if (!GTK_WIDGET_VISIBLE(toolbar)) {
2079 // If the toolbar is not showing, use the location of web contents as the 2125 // If the toolbar is not showing, use the location of web contents as the
2080 // boundary of where to ignore clicks. 2126 // boundary of where to ignore clicks.
2081 toolbar = browser->render_area_vbox_; 2127 toolbar = window->render_area_vbox_;
2082 } 2128 }
2083 gint toolbar_y; 2129 gint toolbar_y;
2084 gtk_widget_get_pointer(toolbar, NULL, &toolbar_y); 2130 gtk_widget_get_pointer(toolbar, NULL, &toolbar_y);
2085 bool has_hit_titlebar = !browser->IsFullscreen() && (toolbar_y < 0) 2131 bool has_hit_titlebar = !window->IsFullscreen() && (toolbar_y < 0)
2086 && !has_hit_edge; 2132 && !has_hit_edge;
2087 if (event->button == 1) { 2133 if (event->button == 1) {
2088 if (GDK_BUTTON_PRESS == event->type) { 2134 if (GDK_BUTTON_PRESS == event->type) {
2089 guint32 last_click_time = browser->last_click_time_; 2135 guint32 last_click_time = window->last_click_time_;
2090 gfx::Point last_click_position = browser->last_click_position_; 2136 gfx::Point last_click_position = window->last_click_position_;
2091 browser->last_click_time_ = event->time; 2137 window->last_click_time_ = event->time;
2092 browser->last_click_position_ = gfx::Point(static_cast<int>(event->x), 2138 window->last_click_position_ = gfx::Point(static_cast<int>(event->x),
2093 static_cast<int>(event->y)); 2139 static_cast<int>(event->y));
2094 2140
2095 // Raise the window after a click on either the titlebar or the border to 2141 // Raise the window after a click on either the titlebar or the border to
2096 // match the behavior of most window managers. 2142 // match the behavior of most window managers.
2097 if (has_hit_titlebar || has_hit_edge) 2143 if (has_hit_titlebar || has_hit_edge)
2098 gdk_window_raise(GTK_WIDGET(browser->window_)->window); 2144 gdk_window_raise(GTK_WIDGET(window->window_)->window);
2099 2145
2100 if (has_hit_titlebar) { 2146 if (has_hit_titlebar) {
2101 // We want to start a move when the user single clicks, but not start a 2147 // We want to start a move when the user single clicks, but not start a
2102 // move when the user double clicks. However, a double click sends the 2148 // move when the user double clicks. However, a double click sends the
2103 // following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE, 2149 // following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE,
2104 // GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we 2150 // GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we
2105 // start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS, 2151 // start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS,
2106 // the call to gtk_window_maximize fails. To work around this, we 2152 // the call to gtk_window_maximize fails. To work around this, we
2107 // keep track of the last click and if it's going to be a double click, 2153 // keep track of the last click and if it's going to be a double click,
2108 // we don't call gtk_window_begin_move_drag. 2154 // we don't call gtk_window_begin_move_drag.
2109 static GtkSettings* settings = gtk_settings_get_default(); 2155 static GtkSettings* settings = gtk_settings_get_default();
2110 gint double_click_time = 250; 2156 gint double_click_time = 250;
2111 gint double_click_distance = 5; 2157 gint double_click_distance = 5;
2112 g_object_get(G_OBJECT(settings), 2158 g_object_get(G_OBJECT(settings),
2113 "gtk-double-click-time", &double_click_time, 2159 "gtk-double-click-time", &double_click_time,
2114 "gtk-double-click-distance", &double_click_distance, 2160 "gtk-double-click-distance", &double_click_distance,
2115 NULL); 2161 NULL);
2116 2162
2117 guint32 click_time = event->time - last_click_time; 2163 guint32 click_time = event->time - last_click_time;
2118 int click_move_x = static_cast<int>(event->x - last_click_position.x()); 2164 int click_move_x = static_cast<int>(event->x - last_click_position.x());
2119 int click_move_y = static_cast<int>(event->y - last_click_position.y()); 2165 int click_move_y = static_cast<int>(event->y - last_click_position.y());
2120 2166
2121 if (click_time > static_cast<guint32>(double_click_time) || 2167 if (click_time > static_cast<guint32>(double_click_time) ||
2122 click_move_x > double_click_distance || 2168 click_move_x > double_click_distance ||
2123 click_move_y > double_click_distance) { 2169 click_move_y > double_click_distance) {
2124 gtk_window_begin_move_drag(browser->window_, event->button, 2170 gtk_window_begin_move_drag(window->window_, event->button,
2125 static_cast<gint>(event->x_root), 2171 static_cast<gint>(event->x_root),
2126 static_cast<gint>(event->y_root), 2172 static_cast<gint>(event->y_root),
2127 event->time); 2173 event->time);
2128 return TRUE; 2174 return TRUE;
2129 } 2175 }
2130 } else if (has_hit_edge) { 2176 } else if (has_hit_edge) {
2131 gtk_window_begin_resize_drag(browser->window_, edge, event->button, 2177 gtk_window_begin_resize_drag(window->window_, edge, event->button,
2132 static_cast<gint>(event->x_root), 2178 static_cast<gint>(event->x_root),
2133 static_cast<gint>(event->y_root), 2179 static_cast<gint>(event->y_root),
2134 event->time); 2180 event->time);
2135 return TRUE; 2181 return TRUE;
2136 } 2182 }
2137 } else if (GDK_2BUTTON_PRESS == event->type) { 2183 } else if (GDK_2BUTTON_PRESS == event->type) {
2138 if (has_hit_titlebar) { 2184 if (has_hit_titlebar) {
2139 // Maximize/restore on double click. 2185 // Maximize/restore on double click.
2140 if (browser->IsMaximized()) { 2186 if (window->IsMaximized()) {
2141 browser->UnMaximize(); 2187 window->UnMaximize();
2142 } else { 2188 } else {
2143 gtk_window_maximize(browser->window_); 2189 gtk_window_maximize(window->window_);
2144 } 2190 }
2145 return TRUE; 2191 return TRUE;
2146 } 2192 }
2147 } 2193 }
2148 } else if (event->button == 2) { 2194 } else if (event->button == 2) {
2149 if (has_hit_titlebar || has_hit_edge) { 2195 if (has_hit_titlebar || has_hit_edge) {
2150 gdk_window_lower(GTK_WIDGET(browser->window_)->window); 2196 gdk_window_lower(GTK_WIDGET(window->window_)->window);
2151 } 2197 }
2152 return TRUE; 2198 return TRUE;
2153 } else if (event->button == 3) { 2199 } else if (event->button == 3) {
2154 if (has_hit_titlebar) { 2200 if (has_hit_titlebar) {
2155 browser->titlebar_->ShowContextMenu(); 2201 window->titlebar_->ShowContextMenu();
2156 return TRUE; 2202 return TRUE;
2157 } 2203 }
2158 } 2204 }
2159 2205
2160 return FALSE; // Continue to propagate the event. 2206 return FALSE; // Continue to propagate the event.
2161 } 2207 }
2162 2208
2163 // static 2209 // static
2164 void BrowserWindowGtk::MainWindowMapped(GtkWidget* widget, 2210 void BrowserWindowGtk::MainWindowMapped(GtkWidget* widget,
2165 BrowserWindowGtk* window) { 2211 BrowserWindowGtk* window) {
2166 // Map the X Window ID of the window to our window. 2212 // Map the X Window ID of the window to our window.
2167 XID xid = x11_util::GetX11WindowFromGtkWidget(widget); 2213 XID xid = x11_util::GetX11WindowFromGtkWidget(widget);
2168 BrowserWindowGtk::xid_map_.insert( 2214 BrowserWindowGtk::xid_map_.insert(
2169 std::pair<XID, GtkWindow*>(xid, GTK_WINDOW(widget))); 2215 std::pair<XID, GtkWindow*>(xid, GTK_WINDOW(widget)));
2170 } 2216 }
2171 2217
2172 // static 2218 // static
2173 void BrowserWindowGtk::MainWindowUnMapped(GtkWidget* widget, 2219 void BrowserWindowGtk::MainWindowUnMapped(GtkWidget* widget,
2174 BrowserWindowGtk* window) { 2220 BrowserWindowGtk* window) {
2175 // Unmap the X Window ID. 2221 // Unmap the X Window ID.
2176 XID xid = x11_util::GetX11WindowFromGtkWidget(widget); 2222 XID xid = x11_util::GetX11WindowFromGtkWidget(widget);
2177 BrowserWindowGtk::xid_map_.erase(xid); 2223 BrowserWindowGtk::xid_map_.erase(xid);
2178 } 2224 }
2179 2225
2180 // static 2226 // static
2181 gboolean BrowserWindowGtk::OnFocusIn(GtkWidget* widget, 2227 gboolean BrowserWindowGtk::OnFocusIn(GtkWidget* widget,
2182 GdkEventFocus* event, 2228 GdkEventFocus* event,
2183 BrowserWindowGtk* browser) { 2229 BrowserWindowGtk* window) {
2184 BrowserList::SetLastActive(browser->browser_.get()); 2230 BrowserList::SetLastActive(window->browser_.get());
2185 #if defined(OS_CHROMEOS) 2231 #if defined(OS_CHROMEOS)
2186 if (browser->panel_controller_) { 2232 if (window->panel_controller_) {
2187 browser->panel_controller_->OnFocusIn(); 2233 window->panel_controller_->OnFocusIn();
2188 } 2234 }
2189 #endif 2235 #endif
2190 return FALSE; 2236 return FALSE;
2191 } 2237 }
2192 2238
2193 // static 2239 // static
2194 gboolean BrowserWindowGtk::OnFocusOut(GtkWidget* widget, 2240 gboolean BrowserWindowGtk::OnFocusOut(GtkWidget* widget,
2195 GdkEventFocus* event, 2241 GdkEventFocus* event,
2196 BrowserWindowGtk* browser) { 2242 BrowserWindowGtk* window) {
2197 #if defined(OS_CHROMEOS) 2243 #if defined(OS_CHROMEOS)
2198 if (browser->panel_controller_) { 2244 if (window->panel_controller_) {
2199 browser->panel_controller_->OnFocusOut(); 2245 window->panel_controller_->OnFocusOut();
2200 } 2246 }
2201 #endif 2247 #endif
2202 return FALSE; 2248 return FALSE;
2203 } 2249 }
2204 2250
2205 void BrowserWindowGtk::ExecuteBrowserCommand(int id) { 2251 bool BrowserWindowGtk::ExecuteBrowserCommand(int id) {
2206 if (browser_->command_updater()->IsCommandEnabled(id)) 2252 if (browser_->command_updater()->IsCommandEnabled(id)) {
2207 browser_->ExecuteCommand(id); 2253 browser_->ExecuteCommand(id);
2254 return true;
2255 }
2256 return false;
2208 } 2257 }
2209 2258
2210 void BrowserWindowGtk::ShowSupportedWindowFeatures() { 2259 void BrowserWindowGtk::ShowSupportedWindowFeatures() {
2211 if (IsTabStripSupported()) 2260 if (IsTabStripSupported())
2212 tabstrip_->Show(); 2261 tabstrip_->Show();
2213 2262
2214 if (IsToolbarSupported()) 2263 if (IsToolbarSupported())
2215 toolbar_->Show(); 2264 toolbar_->Show();
2216 2265
2217 if (IsBookmarkBarSupported()) 2266 if (IsBookmarkBarSupported())
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 // are taken from the WMs' source code. 2399 // are taken from the WMs' source code.
2351 return (wm_name == "Blackbox" || 2400 return (wm_name == "Blackbox" ||
2352 wm_name == "compiz" || 2401 wm_name == "compiz" ||
2353 wm_name == "e16" || // Enlightenment DR16 2402 wm_name == "e16" || // Enlightenment DR16
2354 wm_name == "KWin" || 2403 wm_name == "KWin" ||
2355 wm_name == "Metacity" || 2404 wm_name == "Metacity" ||
2356 wm_name == "Mutter" || 2405 wm_name == "Mutter" ||
2357 wm_name == "Openbox" || 2406 wm_name == "Openbox" ||
2358 wm_name == "Xfwm4"); 2407 wm_name == "Xfwm4");
2359 } 2408 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/browser_window_gtk.h ('k') | chrome/browser/renderer_host/render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698