<commit_before>/*
 * gtkoverlay.c
 * This file is part of gtk
 *
 * Copyright (C) 2011 - <NAME>, <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include "gtkoverlay.h"
#include "gtkbuildable.h"
#include "gtkscrolledwindow.h"
#include "gtkmarshalers.h"

#include "gtkprivate.h"
#include "gtkintl.h"

/**
 * SECTION:gtkoverlay
 * @short_description: A container which overlays widgets on top of each other
 * @title: GtkOverlay
 *
 * GtkOverlay is a container which contains a single main child, on top
 * of which it can place <firstterm>overlay</firstterm> widgets. The
 * position of each overlay widget is determined by its #GtkWidget:halign
 * and #GtkWidget:valign properties. E.g. a widget with both alignments
 * set to %GTK_ALIGN_START will be placed at the top left corner of the
 * main widget, whereas an overlay with halign set to %GTK_ALIGN_CENTER
 * and valign set to %GTK_ALIGN_END will be placed a the bottom edge of
 * the main widget, horizontally centered. The position can be adjusted
 * by setting the margin properties of the child to non-zero values.
 *
 * More complicated placement of overlays is possible by connecting
 * to the #GtkOverlay::get-child-position signal.
 *
 * <refsect2 id="GtkOverlay-BUILDER-UI">
 * <title>GtkOverlay as GtkBuildable</title>
 * <para>
 * The GtkOverlay implementation of the GtkBuildable interface
 * supports placing a child as an overlay by specifying "overlay" as
 * the "type" attribute of a <tag class="starttag">child</tag> element.
 * </para>
 * </refsect2>
 */

struct _GtkOverlayPrivate
{
  GSList *children;
};

typedef struct _GtkOverlayChild GtkOverlayChild;

struct _GtkOverlayChild
{
  GtkWidget *widget;
  GdkWindow *window;
};

enum {
  GET_CHILD_POSITION,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

static void gtk_overlay_buildable_init (GtkBuildableIface *iface);

G_DEFINE_TYPE_WITH_CODE (GtkOverlay, gtk_overlay, GTK_TYPE_BIN,
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                gtk_overlay_buildable_init))

static GdkWindow *
gtk_overlay_create_child_window (GtkOverlay *overlay,
                                 GtkWidget  *child)
{
  GtkWidget *widget = GTK_WIDGET (overlay);
  GtkAllocation allocation;
  GdkWindow *window;
  GdkWindowAttr attributes;
  gint attributes_mask;

  gtk_widget_get_allocation (child, &allocation);

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.width = allocation.width;
  attributes.height = allocation.height;
  attributes.x = allocation.x;
  attributes.y = allocation.y;
  attributes_mask = GDK_WA_X | GDK_WA_Y;
  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;

  window = gdk_window_new (gtk_widget_get_window (widget),
                           &attributes, attributes_mask);
  gdk_window_set_user_data (window, overlay);
  gtk_style_context_set_background (gtk_widget_get_style_context (widget), window);

  gtk_widget_set_parent_window (child, window);

  return window;
}

static void
gtk_overlay_get_main_widget_allocation (GtkOverlay *overlay,
                                        GtkAllocation *main_alloc_out)
{
  GtkWidget *main_widget;
  GtkAllocation main_alloc;

  main_widget = gtk_bin_get_child (GTK_BIN (overlay));

  /* special-case scrolled windows */
  if (GTK_IS_SCROLLED_WINDOW (main_widget))
    {
      GtkWidget *grandchild;
      gint x, y;

      grandchild = gtk_bin_get_child (GTK_BIN (main_widget));
      res = gtk_widget_translate_coordinates (grandchild, main_widget, 0, 0, &x, &y);

      main_alloc.x = x;
      main_alloc.y = y;
      main_alloc.width = gtk_widget_get_allocated_width (grandchild);
      main_alloc.height = gtk_widget_get_allocated_height (grandchild);
    }
  else
    {
      main_alloc.x = 0;
      main_alloc.y = 0;
      main_alloc.width = gtk_widget_get_allocated_width (main_widget);
      main_alloc.height = gtk_widget_get_allocated_height (main_widget);
    }

  if (main_alloc_out)
    *main_alloc_out = main_alloc;
}

static void
gtk_overlay_child_allocate (GtkOverlay      *overlay,
                            GtkOverlayChild *child)
{
  gint left, right, top, bottom;
  GtkAllocation allocation, child_allocation, overlay_allocation;
  gboolean result;

  if (gtk_widget_get_mapped (GTK_WIDGET (overlay)))
    {
      if (gtk_widget_get_visible (child->widget))
        gdk_window_show (child->window);
      else if (gdk_window_is_visible (child->window))
        gdk_window_hide (child->window);<commit_msg>overlay: do not to set uninitialized values in the main allocation<commit_after>/*
 * gtkoverlay.c
 * This file is part of gtk
 *
 * Copyright (C) 2011 - <NAME>, <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include "gtkoverlay.h"
#include "gtkbuildable.h"
#include "gtkscrolledwindow.h"
#include "gtkmarshalers.h"

#include "gtkprivate.h"
#include "gtkintl.h"

/**
 * SECTION:gtkoverlay
 * @short_description: A container which overlays widgets on top of each other
 * @title: GtkOverlay
 *
 * GtkOverlay is a container which contains a single main child, on top
 * of which it can place <firstterm>overlay</firstterm> widgets. The
 * position of each overlay widget is determined by its #GtkWidget:halign
 * and #GtkWidget:valign properties. E.g. a widget with both alignments
 * set to %GTK_ALIGN_START will be placed at the top left corner of the
 * main widget, whereas an overlay with halign set to %GTK_ALIGN_CENTER
 * and valign set to %GTK_ALIGN_END will be placed a the bottom edge of
 * the main widget, horizontally centered. The position can be adjusted
 * by setting the margin properties of the child to non-zero values.
 *
 * More complicated placement of overlays is possible by connecting
 * to the #GtkOverlay::get-child-position signal.
 *
 * <refsect2 id="GtkOverlay-BUILDER-UI">
 * <title>GtkOverlay as GtkBuildable</title>
 * <para>
 * The GtkOverlay implementation of the GtkBuildable interface
 * supports placing a child as an overlay by specifying "overlay" as
 * the "type" attribute of a <tag class="starttag">child</tag> element.
 * </para>
 * </refsect2>
 */

struct _GtkOverlayPrivate
{
  GSList *children;
};

typedef struct _GtkOverlayChild GtkOverlayChild;

struct _GtkOverlayChild
{
  GtkWidget *widget;
  GdkWindow *window;
};

enum {
  GET_CHILD_POSITION,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

static void gtk_overlay_buildable_init (GtkBuildableIface *iface);

G_DEFINE_TYPE_WITH_CODE (GtkOverlay, gtk_overlay, GTK_TYPE_BIN,
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                gtk_overlay_buildable_init))

static GdkWindow *
gtk_overlay_create_child_window (GtkOverlay *overlay,
                                 GtkWidget  *child)
{
  GtkWidget *widget = GTK_WIDGET (overlay);
  GtkAllocation allocation;
  GdkWindow *window;
  GdkWindowAttr attributes;
  gint attributes_mask;

  gtk_widget_get_allocation (child, &allocation);

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.width = allocation.width;
  attributes.height = allocation.height;
  attributes.x = allocation.x;
  attributes.y = allocation.y;
  attributes_mask = GDK_WA_X | GDK_WA_Y;
  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;

  window = gdk_window_new (gtk_widget_get_window (widget),
                           &attributes, attributes_mask);
  gdk_window_set_user_data (window, overlay);
  gtk_style_context_set_background (gtk_widget_get_style_context (widget), window);

  gtk_widget_set_parent_window (child, window);

  return window;
}

static void
gtk_overlay_get_main_widget_allocation (GtkOverlay *overlay,
                                        GtkAllocation *main_alloc_out)
{
  GtkWidget *main_widget;
  GtkAllocation main_alloc;

  main_widget = gtk_bin_get_child (GTK_BIN (overlay));

  /* special-case scrolled windows */
  if (GTK_IS_SCROLLED_WINDOW (main_widget))
    {
      GtkWidget *grandchild;
      gint x, y;
      gboolean res;

      grandchild = gtk_bin_get_child (GTK_BIN (main_widget));
      res = gtk_widget_translate_coordinates (grandchild, main_widget, 0, 0, &x, &y);

      if (res)
        {
          main_alloc.x = x;
          main_alloc.y = y;
        }
      else
        {
          main_alloc.x = 0;
          main_alloc.y = 0;
        }

      main_alloc.width = gtk_widget_get_allocated_width (grandchild);
      main_alloc.height = gtk_widget_get_allocated_height (grandchild);
    }
  else
    {
      main_alloc.x = 0;
      main_alloc.y = 0;
      main_alloc.width = gtk_widget_get_allocated_width (main_widget);
      main_alloc.height = gtk_widget_get_allocated_height (main_widget);
    }

  if (main_alloc_out)
    *main_alloc_out = main_alloc;
}

static void
gtk_overlay_child_allocate (GtkOverlay      *overlay,
                            GtkOverlayChild *child)
{
  gint left, right, top, bottom;
  GtkAllocation allocation, child_allocation, overlay_allocation;
  gboolean result;

  if (gtk_widget_get_mapped (GTK_WIDGET (overlay)))
    {
      if (gtk_widget_get_visible (child->widget))
        gdk_window_show (child->window);
      else if (gdk_window_is_visible (child->window))
        gdk_window_hide (child->window);
{'fraction_non_alphanumeric': 0.0808574652124859, 'fraction_numerical': 0.002444528018051899, 'mean_word_length': 3.5908502373759172, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6564324', 'n_tokens_mistral': 3405, 'n_tokens_neox': 3338, 'n_words': 966}