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

Side by Side Diff: views/widget/widget_gtk.cc

Issue 6675005: Integrate the new input method API for Views into Chromium. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 9 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) 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 "views/widget/widget_gtk.h" 5 #include "views/widget/widget_gtk.h"
6 6
7 #include <gdk/gdk.h> 7 #include <gdk/gdk.h>
8 #include <gdk/gdkx.h> 8 #include <gdk/gdkx.h>
9 #include <X11/extensions/shape.h> 9 #include <X11/extensions/shape.h>
10 10
11 #include <set> 11 #include <set>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/auto_reset.h" 14 #include "base/auto_reset.h"
15 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
16 #include "base/message_loop.h" 16 #include "base/message_loop.h"
17 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
18 #include "ui/base/dragdrop/drag_drop_types.h" 18 #include "ui/base/dragdrop/drag_drop_types.h"
19 #include "ui/base/dragdrop/os_exchange_data.h" 19 #include "ui/base/dragdrop/os_exchange_data.h"
20 #include "ui/base/dragdrop/os_exchange_data_provider_gtk.h" 20 #include "ui/base/dragdrop/os_exchange_data_provider_gtk.h"
21 #include "ui/base/gtk/gtk_windowing.h" 21 #include "ui/base/gtk/gtk_windowing.h"
22 #include "ui/base/x/x11_util.h" 22 #include "ui/base/x/x11_util.h"
23 #include "ui/gfx/canvas_skia_paint.h" 23 #include "ui/gfx/canvas_skia_paint.h"
24 #include "ui/gfx/path.h" 24 #include "ui/gfx/path.h"
25 #include "views/views_delegate.h" 25 #include "views/views_delegate.h"
26 #include "views/controls/textfield/native_textfield_views.h"
26 #include "views/focus/view_storage.h" 27 #include "views/focus/view_storage.h"
27 #include "views/widget/drop_target_gtk.h" 28 #include "views/widget/drop_target_gtk.h"
28 #include "views/widget/gtk_views_fixed.h" 29 #include "views/widget/gtk_views_fixed.h"
29 #include "views/widget/gtk_views_window.h" 30 #include "views/widget/gtk_views_window.h"
30 #include "views/widget/root_view.h" 31 #include "views/widget/root_view.h"
31 #include "views/widget/tooltip_manager_gtk.h" 32 #include "views/widget/tooltip_manager_gtk.h"
32 #include "views/widget/widget_delegate.h" 33 #include "views/widget/widget_delegate.h"
33 #include "views/window/window_gtk.h" 34 #include "views/window/window_gtk.h"
34 35
35 #if defined(TOUCH_UI) 36 #if defined(TOUCH_UI)
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 static bool installed_message_loop_observer = false; 287 static bool installed_message_loop_observer = false;
287 if (!installed_message_loop_observer) { 288 if (!installed_message_loop_observer) {
288 installed_message_loop_observer = true; 289 installed_message_loop_observer = true;
289 MessageLoopForUI* loop = MessageLoopForUI::current(); 290 MessageLoopForUI* loop = MessageLoopForUI::current();
290 if (loop) 291 if (loop)
291 loop->AddObserver(DropObserver::GetInstance()); 292 loop->AddObserver(DropObserver::GetInstance());
292 } 293 }
293 } 294 }
294 295
295 WidgetGtk::~WidgetGtk() { 296 WidgetGtk::~WidgetGtk() {
297 // We need to delete the input method before calling DestroyRootView(),
298 // because it'll set focus_manager_ to NULL.
299 input_method_.reset();
296 DestroyRootView(); 300 DestroyRootView();
297 DCHECK(delete_on_destroy_ || widget_ == NULL); 301 DCHECK(delete_on_destroy_ || widget_ == NULL);
298 if (type_ != TYPE_CHILD) 302 if (type_ != TYPE_CHILD)
299 ActiveWindowWatcherX::RemoveObserver(this); 303 ActiveWindowWatcherX::RemoveObserver(this);
300 } 304 }
301 305
302 void WidgetGtk::SetCreateParams(const CreateParams& params) { 306 void WidgetGtk::SetCreateParams(const CreateParams& params) {
303 // Set non-style attributes. 307 // Set non-style attributes.
304 set_delete_on_destroy(params.delete_on_destroy); 308 set_delete_on_destroy(params.delete_on_destroy);
305 309
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 void WidgetGtk::Init(GtkWidget* parent, 502 void WidgetGtk::Init(GtkWidget* parent,
499 const gfx::Rect& bounds) { 503 const gfx::Rect& bounds) {
500 Widget::Init(parent, bounds); 504 Widget::Init(parent, bounds);
501 if (type_ != TYPE_CHILD) 505 if (type_ != TYPE_CHILD)
502 ActiveWindowWatcherX::AddObserver(this); 506 ActiveWindowWatcherX::AddObserver(this);
503 507
504 // Make container here. 508 // Make container here.
505 CreateGtkWidget(parent, bounds); 509 CreateGtkWidget(parent, bounds);
506 delegate_->OnNativeWidgetCreated(); 510 delegate_->OnNativeWidgetCreated();
507 511
512 // Creates input method for toplevel widget after calling
513 // delegate_->OnNativeWidgetCreated(), to make sure that focus manager is
514 // already created at this point.
515 // TODO(suzhe): Always enable input method when we start to use
516 // RenderWidgetHostViewViews in normal ChromeOS.
517 #if !defined(TOUCH_UI)
518 if (type_ != TYPE_CHILD && NativeTextfieldViews::IsTextfieldViewsEnabled()) {
519 #else
520 if (type_ != TYPE_CHILD) {
521 #endif
522 input_method_.reset(new InputMethodGtk(this));
523 input_method_->Init(GetWidget());
524 }
525
508 if (opacity_ != 255) 526 if (opacity_ != 255)
509 SetOpacity(opacity_); 527 SetOpacity(opacity_);
510 528
511 // Make sure we receive our motion events. 529 // Make sure we receive our motion events.
512 530
513 // In general we register most events on the parent of all widgets. At a 531 // In general we register most events on the parent of all widgets. At a
514 // minimum we need painting to happen on the parent (otherwise painting 532 // minimum we need painting to happen on the parent (otherwise painting
515 // doesn't work at all), and similarly we need mouse release events on the 533 // doesn't work at all), and similarly we need mouse release events on the
516 // parent as windows don't get mouse releases. 534 // parent as windows don't get mouse releases.
517 gtk_widget_add_events(window_contents_, 535 gtk_widget_add_events(window_contents_,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 665
648 void WidgetGtk::ClearNativeFocus() { 666 void WidgetGtk::ClearNativeFocus() {
649 DCHECK(type_ != TYPE_CHILD); 667 DCHECK(type_ != TYPE_CHILD);
650 if (!GetNativeView()) { 668 if (!GetNativeView()) {
651 NOTREACHED(); 669 NOTREACHED();
652 return; 670 return;
653 } 671 }
654 gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL); 672 gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL);
655 } 673 }
656 674
657 bool WidgetGtk::HandleKeyboardEvent(GdkEventKey* event) { 675 bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) {
658 if (!GetFocusManager()) 676 if (!GetFocusManager())
659 return false; 677 return false;
660 678
661 KeyEvent key(reinterpret_cast<NativeEvent>(event)); 679 const int key_code = key.key_code();
662 int key_code = key.key_code();
663 bool handled = false; 680 bool handled = false;
664 681
665 // Always reset |should_handle_menu_key_release_| unless we are handling a 682 // Always reset |should_handle_menu_key_release_| unless we are handling a
666 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only 683 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
667 // be activated when handling a VKEY_MENU key release event which is preceded 684 // be activated when handling a VKEY_MENU key release event which is preceded
668 // by an un-handled VKEY_MENU key press event. 685 // by an un-handled VKEY_MENU key press event.
669 if (key_code != ui::VKEY_MENU || event->type != GDK_KEY_RELEASE) 686 if (key_code != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED)
670 should_handle_menu_key_release_ = false; 687 should_handle_menu_key_release_ = false;
671 688
672 if (event->type == GDK_KEY_PRESS) { 689 if (key.type() == ui::ET_KEY_PRESSED) {
673 // VKEY_MENU is triggered by key release event. 690 // VKEY_MENU is triggered by key release event.
674 // FocusManager::OnKeyEvent() returns false when the key has been consumed. 691 // FocusManager::OnKeyEvent() returns false when the key has been consumed.
675 if (key_code != ui::VKEY_MENU) 692 if (key_code != ui::VKEY_MENU)
676 handled = !GetFocusManager()->OnKeyEvent(key); 693 handled = !GetFocusManager()->OnKeyEvent(key);
677 else 694 else
678 should_handle_menu_key_release_ = true; 695 should_handle_menu_key_release_ = true;
679 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && 696 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ &&
680 (key.flags() & ~ui::EF_ALT_DOWN) == 0) { 697 (key.flags() & ~ui::EF_ALT_DOWN) == 0) {
681 // Trigger VKEY_MENU when only this key is pressed and released, and both 698 // Trigger VKEY_MENU when only this key is pressed and released, and both
682 // press and release events are not handled by others. 699 // press and release events are not handled by others.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 if (HasNativeCapture()) 763 if (HasNativeCapture())
747 gtk_grab_remove(window_contents_); 764 gtk_grab_remove(window_contents_);
748 } 765 }
749 766
750 bool WidgetGtk::HasNativeCapture() const { 767 bool WidgetGtk::HasNativeCapture() const {
751 // TODO(beng): Should be able to use gtk_widget_has_grab() here but the 768 // TODO(beng): Should be able to use gtk_widget_has_grab() here but the
752 // trybots don't have Gtk 2.18. 769 // trybots don't have Gtk 2.18.
753 return GTK_WIDGET_HAS_GRAB(window_contents_); 770 return GTK_WIDGET_HAS_GRAB(window_contents_);
754 } 771 }
755 772
773 InputMethod* WidgetGtk::GetInputMethodNative() {
774 return input_method_.get();
775 }
776
777 void WidgetGtk::ReplaceInputMethod(InputMethod* input_method) {
778 input_method_.reset(input_method);
779 if (input_method) {
780 input_method->set_delegate(this);
781 input_method->Init(GetWidget());
782 }
783 }
784
756 gfx::Rect WidgetGtk::GetWindowScreenBounds() const { 785 gfx::Rect WidgetGtk::GetWindowScreenBounds() const {
757 // Client == Window bounds on Gtk. 786 // Client == Window bounds on Gtk.
758 return GetClientAreaScreenBounds(); 787 return GetClientAreaScreenBounds();
759 } 788 }
760 789
761 gfx::Rect WidgetGtk::GetClientAreaScreenBounds() const { 790 gfx::Rect WidgetGtk::GetClientAreaScreenBounds() const {
762 // Due to timing we can get a request for bounds after Close(). 791 // Due to timing we can get a request for bounds after Close().
763 // TODO(beng): Figure out if this is bogus. 792 // TODO(beng): Figure out if this is bogus.
764 if (!widget_) 793 if (!widget_)
765 return gfx::Rect(size_); 794 return gfx::Rect(size_);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 if (close_widget_factory_.empty()) { 865 if (close_widget_factory_.empty()) {
837 // And we delay the close just in case we're on the stack. 866 // And we delay the close just in case we're on the stack.
838 MessageLoop::current()->PostTask(FROM_HERE, 867 MessageLoop::current()->PostTask(FROM_HERE,
839 close_widget_factory_.NewRunnableMethod( 868 close_widget_factory_.NewRunnableMethod(
840 &WidgetGtk::CloseNow)); 869 &WidgetGtk::CloseNow));
841 } 870 }
842 } 871 }
843 872
844 void WidgetGtk::CloseNow() { 873 void WidgetGtk::CloseNow() {
845 if (widget_) { 874 if (widget_) {
875 input_method_.reset();
846 gtk_widget_destroy(widget_); // Triggers OnDestroy(). 876 gtk_widget_destroy(widget_); // Triggers OnDestroy().
847 } 877 }
848 } 878 }
849 879
850 void WidgetGtk::Show() { 880 void WidgetGtk::Show() {
851 if (widget_) { 881 if (widget_) {
852 gtk_widget_show(widget_); 882 gtk_widget_show(widget_);
853 if (widget_->window) 883 if (widget_->window)
854 gdk_window_raise(widget_->window); 884 gdk_window_raise(widget_->window);
855 } 885 }
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { 1177 gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
1148 if (has_focus_) 1178 if (has_focus_)
1149 return false; // This is the second focus-in event in a row, ignore it. 1179 return false; // This is the second focus-in event in a row, ignore it.
1150 has_focus_ = true; 1180 has_focus_ = true;
1151 1181
1152 should_handle_menu_key_release_ = false; 1182 should_handle_menu_key_release_ = false;
1153 1183
1154 if (type_ == TYPE_CHILD) 1184 if (type_ == TYPE_CHILD)
1155 return false; 1185 return false;
1156 1186
1187 // Only top-level Widget should have an InputMethod instance.
1188 if (input_method_.get())
1189 input_method_->OnFocusIn();
1190
1157 // See description of got_initial_focus_in_ for details on this. 1191 // See description of got_initial_focus_in_ for details on this.
1158 if (!got_initial_focus_in_) { 1192 if (!got_initial_focus_in_) {
1159 got_initial_focus_in_ = true; 1193 got_initial_focus_in_ = true;
1160 SetInitialFocus(); 1194 SetInitialFocus();
1161 } else { 1195 } else {
1162 GetFocusManager()->RestoreFocusedView(); 1196 GetFocusManager()->RestoreFocusedView();
1163 } 1197 }
1164 return false; 1198 return false;
1165 } 1199 }
1166 1200
1167 gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) { 1201 gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
1168 if (!has_focus_) 1202 if (!has_focus_)
1169 return false; // This is the second focus-out event in a row, ignore it. 1203 return false; // This is the second focus-out event in a row, ignore it.
1170 has_focus_ = false; 1204 has_focus_ = false;
1171 1205
1172 if (type_ == TYPE_CHILD) 1206 if (type_ == TYPE_CHILD)
1173 return false; 1207 return false;
1174 1208
1209 // Only top-level Widget should have an InputMethod instance.
1210 if (input_method_.get())
1211 input_method_->OnFocusOut();
1212
1175 // The top-level window lost focus, store the focused view. 1213 // The top-level window lost focus, store the focused view.
1176 GetFocusManager()->StoreFocusedView(); 1214 GetFocusManager()->StoreFocusedView();
1177 return false; 1215 return false;
1178 } 1216 }
1179 1217
1180 gboolean WidgetGtk::OnKeyEvent(GtkWidget* widget, GdkEventKey* event) { 1218 gboolean WidgetGtk::OnKeyEvent(GtkWidget* widget, GdkEventKey* event) {
1181 KeyEvent key(reinterpret_cast<NativeEvent>(event)); 1219 KeyEvent key(reinterpret_cast<NativeEvent>(event));
1220 if (input_method_.get())
1221 input_method_->DispatchKeyEvent(key);
1222 else
1223 DispatchKeyEventPostIME(key);
1182 1224
1183 // Always reset |should_handle_menu_key_release_| unless we are handling a 1225 // Returns true to prevent GtkWindow's default key event handler.
1184 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only 1226 return true;
1185 // be activated when handling a VKEY_MENU key release event which is preceded
1186 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent().
1187 if (key.key_code() != ui::VKEY_MENU || event->type != GDK_KEY_RELEASE)
1188 should_handle_menu_key_release_ = false;
1189
1190 bool handled = false;
1191
1192 // Dispatch the key event to View hierarchy first.
1193 handled = GetRootView()->ProcessKeyEvent(key);
1194
1195 // Dispatch the key event to native GtkWidget hierarchy.
1196 // To prevent GtkWindow from handling the key event as a keybinding, we need
1197 // to bypass GtkWindow's default key event handler and dispatch the event
1198 // here.
1199 if (!handled && GTK_IS_WINDOW(widget))
1200 handled = gtk_window_propagate_key_event(GTK_WINDOW(widget), event);
1201
1202 // On Linux, in order to handle VKEY_MENU (Alt) accelerator key correctly and
1203 // avoid issues like: http://crbug.com/40966 and http://crbug.com/49701, we
1204 // should only send the key event to the focus manager if it's not handled by
1205 // any View or native GtkWidget.
1206 // The flow is different when the focus is in a RenderWidgetHostViewGtk, which
1207 // always consumes the key event and send it back to us later by calling
1208 // HandleKeyboardEvent() directly, if it's not handled by webkit.
1209 if (!handled)
1210 handled = HandleKeyboardEvent(event);
1211
1212 // Dispatch the key event for bindings processing.
1213 if (!handled && GTK_IS_WINDOW(widget))
1214 handled = gtk_bindings_activate_event(GTK_OBJECT(widget), event);
1215
1216 // Always return true for toplevel window to prevents GtkWindow's default key
1217 // event handler.
1218 return GTK_IS_WINDOW(widget) ? true : handled;
1219 } 1227 }
1220 1228
1221 gboolean WidgetGtk::OnQueryTooltip(GtkWidget* widget, 1229 gboolean WidgetGtk::OnQueryTooltip(GtkWidget* widget,
1222 gint x, 1230 gint x,
1223 gint y, 1231 gint y,
1224 gboolean keyboard_mode, 1232 gboolean keyboard_mode,
1225 GtkTooltip* tooltip) { 1233 GtkTooltip* tooltip) {
1226 return tooltip_manager_->ShowTooltip(x, y, keyboard_mode, tooltip); 1234 return tooltip_manager_->ShowTooltip(x, y, keyboard_mode, tooltip);
1227 } 1235 }
1228 1236
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 1296
1289 RootView* WidgetGtk::CreateRootView() { 1297 RootView* WidgetGtk::CreateRootView() {
1290 return new RootView(this); 1298 return new RootView(this);
1291 } 1299 }
1292 1300
1293 gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { 1301 gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() {
1294 DCHECK(window_contents_ && window_contents_->window); 1302 DCHECK(window_contents_ && window_contents_->window);
1295 return GDK_WINDOW_XID(window_contents_->window); 1303 return GDK_WINDOW_XID(window_contents_->window);
1296 } 1304 }
1297 1305
1306 void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) {
1307 // Always reset |should_handle_menu_key_release_| unless we are handling a
1308 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
1309 // be activated when handling a VKEY_MENU key release event which is preceded
1310 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent().
1311 if (key.key_code() != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED)
1312 should_handle_menu_key_release_ = false;
1313
1314 bool handled = false;
1315
1316 // Dispatch the key event to View hierarchy first.
1317 handled = GetRootView()->ProcessKeyEvent(key);
1318
1319 if (key.key_code() == ui::VKEY_PROCESSKEY || handled)
1320 return;
1321
1322 // Dispatch the key event to native GtkWidget hierarchy.
1323 // To prevent GtkWindow from handling the key event as a keybinding, we need
1324 // to bypass GtkWindow's default key event handler and dispatch the event
1325 // here.
1326 GdkEventKey* event = reinterpret_cast<GdkEventKey*>(key.native_event());
1327 if (!handled && event && GTK_IS_WINDOW(widget_))
1328 handled = gtk_window_propagate_key_event(GTK_WINDOW(widget_), event);
1329
1330 // On Linux, in order to handle VKEY_MENU (Alt) accelerator key correctly and
1331 // avoid issues like: http://crbug.com/40966 and http://crbug.com/49701, we
1332 // should only send the key event to the focus manager if it's not handled by
1333 // any View or native GtkWidget.
1334 // The flow is different when the focus is in a RenderWidgetHostViewGtk, which
1335 // always consumes the key event and send it back to us later by calling
1336 // HandleKeyboardEvent() directly, if it's not handled by webkit.
1337 if (!handled)
1338 handled = HandleKeyboardEvent(key);
1339
1340 // Dispatch the key event for bindings processing.
1341 if (!handled && event && GTK_IS_WINDOW(widget_))
1342 gtk_bindings_activate_event(GTK_OBJECT(widget_), event);
1343 }
1344
1298 gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { 1345 gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) {
1299 // Clear the background to be totally transparent. We don't need to 1346 // Clear the background to be totally transparent. We don't need to
1300 // paint the root view here as that is done by OnPaint. 1347 // paint the root view here as that is done by OnPaint.
1301 DCHECK(transparent_); 1348 DCHECK(transparent_);
1302 DrawTransparentBackground(widget, event); 1349 DrawTransparentBackground(widget, event);
1303 return false; 1350 return false;
1304 } 1351 }
1305 1352
1306 bool WidgetGtk::ProcessMousePressed(GdkEventButton* event) { 1353 bool WidgetGtk::ProcessMousePressed(GdkEventButton* event) {
1307 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { 1354 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) {
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 1687
1641 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); 1688 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view);
1642 if (native_widget) 1689 if (native_widget)
1643 children->insert(native_widget); 1690 children->insert(native_widget);
1644 gtk_container_foreach(GTK_CONTAINER(native_view), 1691 gtk_container_foreach(GTK_CONTAINER(native_view),
1645 EnumerateChildWidgetsForNativeWidgets, 1692 EnumerateChildWidgetsForNativeWidgets,
1646 reinterpret_cast<gpointer>(children)); 1693 reinterpret_cast<gpointer>(children));
1647 } 1694 }
1648 1695
1649 } // namespace views 1696 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698