Bug 1364355 - Implement UpdateOpaqueRegion() by gdk_window_set_opaque_region(), r=karlt
authorMartin Stransky <stransky@redhat.com>
Fri, 26 May 2017 21:27:32 +0200
changeset 361776 457e6aea4650b4cc8bbc6581342fdc44bc8dbec1
parent 361775 d04f932669e756a1c673a5f47e68f5596cf6b25f
child 361777 4db765715213ac3e0bf46fe492acb5b031b128e7
push id31942
push userryanvm@gmail.com
push dateThu, 01 Jun 2017 15:54:15 +0000
treeherdermozilla-central@cac2fd43de81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs1364355
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1364355 - Implement UpdateOpaqueRegion() by gdk_window_set_opaque_region(), r=karlt MozReview-Commit-ID: 50N99ZlvFUh
widget/gtk/mozgtk/mozgtk.c
widget/gtk/nsWindow.cpp
widget/gtk/nsWindow.h
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -512,16 +512,17 @@ STUB(gtk_window_unmaximize)
 STUB(gdk_device_get_source)
 STUB(gdk_device_manager_get_client_pointer)
 STUB(gdk_disable_multidevice)
 STUB(gdk_device_manager_list_devices)
 STUB(gdk_display_get_device_manager)
 STUB(gdk_error_trap_pop_ignored)
 STUB(gdk_event_get_source_device)
 STUB(gdk_window_get_type)
+STUB(gdk_window_get_window_type)
 STUB(gdk_x11_window_get_xid)
 STUB(gdk_x11_display_get_type)
 STUB(gtk_box_new)
 STUB(gtk_cairo_should_draw_window)
 STUB(gtk_cairo_transform_to_window)
 STUB(gtk_combo_box_text_append)
 STUB(gtk_drag_set_icon_surface)
 STUB(gtk_get_major_version)
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -4365,16 +4365,43 @@ nsWindow::GetTransparencyMode()
         }
 
         return topWindow->GetTransparencyMode();
     }
 
     return mIsTransparent ? eTransparencyTransparent : eTransparencyOpaque;
 }
 
+#if (MOZ_WIDGET_GTK >= 3)
+void nsWindow::UpdateOpaqueRegion(const LayoutDeviceIntRegion& aOpaqueRegion)
+{
+    // Available as of GTK 3.10+
+    static auto sGdkWindowSetOpaqueRegion =
+        (void (*)(GdkWindow*, cairo_region_t*))
+            dlsym(RTLD_DEFAULT, "gdk_window_set_opaque_region");
+
+    if (sGdkWindowSetOpaqueRegion && mGdkWindow &&
+        gdk_window_get_window_type(mGdkWindow) == GDK_WINDOW_TOPLEVEL) {
+        if (aOpaqueRegion.IsEmpty()) {
+            (*sGdkWindowSetOpaqueRegion)(mGdkWindow, nullptr);
+        } else {
+            cairo_region_t *region = cairo_region_create();
+            for (auto iter = aOpaqueRegion.RectIter(); !iter.Done();
+                 iter.Next()) {
+                const LayoutDeviceIntRect &r = iter.Get();
+                cairo_rectangle_int_t rect = { r.x, r.y, r.width, r.height };
+                cairo_region_union_rectangle(region, &rect);
+            }
+            (*sGdkWindowSetOpaqueRegion)(mGdkWindow, region);
+            cairo_region_destroy(region);
+        }
+    }
+}
+#endif
+
 nsresult
 nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
 {
     // If this is a remotely updated widget we receive clipping, position, and
     // size information from a source other than our owner. Don't let our parent
     // update this information.
     if (mWindowType == eWindowType_plugin_ipc_chrome) {
       return NS_OK;
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -303,16 +303,19 @@ public:
 
     // These methods are for toplevel windows only.
     void               ResizeTransparencyBitmap();
     void               ApplyTransparencyBitmap();
     void               ClearTransparencyBitmap();
 
    virtual void        SetTransparencyMode(nsTransparencyMode aMode) override;
    virtual nsTransparencyMode GetTransparencyMode() override;
+#if (MOZ_WIDGET_GTK >= 3)
+   virtual void        UpdateOpaqueRegion(const LayoutDeviceIntRegion& aOpaqueRegion) override;
+#endif
    virtual nsresult    ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
    nsresult            UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
                                                             uint8_t* aAlphas, int32_t aStride);
 
 #if (MOZ_WIDGET_GTK == 2)
     static already_AddRefed<DrawTarget> GetDrawTargetForGdkDrawable(GdkDrawable* aDrawable,
                                                                     const mozilla::gfx::IntSize& aSize);
 #endif