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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
// 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 "views/controls/native_view_host_gtk.h"
#include <gtk/gtk.h>
#include "base/logging.h"
#include "views/widget/widget_gtk.h"
namespace views {
NativeViewHostGtk::NativeViewHostGtk() {
}
NativeViewHostGtk::~NativeViewHostGtk() {
}
void NativeViewHostGtk::Attach(GtkWidget* widget) {
DCHECK(native_view() == NULL);
DCHECK(widget);
set_native_view(widget);
// First hide the new window. We don't want anything to draw (like sub-hwnd
// borders), when we change the parent below.
gtk_widget_hide(widget);
// Set the parent.
static_cast<WidgetGtk*>(GetWidget())->AddChild(widget);
Layout();
// TODO: figure out focus.
// FocusManager::InstallFocusSubclass(
// hwnd, associated_focus_view()_ ? associated_focus_view() : this);
}
void NativeViewHostGtk::Detach() {
DCHECK(native_view());
// TODO: focus.
// FocusManager::UninstallFocusSubclass(native_view());
set_native_view(NULL);
set_installed_clip(false);
}
void NativeViewHostGtk::ViewHierarchyChanged(bool is_add, View* parent,
View* child) {
if (!native_view())
return;
WidgetGtk* parent_widget = static_cast<WidgetGtk*>(GetWidget());
if (is_add && parent_widget) {
GtkWidget* widget_parent = gtk_widget_get_parent(native_view());
GtkWidget* parent_widget_widget = parent_widget->child_widget_parent();
if (widget_parent != parent_widget_widget) {
g_object_ref(native_view());
if (widget_parent)
gtk_container_remove(GTK_CONTAINER(widget_parent), native_view());
gtk_container_add(GTK_CONTAINER(parent_widget_widget), native_view());
g_object_unref(native_view());
}
if (IsVisibleInRootView())
gtk_widget_show(native_view());
else
gtk_widget_hide(native_view());
Layout();
} else if (!is_add) {
gtk_widget_hide(native_view());
if (parent_widget) {
gtk_container_remove(GTK_CONTAINER(parent_widget->child_widget_parent()),
native_view());
}
}
}
void NativeViewHostGtk::Focus() {
NOTIMPLEMENTED();
}
void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) {
DCHECK(w > 0 && h > 0);
bool has_window = (GTK_WIDGET_FLAGS(native_view()) & GTK_NO_WINDOW) == 0;
if (!has_window) {
// Clip is only supported on GtkWidgets that have windows. If this becomes
// an issue (as it may be in the options dialog) we'll need to wrap the
// widget in a GtkFixed with a window. We have to do this as not all widgets
// support turning on GTK_NO_WINDOW (for example, buttons don't appear to
// draw anything when they have a window).
NOTREACHED();
return;
}
DCHECK(has_window);
// Unset the current region.
gdk_window_shape_combine_region(native_view()->window, NULL, 0, 0);
// Set a new region.
// TODO: using shapes is a bit expensive. Should investigated if there is
// another more efficient way to accomplish this.
GdkRectangle clip_rect = { x, y, w, h };
GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
gdk_window_shape_combine_region(native_view()->window, clip_region, x, y);
gdk_region_destroy(clip_region);
}
void NativeViewHostGtk::UninstallClip() {
gtk_widget_shape_combine_mask(native_view(), NULL, 0, 0);
}
void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
WidgetGtk* parent = static_cast<WidgetGtk*>(GetWidget());
parent->PositionChild(native_view(), x, y, w, h);
gtk_widget_show(native_view());
}
void NativeViewHostGtk::HideWidget() {
gtk_widget_hide(native_view());
}
} // namespace views
|