@@ -4794,70 +4794,36 @@ void nsWindow::UpdateWindowDraggingRegion(
47944794 }
47954795}
47964796
4797- // See subtract_corners_from_region() at gtk/gtkwindow.c
4798- // We need to subtract corners from toplevel window opaque region
4799- // to draw transparent corners of default Gtk titlebar.
4800- // Both implementations (cairo_region_t and wl_region) needs to be synced.
4801- static void SubtractTitlebarCorners (cairo_region_t * aRegion, int aX, int aY,
4802- int aWindowWidth) {
4803- cairo_rectangle_int_t rect = {aX, aY, TITLEBAR_SHAPE_MASK_HEIGHT ,
4804- TITLEBAR_SHAPE_MASK_HEIGHT };
4805- cairo_region_subtract_rectangle (aRegion, &rect);
4806- rect = {
4807- aX + aWindowWidth - TITLEBAR_SHAPE_MASK_HEIGHT ,
4808- aY,
4809- TITLEBAR_SHAPE_MASK_HEIGHT ,
4810- TITLEBAR_SHAPE_MASK_HEIGHT ,
4811- };
4812- cairo_region_subtract_rectangle (aRegion, &rect);
4813- }
4814-
48154797#ifdef MOZ_WAYLAND
4816- static void SubtractTitlebarCorners (wl_region* aRegion, int aX, int aY,
4817- int aWindowWidth) {
4818- wl_region_subtract (aRegion, aX, aY, TITLEBAR_SHAPE_MASK_HEIGHT ,
4819- TITLEBAR_SHAPE_MASK_HEIGHT );
4820- wl_region_subtract (aRegion, aX + aWindowWidth - TITLEBAR_SHAPE_MASK_HEIGHT ,
4821- aY, TITLEBAR_SHAPE_MASK_HEIGHT ,
4822- TITLEBAR_SHAPE_MASK_HEIGHT );
4823- }
4824-
4825- void nsWindow::UpdateTopLevelOpaqueRegionWayland (bool aSubtractCorners) {
4798+ void nsWindow::UpdateOpaqueRegionWayland (cairo_region_t * aRegion) {
48264799 wl_surface* surface = moz_gtk_widget_get_wl_surface (GTK_WIDGET (mShell ));
48274800 if (!surface) {
48284801 return ;
48294802 }
48304803
48314804 GdkDisplay* display = gtk_widget_get_display (GTK_WIDGET (mShell ));
48324805 nsWaylandDisplay* waylandDisplay = WaylandDisplayGet (display);
4833- struct wl_compositor * compositor = waylandDisplay->GetCompositor ();
4834-
4835- // Set opaque region to mShell. It's moved to mClientOffset.x/mClientOffset.y
4836- // from origin as we need transparent shadows around a window.
4837- wl_region* region = wl_compositor_create_region (compositor);
4838- int x = DevicePixelsToGdkCoordRoundDown (mClientOffset .x );
4839- int y = DevicePixelsToGdkCoordRoundDown (mClientOffset .y );
4840- int width = DevicePixelsToGdkCoordRoundDown (mBounds .width );
4841- int height = DevicePixelsToGdkCoordRoundDown (mBounds .height );
4842- wl_region_add (region, x, y, width, height);
4843- if (aSubtractCorners) {
4844- SubtractTitlebarCorners (region, x, y, width);
4845- }
4846- wl_surface_set_opaque_region (surface, region);
4847- wl_region_destroy (region);
4848-
4849- // Set region to mozcontainer which does not have any offset
4850- region = wl_compositor_create_region (compositor);
4851- wl_region_add (region, 0 , 0 , width, height);
4852- if (aSubtractCorners) {
4853- SubtractTitlebarCorners (region, 0 , 0 , width);
4854- }
4855- moz_container_set_opaque_region (mContainer , region);
4806+
4807+ wl_region* wl_region = nullptr ;
4808+ if (aRegion) {
4809+ struct wl_compositor * compositor = waylandDisplay->GetCompositor ();
4810+ wl_region = wl_compositor_create_region (compositor);
4811+ int n_rects = cairo_region_num_rectangles (aRegion);
4812+ for (int i = 0 ; i < n_rects; i++) {
4813+ cairo_rectangle_int_t rect;
4814+ cairo_region_get_rectangle (aRegion, i, &rect);
4815+ wl_region_add (wl_region, rect.x , rect.y , rect.width , rect.height );
4816+ }
4817+ }
4818+
4819+ wl_surface_set_opaque_region (surface, wl_region);
4820+ if (wl_region) {
4821+ wl_region_destroy (wl_region);
4822+ }
48564823}
48574824#endif
48584825
4859- static void GdkWindowSetOpaqueRegion (GdkWindow* aGdkWindow,
4860- cairo_region_t * aRegion) {
4826+ void nsWindow::UpdateOpaqueRegionGtk (cairo_region_t * aRegion) {
48614827 // Available as of GTK 3.10+
48624828 static auto sGdkWindowSetOpaqueRegion =
48634829 (void (*)(GdkWindow*, cairo_region_t *))dlsym (
@@ -4868,82 +4834,82 @@ static void GdkWindowSetOpaqueRegion(GdkWindow* aGdkWindow,
48684834 return ;
48694835 }
48704836
4871- (*sGdkWindowSetOpaqueRegion )(aGdkWindow, aRegion);
4872- }
4873-
4874- void nsWindow::UpdateTopLevelOpaqueRegionGtk (bool aSubtractCorners) {
4875- cairo_region_t * region = cairo_region_create ();
4876- int x = DevicePixelsToGdkCoordRoundDown (mClientOffset .x );
4877- int y = DevicePixelsToGdkCoordRoundDown (mClientOffset .y );
4878- int width = DevicePixelsToGdkCoordRoundDown (mBounds .width );
4879- int height = DevicePixelsToGdkCoordRoundDown (mBounds .height );
4880-
4881- cairo_rectangle_int_t rect = {x, y, width, height};
4882- cairo_region_union_rectangle (region, &rect);
4883-
4884- if (aSubtractCorners) {
4885- SubtractTitlebarCorners (region, x, y, width);
4886- }
4887-
4888- GdkWindow* window =
4889- (mDrawToContainer ) ? gtk_widget_get_window (mShell ) : mGdkWindow ;
4890- MOZ_ASSERT (gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL );
4891- GdkWindowSetOpaqueRegion (window, region);
4892-
4893- cairo_region_destroy (region);
4894- }
4895-
4896- void nsWindow::UpdatePopupOpaqueRegion (
4897- const LayoutDeviceIntRegion& aOpaqueRegion) {
4898- cairo_region_t * region = nullptr ;
4899-
4900- if (!aOpaqueRegion.IsEmpty ()) {
4901- region = cairo_region_create ();
4902- for (auto iter = aOpaqueRegion.RectIter (); !iter.Done (); iter.Next ()) {
4903- const LayoutDeviceIntRect& r = iter.Get ();
4904- cairo_rectangle_int_t rect = {r.x , r.y , r.width , r.height };
4905- cairo_region_union_rectangle (region, &rect);
4906- }
4907- }
4908-
49094837 GdkWindow* window =
49104838 (mDrawToContainer ) ? gtk_widget_get_window (mShell ) : mGdkWindow ;
4911- MOZ_ASSERT (gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL );
4912- GdkWindowSetOpaqueRegion (window, region);
4913-
4914- if (region) {
4915- cairo_region_destroy (region);
4839+ if (gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL ) {
4840+ (*sGdkWindowSetOpaqueRegion )(window, aRegion);
49164841 }
49174842}
49184843
49194844void nsWindow::UpdateOpaqueRegion (const LayoutDeviceIntRegion& aOpaqueRegion) {
4920- // Don 't set shape mask if we use transparency bitmap.
4845+ // Also don 't set shape mask if we use transparency bitmap.
49214846 if (mTransparencyBitmapForTitlebar ) {
49224847 return ;
49234848 }
49244849
4850+ cairo_region_t * region = nullptr ;
4851+
4852+ // We don't tweak opaque regions for non-toplevel windows (popup, panels etc.)
4853+ // as they can be transparent by gecko.
49254854 if (mWindowType != eWindowType_toplevel) {
4926- // We don't tweak opaque regions for non-toplevel windows
4927- // (popup, panels etc.) as they can be transparent by gecko.
4928- UpdatePopupOpaqueRegion (aOpaqueRegion);
4855+ if (!aOpaqueRegion.IsEmpty ()) {
4856+ region = cairo_region_create ();
4857+ for (auto iter = aOpaqueRegion.RectIter (); !iter.Done (); iter.Next ()) {
4858+ const LayoutDeviceIntRect& r = iter.Get ();
4859+ cairo_rectangle_int_t rect = {r.x , r.y , r.width , r.height };
4860+ cairo_region_union_rectangle (region, &rect);
4861+ }
4862+ }
49294863 } else {
49304864 // Gecko does not use transparent toplevel windows (see Bug 1469716),
49314865 // however we need to make it transparent to draw round corners of
49324866 // Gtk titlebar.
4867+ region = cairo_region_create ();
4868+
4869+ GtkBorder decorationSize = {0 , 0 , 0 , 0 };
4870+ if (mCSDSupportLevel == CSD_SUPPORT_CLIENT &&
4871+ mSizeState == nsSizeMode_Normal) {
4872+ decorationSize = GetCSDDecorationSize (
4873+ gtk_window_get_window_type (GTK_WINDOW (mShell )) == GTK_WINDOW_POPUP );
4874+ }
4875+
4876+ int width = DevicePixelsToGdkCoordRoundDown (mBounds .width );
4877+ int height = DevicePixelsToGdkCoordRoundDown (mBounds .height );
4878+
4879+ cairo_rectangle_int_t rect = {decorationSize.left , decorationSize.top ,
4880+ width, height};
4881+ cairo_region_union_rectangle (region, &rect);
49334882
49344883 // Subtract transparent corners which are used by
49354884 // various Gtk themes for toplevel windows when titlebar
49364885 // is rendered by gecko.
4937- bool drawTilebarCorners = (mDrawInTitlebar && !mIsPIPWindow ) &&
4938- (mSizeState == nsSizeMode_Normal && !mIsTiled );
4939- if (mIsX11Display ) {
4940- UpdateTopLevelOpaqueRegionGtk (drawTilebarCorners);
4886+ if (mDrawInTitlebar && !mIsPIPWindow && mSizeState == nsSizeMode_Normal &&
4887+ !mIsTiled ) {
4888+ cairo_rectangle_int_t rect = {decorationSize.left , decorationSize.top ,
4889+ TITLEBAR_SHAPE_MASK_HEIGHT ,
4890+ TITLEBAR_SHAPE_MASK_HEIGHT };
4891+ cairo_region_subtract_rectangle (region, &rect);
4892+ rect = {
4893+ decorationSize.left + width - TITLEBAR_SHAPE_MASK_HEIGHT ,
4894+ decorationSize.top ,
4895+ TITLEBAR_SHAPE_MASK_HEIGHT ,
4896+ TITLEBAR_SHAPE_MASK_HEIGHT ,
4897+ };
4898+ cairo_region_subtract_rectangle (region, &rect);
49414899 }
4900+ }
4901+
4902+ if (mIsX11Display ) {
4903+ UpdateOpaqueRegionGtk (region);
4904+ }
49424905#ifdef MOZ_WAYLAND
4943- else {
4944- UpdateTopLevelOpaqueRegionWayland (drawTilebarCorners );
4945- }
4906+ else {
4907+ UpdateOpaqueRegionWayland (region );
4908+ }
49464909#endif
4910+
4911+ if (region) {
4912+ cairo_region_destroy (region);
49474913 }
49484914}
49494915
@@ -7717,8 +7683,6 @@ void nsWindow::LockAspectRatio(bool aShouldLock) {
77177683 float width = (float )DevicePixelsToGdkCoordRoundDown (mBounds .width );
77187684 float height = (float )DevicePixelsToGdkCoordRoundDown (mBounds .height );
77197685
7720- // TODO - compare mShell GdkWindow size and mContainer GdkWindow size
7721- // instead of GetCSDDecorationSize() call.
77227686 if (mCSDSupportLevel == CSD_SUPPORT_CLIENT ) {
77237687 GtkBorder decorationSize = GetCSDDecorationSize (
77247688 gtk_window_get_window_type (GTK_WINDOW (mShell )) == GTK_WINDOW_POPUP );
0 commit comments