| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/widget/native_widget_gtk.h" | 5 #include "ui/views/widget/native_widget_gtk.h" |
| 6 | 6 |
| 7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
| 9 #include <X11/extensions/shape.h> | 9 #include <X11/extensions/shape.h> |
| 10 #include <gdk/gdk.h> | 10 #include <gdk/gdk.h> |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 ignore_drag_leave_(false), | 348 ignore_drag_leave_(false), |
| 349 opacity_(255), | 349 opacity_(255), |
| 350 drag_data_(NULL), | 350 drag_data_(NULL), |
| 351 window_state_(GDK_WINDOW_STATE_WITHDRAWN), | 351 window_state_(GDK_WINDOW_STATE_WITHDRAWN), |
| 352 is_active_(false), | 352 is_active_(false), |
| 353 transient_to_parent_(false), | 353 transient_to_parent_(false), |
| 354 got_initial_focus_in_(false), | 354 got_initial_focus_in_(false), |
| 355 has_focus_(false), | 355 has_focus_(false), |
| 356 always_on_top_(false), | 356 always_on_top_(false), |
| 357 is_double_buffered_(false), | 357 is_double_buffered_(false), |
| 358 should_handle_menu_key_release_(false), | |
| 359 dragged_view_(NULL), | 358 dragged_view_(NULL), |
| 360 painted_(false), | 359 painted_(false), |
| 361 has_pointer_grab_(false), | 360 has_pointer_grab_(false), |
| 362 has_keyboard_grab_(false), | 361 has_keyboard_grab_(false), |
| 363 grab_notify_signal_id_(0), | 362 grab_notify_signal_id_(0), |
| 364 is_menu_(false), | 363 is_menu_(false), |
| 365 signal_registrar_(new ui::GtkSignalRegistrar) { | 364 signal_registrar_(new ui::GtkSignalRegistrar) { |
| 366 static bool installed_message_loop_observer = false; | 365 static bool installed_message_loop_observer = false; |
| 367 if (!installed_message_loop_observer) { | 366 if (!installed_message_loop_observer) { |
| 368 installed_message_loop_observer = true; | 367 installed_message_loop_observer = true; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 GetWidget()->GetRootView()->SchedulePaint(); | 552 GetWidget()->GetRootView()->SchedulePaint(); |
| 554 } | 553 } |
| 555 } | 554 } |
| 556 | 555 |
| 557 //////////////////////////////////////////////////////////////////////////////// | 556 //////////////////////////////////////////////////////////////////////////////// |
| 558 // NativeWidgetGtk implementation: | 557 // NativeWidgetGtk implementation: |
| 559 | 558 |
| 560 bool NativeWidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { | 559 bool NativeWidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { |
| 561 if (!GetWidget()->GetFocusManager()) | 560 if (!GetWidget()->GetFocusManager()) |
| 562 return false; | 561 return false; |
| 563 | 562 return GetWidget()->GetFocusManager()->OnKeyEvent(key); |
| 564 const int key_code = key.key_code(); | |
| 565 bool handled = false; | |
| 566 | |
| 567 // Always reset |should_handle_menu_key_release_| unless we are handling a | |
| 568 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only | |
| 569 // be activated when handling a VKEY_MENU key release event which is preceded | |
| 570 // by an un-handled VKEY_MENU key press event. | |
| 571 if (key_code != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED) | |
| 572 should_handle_menu_key_release_ = false; | |
| 573 | |
| 574 if (key.type() == ui::ET_KEY_PRESSED) { | |
| 575 // VKEY_MENU is triggered by key release event. | |
| 576 // FocusManager::OnKeyEvent() returns false when the key has been consumed. | |
| 577 if (key_code != ui::VKEY_MENU) | |
| 578 handled = !GetWidget()->GetFocusManager()->OnKeyEvent(key); | |
| 579 else | |
| 580 should_handle_menu_key_release_ = true; | |
| 581 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && | |
| 582 (key.flags() & ~ui::EF_ALT_DOWN) == 0) { | |
| 583 // Trigger VKEY_MENU when only this key is pressed and released, and both | |
| 584 // press and release events are not handled by others. | |
| 585 ui::Accelerator accelerator(ui::VKEY_MENU, false, false, false); | |
| 586 handled = GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator); | |
| 587 } | |
| 588 | |
| 589 return handled; | |
| 590 } | 563 } |
| 591 | 564 |
| 592 bool NativeWidgetGtk::SuppressFreezeUpdates() { | 565 bool NativeWidgetGtk::SuppressFreezeUpdates() { |
| 593 if (!painted_) { | 566 if (!painted_) { |
| 594 painted_ = true; | 567 painted_ = true; |
| 595 return true; | 568 return true; |
| 596 } | 569 } |
| 597 return false; | 570 return false; |
| 598 } | 571 } |
| 599 | 572 |
| (...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 delegate_->OnMouseEvent(mouse_event); | 1570 delegate_->OnMouseEvent(mouse_event); |
| 1598 } | 1571 } |
| 1599 return true; | 1572 return true; |
| 1600 } | 1573 } |
| 1601 | 1574 |
| 1602 gboolean NativeWidgetGtk::OnScroll(GtkWidget* widget, GdkEventScroll* event) { | 1575 gboolean NativeWidgetGtk::OnScroll(GtkWidget* widget, GdkEventScroll* event) { |
| 1603 MouseWheelEvent mouse_event(TransformEvent(event)); | 1576 MouseWheelEvent mouse_event(TransformEvent(event)); |
| 1604 return delegate_->OnMouseEvent(mouse_event); | 1577 return delegate_->OnMouseEvent(mouse_event); |
| 1605 } | 1578 } |
| 1606 | 1579 |
| 1607 gboolean NativeWidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { | 1580 gboolean NativeWidgetGtk::OnFocusIn(GtkWidget* gtk_widget, |
| 1581 GdkEventFocus* event) { |
| 1608 if (has_focus_) | 1582 if (has_focus_) |
| 1609 return false; // This is the second focus-in event in a row, ignore it. | 1583 return false; // This is the second focus-in event in a row, ignore it. |
| 1610 has_focus_ = true; | 1584 has_focus_ = true; |
| 1611 | 1585 |
| 1612 should_handle_menu_key_release_ = false; | 1586 Widget* widget = GetWidget(); |
| 1613 | 1587 |
| 1614 if (!GetWidget()->is_top_level()) | 1588 if (widget->GetFocusManager()) |
| 1589 widget->GetFocusManager()->ResetMenuKeyState(); |
| 1590 |
| 1591 if (!widget->is_top_level()) |
| 1615 return false; | 1592 return false; |
| 1616 | 1593 |
| 1617 // Only top-level Widget should have an InputMethod instance. | 1594 // Only top-level Widget should have an InputMethod instance. |
| 1618 InputMethod* input_method = GetWidget()->GetInputMethod(); | 1595 InputMethod* input_method = widget->GetInputMethod(); |
| 1619 if (input_method) | 1596 if (input_method) |
| 1620 input_method->OnFocus(); | 1597 input_method->OnFocus(); |
| 1621 | 1598 |
| 1622 // See description of got_initial_focus_in_ for details on this. | 1599 // See description of got_initial_focus_in_ for details on this. |
| 1623 if (!got_initial_focus_in_) { | 1600 if (!got_initial_focus_in_) { |
| 1624 got_initial_focus_in_ = true; | 1601 got_initial_focus_in_ = true; |
| 1625 // Sets initial focus here. On X11/Gtk, window creation | 1602 // Sets initial focus here. On X11/Gtk, window creation |
| 1626 // is asynchronous and a focus request has to be made after a window | 1603 // is asynchronous and a focus request has to be made after a window |
| 1627 // gets created. | 1604 // gets created. |
| 1628 GetWidget()->SetInitialFocus(); | 1605 widget->SetInitialFocus(); |
| 1629 } | 1606 } |
| 1630 return false; | 1607 return false; |
| 1631 } | 1608 } |
| 1632 | 1609 |
| 1633 gboolean NativeWidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) { | 1610 gboolean NativeWidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) { |
| 1634 if (!has_focus_) | 1611 if (!has_focus_) |
| 1635 return false; // This is the second focus-out event in a row, ignore it. | 1612 return false; // This is the second focus-out event in a row, ignore it. |
| 1636 has_focus_ = false; | 1613 has_focus_ = false; |
| 1637 | 1614 |
| 1638 if (!GetWidget()->is_top_level()) | 1615 if (!GetWidget()->is_top_level()) |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1763 } | 1740 } |
| 1764 | 1741 |
| 1765 //////////////////////////////////////////////////////////////////////////////// | 1742 //////////////////////////////////////////////////////////////////////////////// |
| 1766 // NativeWidgetGtk, private: | 1743 // NativeWidgetGtk, private: |
| 1767 | 1744 |
| 1768 void NativeWidgetGtk::ScheduleDraw() { | 1745 void NativeWidgetGtk::ScheduleDraw() { |
| 1769 SchedulePaintInRect(gfx::Rect(gfx::Point(), size_)); | 1746 SchedulePaintInRect(gfx::Rect(gfx::Point(), size_)); |
| 1770 } | 1747 } |
| 1771 | 1748 |
| 1772 void NativeWidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { | 1749 void NativeWidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { |
| 1773 // Always reset |should_handle_menu_key_release_| unless we are handling a | 1750 if (GetWidget()->GetFocusManager()) |
| 1774 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only | 1751 GetWidget()->GetFocusManager()->MaybeResetMenuKeyState(key); |
| 1775 // be activated when handling a VKEY_MENU key release event which is preceded | |
| 1776 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent(). | |
| 1777 if (key.key_code() != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED) | |
| 1778 should_handle_menu_key_release_ = false; | |
| 1779 | 1752 |
| 1780 // Send the key event to View hierarchy first. | 1753 // Send the key event to View hierarchy first. |
| 1781 bool handled = delegate_->OnKeyEvent(key); | 1754 bool handled = delegate_->OnKeyEvent(key); |
| 1782 | 1755 |
| 1783 if (key.key_code() == ui::VKEY_PROCESSKEY || handled) | 1756 if (key.key_code() == ui::VKEY_PROCESSKEY || handled) |
| 1784 return; | 1757 return; |
| 1785 | 1758 |
| 1786 // Dispatch the key event to native GtkWidget hierarchy. | 1759 // Dispatch the key event to native GtkWidget hierarchy. |
| 1787 // To prevent GtkWindow from handling the key event as a keybinding, we need | 1760 // To prevent GtkWindow from handling the key event as a keybinding, we need |
| 1788 // to bypass GtkWindow's default key event handler and dispatch the event | 1761 // to bypass GtkWindow's default key event handler and dispatch the event |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2222 button_pressed = event->type == GDK_BUTTON_PRESS || | 2195 button_pressed = event->type == GDK_BUTTON_PRESS || |
| 2223 event->type == GDK_2BUTTON_PRESS || | 2196 event->type == GDK_2BUTTON_PRESS || |
| 2224 event->type == GDK_3BUTTON_PRESS; | 2197 event->type == GDK_3BUTTON_PRESS; |
| 2225 gdk_event_free(event); | 2198 gdk_event_free(event); |
| 2226 } | 2199 } |
| 2227 return button_pressed; | 2200 return button_pressed; |
| 2228 } | 2201 } |
| 2229 | 2202 |
| 2230 } // namespace internal | 2203 } // namespace internal |
| 2231 } // namespace views | 2204 } // namespace views |
| OLD | NEW |