Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/platform/linux/window_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ static const char* kMouseInputPolicyKey = "NativeAPIMouseInputPolicy";
struct MouseInputPolicy {
bool ignored = false;
bool forward = false;
bool shadow_rectangle = false;
guint source = 0;
GtkWidget* widget = nullptr; // The owner, or nullptr for a bare GdkWindow.
GdkWindow* surface = nullptr;
Expand Down Expand Up @@ -239,6 +240,17 @@ static void ApplyMouseInputPolicy(GtkWidget* widget, GdkWindow* surface,
else gdk_window_input_shape_combine_region(surface, region, 0, 0);
if (empty) cairo_region_destroy(empty);
}

static void ClearShadowInput(GtkWidget* widget) {
auto* surface = gtk_widget_get_window(widget);
auto* policy = GetMouseInputPolicy(widget, surface, false);
// Ownership survives surface recreation; explicit input/visual shapes stay intact.
if (!policy || !policy->shadow_rectangle) return;
cairo_region_destroy(policy->region);
policy->region = nullptr;
policy->shadow_rectangle = false;
ApplyMouseInputPolicy(widget, surface, *policy);
}
static const char* kTitleBarStyleKey = "NativeAPITitleBarStyle";
static const char* kFocusableKey = "NativeAPIFocusable";
static const char* kNonActivatingKey = "NativeAPINonActivating";
Expand Down Expand Up @@ -2678,12 +2690,14 @@ static cairo_region_t* RasterizeShape(GtkWidget* widget, GdkWindow* window,
return region;
}

static void ApplyInputRegion(GtkWidget* widget, GdkWindow* window, cairo_region_t* region) {
static void ApplyInputRegion(GtkWidget* widget, GdkWindow* window, cairo_region_t* region,
bool shadow_rectangle = false) {
// GTK intersects its CSD input region with the explicit widget region. Register
// ours with GTK as well as GDK so a later allocation cannot overwrite it.
auto* policy = GetMouseInputPolicy(widget, window, true);
if (policy->region) cairo_region_destroy(policy->region);
policy->region = region ? cairo_region_copy(region) : nullptr;
policy->shadow_rectangle = shadow_rectangle;
ApplyMouseInputPolicy(widget, window, *policy);
g_object_set_data(G_OBJECT(window), kInputShapeKey, region ? GINT_TO_POINTER(1) : nullptr);
gdk_window_invalidate_rect(window, nullptr, TRUE);
Expand All @@ -2703,7 +2717,7 @@ static void RefreshShadowInput(GtkWidget* widget) {
rectangle.AddPoint({double(width), double(height)}); rectangle.AddPoint({0, double(height)});
}
auto* region = RasterizeShape(widget, window, explicit_polygon ? shadow->polygon : rectangle);
ApplyInputRegion(widget, window, region);
ApplyInputRegion(widget, window, region, !explicit_polygon);
cairo_region_destroy(region);
g_object_set_data(G_OBJECT(window), kInputShapeKey, explicit_polygon ? GINT_TO_POINTER(1) : nullptr);
}
Expand Down
2 changes: 2 additions & 0 deletions src/platform/linux/window_shadow_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace nativeapi {
static void RefreshShadowInput(GtkWidget* widget);
static void ClearShadowInput(GtkWidget* widget);
}

namespace nativeapi::linux_shadow {
Expand Down Expand Up @@ -271,6 +272,7 @@ inline void Remove(GtkWidget* widget) {
const int width = child ? gtk_widget_get_allocated_width(child) : 0;
const int height = child ? gtk_widget_get_allocated_height(child) : 0;
g_signal_handlers_disconnect_by_data(widget, state);
ClearShadowInput(widget);
gtk_style_context_remove_class(gtk_widget_get_style_context(widget), kGutterStyleClass);
if (state->overlay && child == state->overlay) {
auto* content = gtk_bin_get_child(GTK_BIN(state->overlay));
Expand Down
Loading