summaryrefslogtreecommitdiffstats
path: root/views/widget/widget_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'views/widget/widget_gtk.cc')
-rw-r--r--views/widget/widget_gtk.cc41
1 files changed, 40 insertions, 1 deletions
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index daa43d1..78f301a 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -4,6 +4,10 @@
#include "views/widget/widget_gtk.h"
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/shape.h>
+
#include "app/drag_drop_types.h"
#include "app/gfx/path.h"
#include "app/os_exchange_data.h"
@@ -98,6 +102,7 @@ WidgetGtk::WidgetGtk(Type type)
ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)),
delete_on_destroy_(true),
transparent_(false),
+ ignore_events_(false),
ignore_drag_leave_(false),
opacity_(255),
drag_data_(NULL),
@@ -151,6 +156,15 @@ bool WidgetGtk::MakeTransparent() {
return true;
}
+bool WidgetGtk::MakeIgnoreEvents() {
+ // Transparency can only be enabled for windows/popups and only if we haven't
+ // realized the widget.
+ DCHECK(!widget_ && type_ != TYPE_CHILD);
+
+ ignore_events_ = true;
+ return true;
+}
+
void WidgetGtk::AddChild(GtkWidget* child) {
gtk_container_add(GTK_CONTAINER(window_contents_), child);
}
@@ -1311,6 +1325,9 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
if (transparent_)
ConfigureWidgetForTransparentBackground();
+
+ if (ignore_events_)
+ ConfigureWidgetForIgnoreEvents();
}
// The widget needs to be realized before handlers like size-allocate can
@@ -1349,6 +1366,26 @@ void WidgetGtk::ConfigureWidgetForTransparentBackground() {
gdk_window_set_back_pixmap(window_contents_->window, NULL, FALSE);
}
+void WidgetGtk::ConfigureWidgetForIgnoreEvents() {
+ gtk_widget_realize(widget_);
+ GdkWindow* gdk_window = widget_->window;
+ Display* display = GDK_WINDOW_XDISPLAY(gdk_window);
+ XID win = GDK_WINDOW_XID(gdk_window);
+
+ // This sets the clickable area to be empty, allowing all events to be
+ // passed to any windows behind this one.
+ XShapeCombineRectangles(
+ display,
+ win,
+ ShapeInput,
+ 0, // x offset
+ 0, // y offset
+ NULL, // rectangles
+ 0, // num rectangles
+ ShapeSet,
+ 0);
+}
+
void WidgetGtk::HandleGrabBroke() {
if (has_capture_) {
if (is_mouse_down_)
@@ -1364,12 +1401,14 @@ void WidgetGtk::HandleGrabBroke() {
// static
Widget* Widget::CreatePopupWidget(TransparencyParam transparent,
- EventsParam /*accept_events*/,
+ EventsParam accept_events,
DeleteParam delete_on_destroy) {
WidgetGtk* popup = new WidgetGtk(WidgetGtk::TYPE_POPUP);
popup->set_delete_on_destroy(delete_on_destroy == DeleteOnDestroy);
if (transparent == Transparent)
popup->MakeTransparent();
+ if (accept_events == NotAcceptEvents)
+ popup->MakeIgnoreEvents();
return popup;
}