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