summaryrefslogtreecommitdiffstats
path: root/views/controls/native_control_gtk.cc
blob: 24410f4a70492102c88f1e9c089b9c3374460712 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) 2011 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 "views/controls/native_control_gtk.h"

#include <gtk/gtk.h>

#include "base/logging.h"
#include "ui/base/accessibility/accessibility_types.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/widget/widget.h"

namespace views {

NativeControlGtk::NativeControlGtk() {
}

NativeControlGtk::~NativeControlGtk() {
  if (native_view())
    gtk_widget_destroy(native_view());
}

////////////////////////////////////////////////////////////////////////////////
// NativeControlGtk, View overrides:

void NativeControlGtk::OnEnabledChanged() {
  View::OnEnabledChanged();
  if (native_view())
    gtk_widget_set_sensitive(native_view(), IsEnabled());
}

void NativeControlGtk::ViewHierarchyChanged(bool is_add, View* parent,
                                            View* child) {
  // Call the base class to hide the view if we're being removed.
  NativeViewHost::ViewHierarchyChanged(is_add, parent, child);

  if (!is_add && child == this && native_view()) {
    Detach();
  } else if (is_add && GetWidget() && !native_view()) {
    // Create the widget when we're added to a valid Widget. Many
    // controls need a parent widget to function properly.
    CreateNativeControl();
  }
}

void NativeControlGtk::VisibilityChanged(View* starting_from, bool is_visible) {
  if (!native_view()) {
    if (GetWidget())
      CreateNativeControl();
  } else {
    // The view becomes visible after native control is created.
    // Layout now.
    Layout();
  }
}

void NativeControlGtk::OnFocus() {
  DCHECK(native_view());
  gtk_widget_grab_focus(native_view());
  GetWidget()->NotifyAccessibilityEvent(
      parent(), ui::AccessibilityTypes::EVENT_FOCUS, true);
}

void NativeControlGtk::NativeControlCreated(GtkWidget* native_control) {
  Attach(native_control);

  // Update the newly created GtkWidget with any resident enabled state.
  gtk_widget_set_sensitive(native_view(), IsEnabled());

  // Listen for focus change event to update the FocusManager focused view.
  g_signal_connect(native_control, "focus-in-event",
                   G_CALLBACK(CallFocusIn), this);
}

// static
gboolean NativeControlGtk::CallFocusIn(GtkWidget* gtk_widget,
                                       GdkEventFocus* event,
                                       NativeControlGtk* control) {
  Widget* widget = Widget::GetTopLevelWidgetForNativeView(gtk_widget);
  FocusManager* focus_manager = widget ? widget->GetFocusManager() : NULL;
  if (!focus_manager) {
    // TODO(jcampan): http://crbug.com/21378 Reenable this NOTREACHED() when the
    // options page is only based on views.
    // NOTREACHED();
    NOTIMPLEMENTED();
    return false;
  }
  focus_manager->SetFocusedView(control->focus_view());
  return false;
}

}  // namespace views