summaryrefslogtreecommitdiffstats
path: root/chrome/views
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-23 20:26:56 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-23 20:26:56 +0000
commitfdc92726554124b1fb8dbb86c4a5f44168945a73 (patch)
tree7c947116f03952f4c440eb5a0adbc1a6478b2198 /chrome/views
parent8205209f3b57a69fe811f18771a533bf01407d7f (diff)
downloadchromium_src-fdc92726554124b1fb8dbb86c4a5f44168945a73.zip
chromium_src-fdc92726554124b1fb8dbb86c4a5f44168945a73.tar.gz
chromium_src-fdc92726554124b1fb8dbb86c4a5f44168945a73.tar.bz2
Deliver events and notifications to the RootView.
Review URL: http://codereview.chromium.org/42519 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12305 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/views')
-rw-r--r--chrome/views/SConscript7
-rw-r--r--chrome/views/event.cc56
-rw-r--r--chrome/views/event.h21
-rw-r--r--chrome/views/event_gtk.cc36
-rw-r--r--chrome/views/event_win.cc63
-rw-r--r--chrome/views/views.vcproj4
-rw-r--r--chrome/views/widget/root_view.cc2
-rw-r--r--chrome/views/widget/root_view_gtk.cc4
-rw-r--r--chrome/views/widget/widget_gtk.cc108
-rw-r--r--chrome/views/widget/widget_gtk.h46
10 files changed, 254 insertions, 93 deletions
diff --git a/chrome/views/SConscript b/chrome/views/SConscript
index 626a420..db986d6 100644
--- a/chrome/views/SConscript
+++ b/chrome/views/SConscript
@@ -185,9 +185,10 @@ if env.Bit('windows'):
if env.Bit('linux'):
input_files += [
- "view_gtk.cc",
- "widget/root_view_gtk.cc",
- "widget/widget_gtk.cc"
+ 'event_gtk.cc',
+ 'view_gtk.cc',
+ 'widget/root_view_gtk.cc',
+ 'widget/widget_gtk.cc'
]
# TODO(port?): Incomplete and undecided Views stuff. These compile but aren't
# currently needed, and they break the shared build due to missing symbols
diff --git a/chrome/views/event.cc b/chrome/views/event.cc
index 242daa2..af603cb 100644
--- a/chrome/views/event.cc
+++ b/chrome/views/event.cc
@@ -19,37 +19,6 @@ Event::Event(EventType type, int flags)
flags_(flags) {
}
-#if defined(OS_WIN)
-int Event::GetWindowsFlags() const {
- // TODO: need support for x1/x2.
- int result = 0;
- result |= (flags_ & EF_SHIFT_DOWN) ? MK_SHIFT : 0;
- result |= (flags_ & EF_CONTROL_DOWN) ? MK_CONTROL : 0;
- result |= (flags_ & EF_LEFT_BUTTON_DOWN) ? MK_LBUTTON : 0;
- result |= (flags_ & EF_MIDDLE_BUTTON_DOWN) ? MK_MBUTTON : 0;
- result |= (flags_ & EF_RIGHT_BUTTON_DOWN) ? MK_RBUTTON : 0;
- return result;
-}
-
-//static
-int Event::ConvertWindowsFlags(UINT win_flags) {
- int r = 0;
- if (win_flags & MK_CONTROL)
- r |= EF_CONTROL_DOWN;
- if (win_flags & MK_SHIFT)
- r |= EF_SHIFT_DOWN;
- if (GetKeyState(VK_MENU) < 0)
- r |= EF_ALT_DOWN;
- if (win_flags & MK_LBUTTON)
- r |= EF_LEFT_BUTTON_DOWN;
- if (win_flags & MK_MBUTTON)
- r |= EF_MIDDLE_BUTTON_DOWN;
- if (win_flags & MK_RBUTTON)
- r |= EF_RIGHT_BUTTON_DOWN;
- return r;
-}
-#endif
-
// static
int Event::ConvertWebInputEventFlags(int web_input_event_flags) {
int r = 0;
@@ -83,30 +52,5 @@ MouseEvent::MouseEvent(const MouseEvent& model, View* from, View* to)
: LocatedEvent(model, from, to) {
}
-
-int KeyEvent::GetKeyStateFlags() const {
-#if defined(OS_WIN)
- // Windows Keyboard messages don't come with control key state as parameters
- // like mouse messages do, so we need to explicitly probe for these key
- // states.
- int flags = 0;
- if (GetKeyState(VK_MENU) & 0x80)
- flags |= Event::EF_ALT_DOWN;
- if (GetKeyState(VK_SHIFT) & 0x80)
- flags |= Event::EF_SHIFT_DOWN;
- if (GetKeyState(VK_CONTROL) & 0x80)
- flags |= Event::EF_CONTROL_DOWN;
- return flags;
-#else
- return 0;
-#endif
-}
-
-#if defined(OS_WIN)
-bool KeyEvent::IsExtendedKey() const {
- return (message_flags_ & KF_EXTENDED) == KF_EXTENDED;
-}
-#endif
-
} // namespace views
diff --git a/chrome/views/event.h b/chrome/views/event.h
index 92f93ef..37524eb 100644
--- a/chrome/views/event.h
+++ b/chrome/views/event.h
@@ -6,6 +6,11 @@
#define CHROME_VIEWS_EVENT_H_
#include "base/basictypes.h"
+
+#if defined(OS_LINUX)
+#include <gdk/gdk.h>
+#endif
+
#include "base/gfx/point.h"
#include "webkit/glue/window_open_disposition.h"
@@ -86,6 +91,9 @@ class Event {
// Convert windows flags to views::Event flags
static int ConvertWindowsFlags(uint32 win_flags);
+#elif defined(OS_LINUX)
+ // Convert the state member on a GdkEvent to views::Event flags
+ static int GetFlagsFromGdkState(int state);
#endif
// Convert WebInputEvent::Modifiers flags to views::Event flags.
@@ -221,13 +229,12 @@ class MouseEvent : public LocatedEvent {
////////////////////////////////////////////////////////////////////////////////
class KeyEvent : public Event {
public:
+#if defined(OS_WIN)
// Create a new key event
- KeyEvent(EventType type, int ch, int repeat_count, int message_flags)
- : Event(type, GetKeyStateFlags()),
- character_(ch),
- repeat_count_(repeat_count),
- message_flags_(message_flags) {
- }
+ KeyEvent(EventType type, int ch, int repeat_count, int message_flags);
+#elif defined(OS_LINUX)
+ KeyEvent(GdkEventKey* event);
+#endif
int GetCharacter() const {
return character_;
@@ -242,7 +249,9 @@ class KeyEvent : public Event {
}
private:
+#if defined(OS_WIN)
int GetKeyStateFlags() const;
+#endif
int character_;
int repeat_count_;
diff --git a/chrome/views/event_gtk.cc b/chrome/views/event_gtk.cc
new file mode 100644
index 0000000..dfe89d2
--- /dev/null
+++ b/chrome/views/event_gtk.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/views/event.h"
+
+namespace views {
+
+KeyEvent::KeyEvent(GdkEventKey* event)
+ : Event(event->type == GDK_KEY_PRESS ?
+ Event::ET_KEY_PRESSED : Event::ET_KEY_RELEASED,
+ GetFlagsFromGdkState(event->state)),
+ // TODO(erg): All these values are iffy.
+ character_(event->keyval),
+ repeat_count_(0),
+ message_flags_(0) {
+}
+
+int Event::GetFlagsFromGdkState(int state) {
+ int flags = 0;
+ if (state & GDK_CONTROL_MASK)
+ flags |= Event::EF_CONTROL_DOWN;
+ if (state & GDK_SHIFT_MASK)
+ flags |= Event::EF_SHIFT_DOWN;
+ if (state & GDK_MOD1_MASK)
+ flags |= Event::EF_ALT_DOWN;
+ if (state & GDK_BUTTON1_MASK)
+ flags |= Event::EF_LEFT_BUTTON_DOWN;
+ if (state & GDK_BUTTON2_MASK)
+ flags |= Event::EF_MIDDLE_BUTTON_DOWN;
+ if (state & GDK_BUTTON3_MASK)
+ flags |= Event::EF_RIGHT_BUTTON_DOWN;
+ return flags;
+}
+
+} // namespace views
diff --git a/chrome/views/event_win.cc b/chrome/views/event_win.cc
new file mode 100644
index 0000000..16449a5
--- /dev/null
+++ b/chrome/views/event_win.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/views/event.h"
+
+namespace views {
+
+int Event::GetWindowsFlags() const {
+ // TODO: need support for x1/x2.
+ int result = 0;
+ result |= (flags_ & EF_SHIFT_DOWN) ? MK_SHIFT : 0;
+ result |= (flags_ & EF_CONTROL_DOWN) ? MK_CONTROL : 0;
+ result |= (flags_ & EF_LEFT_BUTTON_DOWN) ? MK_LBUTTON : 0;
+ result |= (flags_ & EF_MIDDLE_BUTTON_DOWN) ? MK_MBUTTON : 0;
+ result |= (flags_ & EF_RIGHT_BUTTON_DOWN) ? MK_RBUTTON : 0;
+ return result;
+}
+
+//static
+int Event::ConvertWindowsFlags(UINT win_flags) {
+ int r = 0;
+ if (win_flags & MK_CONTROL)
+ r |= EF_CONTROL_DOWN;
+ if (win_flags & MK_SHIFT)
+ r |= EF_SHIFT_DOWN;
+ if (GetKeyState(VK_MENU) < 0)
+ r |= EF_ALT_DOWN;
+ if (win_flags & MK_LBUTTON)
+ r |= EF_LEFT_BUTTON_DOWN;
+ if (win_flags & MK_MBUTTON)
+ r |= EF_MIDDLE_BUTTON_DOWN;
+ if (win_flags & MK_RBUTTON)
+ r |= EF_RIGHT_BUTTON_DOWN;
+ return r;
+}
+
+KeyEvent::KeyEvent(EventType type, int ch, int repeat_count, int message_flags)
+ : Event(type, GetKeyStateFlags()),
+ character_(ch),
+ repeat_count_(repeat_count),
+ message_flags_(message_flags) {
+ }
+
+int KeyEvent::GetKeyStateFlags() const {
+ // Windows Keyboard messages don't come with control key state as parameters
+ // like mouse messages do, so we need to explicitly probe for these key
+ // states.
+ int flags = 0;
+ if (GetKeyState(VK_MENU) & 0x80)
+ flags |= Event::EF_ALT_DOWN;
+ if (GetKeyState(VK_SHIFT) & 0x80)
+ flags |= Event::EF_SHIFT_DOWN;
+ if (GetKeyState(VK_CONTROL) & 0x80)
+ flags |= Event::EF_CONTROL_DOWN;
+ return flags;
+}
+
+bool KeyEvent::IsExtendedKey() const {
+ return (message_flags_ & KF_EXTENDED) == KF_EXTENDED;
+}
+
+} // namespace views
diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj
index 46622b4..01e5770 100644
--- a/chrome/views/views.vcproj
+++ b/chrome/views/views.vcproj
@@ -800,6 +800,10 @@
>
</File>
<File
+ RelativePath=".\event_win.cc"
+ >
+ </File>
+ <File
RelativePath=".\fill_layout.cc"
>
</File>
diff --git a/chrome/views/widget/root_view.cc b/chrome/views/widget/root_view.cc
index 5e6bcc8..e185b4a 100644
--- a/chrome/views/widget/root_view.cc
+++ b/chrome/views/widget/root_view.cc
@@ -403,7 +403,7 @@ void RootView::OnMouseReleased(const MouseEvent& e, bool canceled) {
}
void RootView::OnMouseMoved(const MouseEvent& e) {
- View *v = GetViewForPoint(e.location());
+ View* v = GetViewForPoint(e.location());
// Find the first enabled view.
while (v && !v->IsEnabled())
v = v->GetParent();
diff --git a/chrome/views/widget/root_view_gtk.cc b/chrome/views/widget/root_view_gtk.cc
index 115b37d..241e042 100644
--- a/chrome/views/widget/root_view_gtk.cc
+++ b/chrome/views/widget/root_view_gtk.cc
@@ -21,10 +21,6 @@ void RootView::OnPaint(GdkEventExpose* event) {
SchedulePaint(gfx::Rect(canvas.rectangle()), false);
if (NeedsPainting(false)) {
ProcessPaint(&canvas);
-
- canvas.FillRectInt(SK_ColorRED, 5, 5, 10, 10);
- canvas.FillRectInt(SK_ColorGREEN, 25, 5, 10, 10);
- canvas.FillRectInt(SK_ColorBLUE, 45, 5, 10, 10);
}
}
}
diff --git a/chrome/views/widget/widget_gtk.cc b/chrome/views/widget/widget_gtk.cc
index a2a7b35..9356c85 100644
--- a/chrome/views/widget/widget_gtk.cc
+++ b/chrome/views/widget/widget_gtk.cc
@@ -10,7 +10,9 @@
namespace views {
WidgetGtk::WidgetGtk()
- : widget_(NULL) {
+ : widget_(NULL),
+ is_mouse_down_(false),
+ last_mouse_event_was_move_(false) {
}
WidgetGtk::~WidgetGtk() {
@@ -30,6 +32,17 @@ void WidgetGtk::Init(const gfx::Rect& bounds,
gtk_drawing_area_size(GTK_DRAWING_AREA(widget_), 100, 100);
gtk_widget_show(widget_);
+ // Make sure we receive our motion events.
+ gtk_widget_set_events(widget_,
+ gtk_widget_get_events(widget_) |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK);
+
root_view_->OnWidgetCreated();
// TODO(port): if(has_own_focus_manager) block
@@ -111,6 +124,7 @@ void WidgetGtk::GetBounds(gfx::Rect* out, bool including_frame) const {
void WidgetGtk::MoveToFront(bool should_activate) {
// TODO(erg): I'm not sure about how to do z-ordering on GTK widgets...
+ NOTIMPLEMENTED();
}
gfx::NativeView WidgetGtk::GetNativeView() const {
@@ -118,7 +132,9 @@ gfx::NativeView WidgetGtk::GetNativeView() const {
}
void WidgetGtk::PaintNow(const gfx::Rect& update_rect) {
-
+ // TODO(erg): This is woefully incomplete and is a straw man implementation.
+ gtk_widget_queue_draw_area(widget_, update_rect.x(), update_rect.y(),
+ update_rect.width(), update_rect.height());
}
RootView* WidgetGtk::GetRootView() {
@@ -144,18 +160,106 @@ TooltipManager* WidgetGtk::GetTooltipManager() {
}
bool WidgetGtk::GetAccelerator(int cmd_id, Accelerator* accelerator) {
+ NOTIMPLEMENTED();
return false;
}
+gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) {
+ gfx::Point screen_loc(event->x_root, event->y_root);
+ if (last_mouse_event_was_move_ && last_mouse_move_x_ == screen_loc.x() &&
+ last_mouse_move_y_ == screen_loc.y()) {
+ // Don't generate a mouse event for the same location as the last.
+ return false;
+ }
+ last_mouse_move_x_ = screen_loc.x();
+ last_mouse_move_y_ = screen_loc.y();
+ last_mouse_event_was_move_ = true;
+ MouseEvent mouse_move(Event::ET_MOUSE_MOVED,
+ event->x,
+ event->y,
+ Event::GetFlagsFromGdkState(event->state));
+ root_view_->OnMouseMoved(mouse_move);
+ return true;
+}
+
+gboolean WidgetGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) {
+ return ProcessMousePressed(event);
+}
+
+gboolean WidgetGtk::OnButtonRelease(GtkWidget* widget, GdkEventButton* event) {
+ ProcessMouseReleased(event);
+ return true;
+}
+
gboolean WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
root_view_->OnPaint(event);
return true;
}
+gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) {
+ // TODO(port): We may not actually need this message; it looks like
+ // OnNotificationNotify() takes care of this case...
+ return false;
+}
+
+gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) {
+ last_mouse_event_was_move_ = false;
+ root_view_->ProcessOnMouseExited();
+ return true;
+}
+
+gboolean WidgetGtk::OnKeyPress(GtkWidget* widget, GdkEventKey* event) {
+ KeyEvent key_event(event);
+ return root_view_->ProcessKeyEvent(key_event);
+}
+
+gboolean WidgetGtk::OnKeyRelease(GtkWidget* widget, GdkEventKey* event) {
+ KeyEvent key_event(event);
+ return root_view_->ProcessKeyEvent(key_event);
+}
+
RootView* WidgetGtk::CreateRootView() {
return new RootView(this);
}
+bool WidgetGtk::ProcessMousePressed(GdkEventButton* event) {
+ last_mouse_event_was_move_ = false;
+ MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED,
+ event->x, event->y,
+// (dbl_click ? MouseEvent::EF_IS_DOUBLE_CLICK : 0) |
+ Event::GetFlagsFromGdkState(event->state));
+ if (root_view_->OnMousePressed(mouse_pressed)) {
+ is_mouse_down_ = true;
+ // TODO(port): Enable this once I figure out what capture is.
+ // if (!has_capture_) {
+ // SetCapture();
+ // has_capture_ = true;
+ // current_action_ = FA_FORWARDING;
+ // }
+ return true;
+ }
+
+ return false;
+}
+
+void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) {
+ last_mouse_event_was_move_ = false;
+ MouseEvent mouse_up(Event::ET_MOUSE_RELEASED,
+ event->x, event->y,
+ Event::GetFlagsFromGdkState(event->state));
+ // Release the capture first, that way we don't get confused if
+ // OnMouseReleased blocks.
+ //
+ // TODO(port): Enable this once I figure out what capture is.
+ // if (has_capture_ && ReleaseCaptureOnMouseReleased()) {
+ // has_capture_ = false;
+ // current_action_ = FA_NONE;
+ // ReleaseCapture();
+ // }
+ is_mouse_down_ = false;
+ root_view_->OnMouseReleased(mouse_up, false);
+}
+
// static
WidgetGtk* WidgetGtk::GetViewForNative(GtkWidget* widget) {
gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-views");
diff --git a/chrome/views/widget/widget_gtk.h b/chrome/views/widget/widget_gtk.h
index 9669ba3..9f3c813 100644
--- a/chrome/views/widget/widget_gtk.h
+++ b/chrome/views/widget/widget_gtk.h
@@ -49,33 +49,19 @@ class WidgetGtk : public Widget {
protected:
virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {}
virtual gboolean OnPaint(GtkWidget* widget, GdkEventExpose* event);
- virtual gboolean OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) {
- return false;
- }
- virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) {
- return false;
- }
- virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) {
- return false;
- }
- virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event) {
- return false;
- }
- virtual gboolean OnButtonRelease(GtkWidget* widget, GdkEventButton* event) {
- return false;
- }
+ virtual gboolean OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event);
+ virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event);
+ virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event);
+ virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event);
+ virtual gboolean OnButtonRelease(GtkWidget* widget, GdkEventButton* event);
virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
return false;
}
virtual gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
return false;
}
- virtual gboolean OnKeyPress(GtkWidget* widget, GdkEventKey* event) {
- return false;
- }
- virtual gboolean OnKeyRelease(GtkWidget* widget, GdkEventKey* event) {
- return false;
- }
+ virtual gboolean OnKeyPress(GtkWidget* widget, GdkEventKey* event);
+ virtual gboolean OnKeyRelease(GtkWidget* widget, GdkEventKey* event);
virtual gboolean OnScroll(GtkWidget* widget, GdkEventScroll* event) {
return false;
}
@@ -87,6 +73,10 @@ class WidgetGtk : public Widget {
private:
virtual RootView* CreateRootView();
+ // Process a mouse click
+ bool ProcessMousePressed(GdkEventButton* event);
+ void ProcessMouseReleased(GdkEventButton* event);
+
// Sets and retrieves the WidgetGtk in the userdata section of the widget.
static WidgetGtk* GetViewForNative(GtkWidget* widget);
static void SetViewForNative(GtkWidget* widget, WidgetGtk* view);
@@ -115,6 +105,20 @@ class WidgetGtk : public Widget {
// The root of the View hierarchy attached to this window.
scoped_ptr<RootView> root_view_;
+
+ // If true, the mouse is currently down.
+ bool is_mouse_down_;
+
+ // The following are used to detect duplicate mouse move events and not
+ // deliver them. Displaying a window may result in the system generating
+ // duplicate move events even though the mouse hasn't moved.
+
+ // If true, the last event was a mouse move event.
+ bool last_mouse_event_was_move_;
+
+ // Coordinates of the last mouse move event, in screen coordinates.
+ int last_mouse_move_x_;
+ int last_mouse_move_y_;
};
} // namespace views