### ----------------------------------------------------
### -- Gnome::Gdk3
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman
### -- File: lib/Gnome/Gdk3/Window.rakumod
### ----------------------------------------------------
### -- Chunk 1 of 5
use v6;
#-------------------------------------------------------------------------------
=begin pod

=head1 Gnome::Gdk3::Window

Onscreen display areas in the target window system

=head1 Description

A B<Gnome::Gdk3::Window> is a (usually) rectangular region on the screen. It’s a low-level object, used to implement high-level objects such as B<Gnome::Gtk3::Widget> and B<Gnome::Gtk3::Window> on the GTK+ level. A B<Gnome::Gtk3::Window> is a toplevel window, the thing a user might think of as a “window” with a titlebar and so on; a B<Gnome::Gtk3::Window> may contain many B<Gnome::Gdk3::Windows>. For example, each B<Gnome::Gtk3::Button> has a B<Gnome::Gdk3::Window> associated with it.


=head2 Composited Windows

Normally, the windowing system takes care of rendering the contents of a child window onto its parent window. This mechanism can be intercepted by calling C<gdk_window_set_composited()> on the child window. For a “composited” window it is the responsibility of the application to render the window contents at the right spot.


=head2 Offscreen Windows

Offscreen windows are more general than composited windows, since they allow not only to modify the rendering of the child window onto its parent, but also to apply coordinate transformations.

To integrate an offscreen window into a window hierarchy, one has to call C<gdk_offscreen_window_set_embedder()> and handle a number of signals. The  I<pick-embedded-child> signal on the embedder window is used to select an offscreen child at given coordinates, and the  I<to-embedder> and  I<from-embedder> signals on the offscreen window are used to translate coordinates between the embedder and the offscreen window.

For rendering an offscreen window onto its embedder, the contents of the offscreen window are available as a surface, via C<gdk_offscreen_window_get_surface()>.


=head2 Testing

Some routines are added to this module for GUI testing. They were in a separate C file but could be included here. These are test utilities to test some of the events generated by mouse and keyboard. This set of routines will not be of much use for the GUI developer. However, for interface testing, this module is may be of use. A package which will be using this, is in development and is called B<Gnome::T>.


=head1 Synopsis
=head2 Declaration

  unit class Gnome::Gdk3::Window;
  also is Gnome::GObject::Object;

=comment head2 Example

=end pod
#-------------------------------------------------------------------------------
use NativeCall;

use Gnome::N::X:api<1>;
use Gnome::N::NativeLib:api<1>;
use Gnome::N::N-GObject:api<1>;
use Gnome::N::GlibToRakuTypes:api<1>;

use Gnome::Glib::Error:api<1>;
use Gnome::Glib::List:api<1>;

use Gnome::GObject::Object:api<1>;

use Gnome::Gdk3::Types:api<1>;
use Gnome::Gdk3::Events:api<1>;
use Gnome::Gdk3::Device:api<1>;

#use Gnome::Cairo;
use Gnome::Cairo::Types:api<1>;
use Gnome::Cairo::Enums:api<1>;

#-------------------------------------------------------------------------------
# /usr/include/gtk-3.0/gdk/gdkwindow.h
# https://developer.gnome.org/gdk3/stable/gdk3-Windows.html
unit class Gnome::Gdk3::Window:auth<github:MARTIMM>:api<1>;
also is Gnome::GObject::Object;

#-------------------------------------------------------------------------------
=begin pod
=head1 Types
=end pod
#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkAnchorHints

Positioning hints for aligning a window relative to a rectangle.

These hints determine how the window should be positioned in the case that
the window would fall off-screen if placed in its ideal position.

For example, C<GDK_ANCHOR_FLIP_X> will replace C<GDK_GRAVITY_NORTH_WEST> with
C<GDK_GRAVITY_NORTH_EAST> and vice versa if the window extends beyond the left
or right edges of the monitor.

If C<GDK_ANCHOR_SLIDE_X> is set, the window can be shifted horizontally to fit
on-screen. If C<GDK_ANCHOR_RESIZE_X> is set, the window can be shrunken
horizontally to fit.

In general, when multiple flags are set, flipping should take precedence over
sliding, which should take precedence over resizing.

Stability: Unstable


=item GDK_ANCHOR_FLIP_X: allow flipping anchors horizontally
=item GDK_ANCHOR_FLIP_Y: allow flipping anchors vertically
=item GDK_ANCHOR_SLIDE_X: allow sliding window horizontally
=item GDK_ANCHOR_SLIDE_Y: allow sliding window vertically
=item GDK_ANCHOR_RESIZE_X: allow resizing window horizontally
=item GDK_ANCHOR_RESIZE_Y: allow resizing window vertically
=item GDK_ANCHOR_FLIP: allow flipping anchors on both axes
=item GDK_ANCHOR_SLIDE: allow sliding window on both axes
=item GDK_ANCHOR_RESIZE: allow resizing window on both axes


=end pod

#TE:0:GdkAnchorHints:
enum GdkAnchorHints is export (
  'GDK_ANCHOR_FLIP_X'   => 1 +< 0,
  'GDK_ANCHOR_FLIP_Y'   => 1 +< 1,
  'GDK_ANCHOR_SLIDE_X'  => 1 +< 2,
  'GDK_ANCHOR_SLIDE_Y'  => 1 +< 3,
  'GDK_ANCHOR_RESIZE_X' => 1 +< 4,
  'GDK_ANCHOR_RESIZE_Y' => 1 +< 5,

#  'GDK_ANCHOR_FLIP'     => GDK_ANCHOR_FLIP_X +| GDK_ANCHOR_FLIP_Y,
#  'GDK_ANCHOR_SLIDE'    => GDK_ANCHOR_SLIDE_X +| GDK_ANCHOR_SLIDE_Y,
#  'GDK_ANCHOR_RESIZE'   => GDK_ANCHOR_RESIZE_X +| GDK_ANCHOR_RESIZE_Y
  'GDK_ANCHOR_FLIP'     => 1 +< 0 +| 1 +< 1,
  'GDK_ANCHOR_SLIDE'    => 1 +< 2 +| 1 +< 3,
  'GDK_ANCHOR_RESIZE'   => 1 +< 4 +| 1 +< 5
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkFullscreenMode

Indicates which monitor (in a multi-head setup) a window should span over
when in fullscreen mode.



=item GDK_FULLSCREEN_ON_CURRENT_MONITOR: Fullscreen on current monitor only.
=item GDK_FULLSCREEN_ON_ALL_MONITORS: Span across all monitors when fullscreen.


=end pod

#TE:0:GdkFullscreenMode:
enum GdkFullscreenMode is export (
  'GDK_FULLSCREEN_ON_CURRENT_MONITOR',
  'GDK_FULLSCREEN_ON_ALL_MONITORS'
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkGravity

Defines the reference point of a window and the meaning of coordinates
passed to C<gtk_window_move()>. See C<gtk_window_move()> and the "implementation
notes" section of the
[Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec)
specification for more details.


=item GDK_GRAVITY_NORTH_WEST: the reference point is at the top left corner.
=item GDK_GRAVITY_NORTH: the reference point is in the middle of the top edge.
=item GDK_GRAVITY_NORTH_EAST: the reference point is at the top right corner.
=item GDK_GRAVITY_WEST: the reference point is at the middle of the left edge.
=item GDK_GRAVITY_CENTER: the reference point is at the center of the window.
=item GDK_GRAVITY_EAST: the reference point is at the middle of the right edge.
=item GDK_GRAVITY_SOUTH_WEST: the reference point is at the lower left corner.
=item GDK_GRAVITY_SOUTH: the reference point is at the middle of the lower edge.
=item GDK_GRAVITY_SOUTH_EAST: the reference point is at the lower right corner.
=item GDK_GRAVITY_STATIC: the reference point is at the top left corner of the window itself, ignoring window manager decorations.


=end pod

#TE:0:GdkGravity:
enum GdkGravity is export (
  'GDK_GRAVITY_NORTH_WEST' => 1,
  'GDK_GRAVITY_NORTH',
  'GDK_GRAVITY_NORTH_EAST',
  'GDK_GRAVITY_WEST',
  'GDK_GRAVITY_CENTER',
  'GDK_GRAVITY_EAST',
  'GDK_GRAVITY_SOUTH_WEST',
  'GDK_GRAVITY_SOUTH',
  'GDK_GRAVITY_SOUTH_EAST',
  'GDK_GRAVITY_STATIC'
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWMDecoration

These are hints originally defined by the Motif toolkit.
The window manager can use them when determining how to decorate
the window. The hint must be set before mapping the window.


=item GDK_DECOR_ALL: all decorations should be applied.
=item GDK_DECOR_BORDER: a frame should be drawn around the window.
=item GDK_DECOR_RESIZEH: the frame should have resize handles.
=item GDK_DECOR_TITLE: a titlebar should be placed above the window.
=item GDK_DECOR_MENU: a button for opening a menu should be included.
=item GDK_DECOR_MINIMIZE: a minimize button should be included.
=item GDK_DECOR_MAXIMIZE: a maximize button should be included.


=end pod

#TE:0:GdkWMDecoration:
enum GdkWMDecoration is export (
  'GDK_DECOR_ALL'		=> 1 +< 0,
  'GDK_DECOR_BORDER'	=> 1 +< 1,
  'GDK_DECOR_RESIZEH'	=> 1 +< 2,
  'GDK_DECOR_TITLE'	=> 1 +< 3,
  'GDK_DECOR_MENU'	=> 1 +< 4,
  'GDK_DECOR_MINIMIZE'	=> 1 +< 5,
  'GDK_DECOR_MAXIMIZE'	=> 1 +< 6
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWMFunction

These are hints originally defined by the Motif toolkit. The window manager
can use them when determining the functions to offer for the window. The
hint must be set before mapping the window.


=item GDK_FUNC_ALL: all functions should be offered.
=item GDK_FUNC_RESIZE: the window should be resizable.
=item GDK_FUNC_MOVE: the window should be movable.
=item GDK_FUNC_MINIMIZE: the window should be minimizable.
=item GDK_FUNC_MAXIMIZE: the window should be maximizable.
=item GDK_FUNC_CLOSE: the window should be closable.


=end pod

#TE:0:GdkWMFunction:
enum GdkWMFunction is export (
  'GDK_FUNC_ALL'		=> 1 +< 0,
  'GDK_FUNC_RESIZE'	=> 1 +< 1,
  'GDK_FUNC_MOVE'		=> 1 +< 2,
  'GDK_FUNC_MINIMIZE'	=> 1 +< 3,
  'GDK_FUNC_MAXIMIZE'	=> 1 +< 4,
  'GDK_FUNC_CLOSE'	=> 1 +< 5
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWindowAttributesType

Used to indicate which fields in the B<Gnome::Gdk3::WindowAttr> struct should be honored.
For example, if you filled in the “cursor” and “x” fields of B<Gnome::Gdk3::WindowAttr>,
pass “I<GDK_WA_X> | I<GDK_WA_CURSOR>” to C<new()>. Fields in
B<Gnome::Gdk3::WindowAttr> not covered by a bit in this enum are required; for example,
the I<width>/I<height>, I<wclass>, and I<window_type> fields are required, they have
no corresponding flag in B<Gnome::Gdk3::WindowAttributesType>.


=item GDK_WA_TITLE: Honor the title field
=item GDK_WA_X: Honor the X coordinate field
=item GDK_WA_Y: Honor the Y coordinate field
=item GDK_WA_CURSOR: Honor the cursor field
=item GDK_WA_VISUAL: Honor the visual field
=item GDK_WA_WMCLASS: Honor the wmclass_class and wmclass_name fields
=item GDK_WA_NOREDIR: Honor the override_redirect field
=item GDK_WA_TYPE_HINT: Honor the type_hint field


=end pod

#TE:0:GdkWindowAttributesType:
enum GdkWindowAttributesType is export (
  'GDK_WA_TITLE'	   => 1 +< 1,
  'GDK_WA_X'	   => 1 +< 2,
  'GDK_WA_Y'	   => 1 +< 3,
  'GDK_WA_CURSOR'	   => 1 +< 4,
  'GDK_WA_VISUAL'	   => 1 +< 5,
  'GDK_WA_WMCLASS'   => 1 +< 6,
  'GDK_WA_NOREDIR'   => 1 +< 7,
  'GDK_WA_TYPE_HINT' => 1 +< 8
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWindowEdge

Determines a window edge or corner.


=item GDK_WINDOW_EDGE_NORTH_WEST: the top left corner.
=item GDK_WINDOW_EDGE_NORTH: the top edge.
=item GDK_WINDOW_EDGE_NORTH_EAST: the top right corner.
=item GDK_WINDOW_EDGE_WEST: the left edge.
=item GDK_WINDOW_EDGE_EAST: the right edge.
=item GDK_WINDOW_EDGE_SOUTH_WEST: the lower left corner.
=item GDK_WINDOW_EDGE_SOUTH: the lower edge.
=item GDK_WINDOW_EDGE_SOUTH_EAST: the lower right corner.


=end pod

#TE:0:GdkWindowEdge:
enum GdkWindowEdge is export (
  'GDK_WINDOW_EDGE_NORTH_WEST',
  'GDK_WINDOW_EDGE_NORTH',
  'GDK_WINDOW_EDGE_NORTH_EAST',
  'GDK_WINDOW_EDGE_WEST',
  'GDK_WINDOW_EDGE_EAST',
  'GDK_WINDOW_EDGE_SOUTH_WEST',
  'GDK_WINDOW_EDGE_SOUTH',
  'GDK_WINDOW_EDGE_SOUTH_EAST'
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWindowHints

Used to indicate which fields of a B<Gnome::Gdk3::Geometry> struct should be paid
attention to. Also, the presence/absence of I<GDK_HINT_POS>,
I<GDK_HINT_USER_POS>, and I<GDK_HINT_USER_SIZE> is significant, though they don't
directly refer to B<Gnome::Gdk3::Geometry> fields. I<GDK_HINT_USER_POS> will be set
automatically by B<Gnome::Gdk3::Window> if you call C<gtk_window_move()>.
I<GDK_HINT_USER_POS> and I<GDK_HINT_USER_SIZE> should be set if the user
specified a size/position using a --geometry command-line argument;
C<gtk_window_parse_geometry()> automatically sets these flags.


=item GDK_HINT_POS: indicates that the program has positioned the window
=item GDK_HINT_MIN_SIZE: min size fields are set
=item GDK_HINT_MAX_SIZE: max size fields are set
=item GDK_HINT_BASE_SIZE: base size fields are set
=item GDK_HINT_ASPECT: aspect ratio fields are set
=item GDK_HINT_RESIZE_INC: resize increment fields are set
=item GDK_HINT_WIN_GRAVITY: window gravity field is set
=item GDK_HINT_USER_POS: indicates that the window’s position was explicitly set by the user
=item GDK_HINT_USER_SIZE: indicates that the window’s size was explicitly set by the user


=end pod

#TE:1:GdkWindowHints:
enum GdkWindowHints is export (
  'GDK_HINT_POS'	       => 1 +< 0,
  'GDK_HINT_MIN_SIZE'    => 1 +< 1,
  'GDK_HINT_MAX_SIZE'    => 1 +< 2,
  'GDK_HINT_BASE_SIZE'   => 1 +< 3,
  'GDK_HINT_ASPECT'      => 1 +< 4,
  'GDK_HINT_RESIZE_INC'  => 1 +< 5,
  'GDK_HINT_WIN_GRAVITY' => 1 +< 6,
  'GDK_HINT_USER_POS'    => 1 +< 7,
  'GDK_HINT_USER_SIZE'   => 1 +< 8
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWindowType

Describes the kind of window.


=item GDK_WINDOW_ROOT: root window; this window has no parent, covers the entire screen, and is created by the window system
=item GDK_WINDOW_TOPLEVEL: toplevel window (used to implement B<Gnome::Gdk3::Window>)
=item GDK_WINDOW_CHILD: child window (used to implement e.g. B<Gnome::Gdk3::Entry>)
=item GDK_WINDOW_TEMP: override redirect temporary window (used to implement B<Gnome::Gdk3::Menu>)
=item GDK_WINDOW_FOREIGN: foreign window (see C<foreign_new()>)
=item GDK_WINDOW_OFFSCREEN: offscreen window (see [Offscreen Windows][OFFSCREEN-WINDOWS]). Since 2.18
=item GDK_WINDOW_SUBSURFACE: subsurface-based window; This window is visually tied to a toplevel, and is moved/stacked with it. Currently this window type is only implemented in Wayland. Since 3.14


=end pod

#TE:0:GdkWindowType:
enum GdkWindowType is export (
  'GDK_WINDOW_ROOT',
  'GDK_WINDOW_TOPLEVEL',
  'GDK_WINDOW_CHILD',
  'GDK_WINDOW_TEMP',
  'GDK_WINDOW_FOREIGN',
  'GDK_WINDOW_OFFSCREEN',
  'GDK_WINDOW_SUBSURFACE'
);

#-------------------------------------------------------------------------------
=begin pod
=head2 enum GdkWindowWindowClass

I<GDK_INPUT_OUTPUT> windows are the standard kind of window you might expect.
Such windows receive events and are also displayed on screen.
I<GDK_INPUT_ONLY> windows are invisible; they are usually placed above other
windows in order to trap or filter the events. You can’t draw on
I<GDK_INPUT_ONLY> windows.

=item GDK_INPUT_OUTPUT: window for graphics and events
=item GDK_INPUT_ONLY: window for events only

=end pod

#TE:0:GdkWindowWindowClass:
enum GdkWindowWindowClass is export (
  'GDK_INPUT_OUTPUT', 'GDK_INPUT_ONLY'
);

#-------------------------------------------------------------------------------
=begin pod
=head2 class N-GdkGeometry

The B<Gnome::Gdk3::Geometry> struct gives the window manager information about
a window’s geometry constraints. Normally you would set these on
the GTK+ level using C<gtk_window_set_geometry_hints()>. B<Gnome::Gdk3::Window>
then sets the hints on the B<Gnome::Gdk3::Window> it creates.

C<set_geometry_hints()> expects the hints to be fully valid already
and simply passes them to the window manager; in contrast,
C<gtk_window_set_geometry_hints()> performs some interpretation. For example,
B<Gnome::Gdk3::Window> will apply the hints to the geometry widget instead of the
toplevel window, if you set a geometry widget. Also, the
I<min_width>/I<min_height>/I<max_width>/I<max_height> fields may be set to -1, and
B<Gnome::Gdk3::Window> will substitute the size request of the window or geometry widget.
If the minimum size hint is not provided, B<Gnome::Gdk3::Window> will use its requisition
as the minimum size. If the minimum size is provided and a geometry widget is
set, B<Gnome::Gdk3::Window> will take the minimum size as the minimum size of the
geometry widget rather than the entire window. The base size is treated
similarly.

The canonical use-case for C<gtk_window_set_geometry_hints()> is to get a
terminal widget to resize properly. Here, the terminal text area should be
the geometry widget; B<Gnome::Gdk3::Window> will then automatically set the base size to
the size of other widgets in the terminal window, such as the menubar and
scrollbar. Then, the I<width_inc> and I<height_inc> fields should be set to the
size of one character in the terminal. Finally, the base size should be set
to the size of one character. The net effect is that the minimum size of the
terminal will have a 1x1 character terminal area, and only terminal sizes on
the “character grid” will be allowed.

Here’s an example of how the terminal example would be implemented, assuming
a terminal area widget called “terminal” and a toplevel window “toplevel”:

=begin comment
|[<!-- language="C" -->
N-GdkGeometry hints;

hints.base_width = terminal->char_width;
hints.base_height = terminal->char_height;
hints.min_width = terminal->char_width;
hints.min_height = terminal->char_height;
hints.width_inc = terminal->char_width;
hints.height_inc = terminal->char_height;

gtk_window_set_geometry_hints (GTK_WINDOW (toplevel),
GTK_WIDGET (terminal),
&hints,
GDK_HINT_RESIZE_INC |
GDK_HINT_MIN_SIZE |
GDK_HINT_BASE_SIZE);
]|
=end comment

The other useful fields are the I<min_aspect> and I<max_aspect> fields; these
contain a width/height ratio as a floating point number. If a geometry widget
is set, the aspect applies to the geometry widget rather than the entire
window. The most common use of these hints is probably to set I<min_aspect> and
I<max_aspect> to the same value, thus forcing the window to keep a constant
aspect ratio.


=item C<Int()> $.min_width: minimum width of window (or -1 to use requisition, with B<Gnome::Gdk3::Window> only)
=item C<Int()> $.min_height: minimum height of window (or -1 to use requisition, with B<Gnome::Gdk3::Window> only)
=item C<Int()> $.max_width: maximum width of window (or -1 to use requisition, with B<Gnome::Gdk3::Window> only)
=item C<Int()> $.max_height: maximum height of window (or -1 to use requisition, with B<Gnome::Gdk3::Window> only)
=item C<Int()> $.base_width: allowed window widths are I<base_width> + I<width_inc> * N where N is any integer (-1 allowed with B<Gnome::Gdk3::Window>)
=item C<Int()> $.base_height: allowed window widths are I<base_height> + I<height_inc> * N where N is any integer (-1 allowed with B<Gnome::Gdk3::Window>)
=item C<Int()> $.width_inc: width resize increment
=item C<Int()> $.height_inc: height resize increment
=item C<Num()> $.min_aspect: minimum width/height ratio
=item C<Num()> $.max_aspect: maximum width/height ratio
=item GdkGravity $.win_gravity: window gravity, see C<gtk_window_set_gravity()>


=end pod

#TT:1:N-GdkGeometry:
class N-GdkGeometry is export is repr('CStruct') {
  has gint $.min_width;
  has gint $.min_height;
  has gint $.max_width;
  has gint $.max_height;
  has gint $.base_width;
  has gint $.base_height;
  has gint $.width_inc;
  has gint $.height_inc;
  has gdouble $.min_aspect;
  has gdouble $.max_aspect;
  has GEnum $.win_gravity;
}

#-------------------------------------------------------------------------------
=begin pod
=head2 class N-GdkWindowAttr

Attributes to use for a newly-created window.


=item Str $.title: title of the window (for toplevel windows)
=item C<Int()> $.event_mask: event mask (see C<set_events()>)
=item C<Int()> $.x: X coordinate relative to parent window (see C<move()>)
=item C<Int()> $.y: Y coordinate relative to parent window (see C<move()>)
=item C<Int()> $.width: width of window
=item C<Int()> $.height: height of window
=item GdkWindowWindowClass $.wclass: B<Gnome::Gdk3::DK_INPUT_OUTPUT> (normal window) or B<Gnome::Gdk3::DK_INPUT_ONLY> (invisible window that receives events)
=item N-GObject $.visual: B<Gnome::Gdk3::Visual> for window
=item GdkWindowType $.window_type: type of window
=item N-GObject $.cursor: cursor for the window (see C<set_cursor()>)
=item Str $.wmclass_name: don’t use (see C<gtk_window_set_wmclass()>)
=item Str $.wmclass_class: don’t use (see C<gtk_window_set_wmclass()>)
=item Bool $.override_redirect: C<True> to bypass the window manager
=item GdkWindowTypeHint $.type_hint: a hint of the function of the window


=end pod

#TT:0:N-GdkWindowAttr:
class N-GdkWindowAttr is export is repr('CStruct') {
  has gchar-ptr $.title;
  has gint $.event_mask;
  has gint $.x;
  has gint $.y;
  has gint $.width;
  has gint $.height;
  has GEnum $.wclass;
  has N-GObject $.visual;
  has GEnum $.window_type;
  has N-GObject $.cursor;
  has gchar-ptr $.wmclass_name;
  has gchar-ptr $.wmclass_class;
  has gboolean $.override_redirect;
  has GEnum $.type_hint;
}

#-------------------------------------------------------------------------------
my Bool $signals-added = False;
#-------------------------------------------------------------------------------
=begin pod
=head1 Methods
=head2 new

=begin comment
=head3 new( :event_mask, :wclass, :window_type, :override_redirect)

Creates a new B<Gnome::Gdk3::Window> using the attributes from I<attributes>. See B<Gnome::Gdk3::WindowAttr> and B<Gnome::Gdk3::WindowAttributesType> for more details.

Note: to use this on displays other than the default display, I<parent> must be specified.

  multi method new ( N-GdkWindowAttr :$attributes, Int $attributes_mask --> N-GObject  )

=item N-GdkWindowAttr $attributes; attributes of the new window
=item Int $attributes_mask; (type B<Gnome::Gdk3::WindowAttributesType>): mask indicating which fields in I<attributes> are valid
=end comment
=end pod

#TM:1:new():
#TM:0:new(:):

submethod BUILD ( *%options ) {

  # add signal info in the form of group<signal-name>.
  # groups are e.g. signal, event, nativeobject etc
  $signals-added = self.add-signal-types( $?CLASS.^name,
    :w2<pick-embedded-child create-surface>,
    :w4<to-embedder from-embedder moved-to-rect>,
  ) unless $signals-added;

  # prevent creating wrong widgets
  if self.^name eq 'Gnome::Gdk3::Window' #`{{ or %options<GdkWindow> }} {

    if self.is-valid { }

    # process all named arguments
    elsif %options<native-object>:exists { }

    else {
      my $no;

      if %options.keys.elems {
        die X::Gnome.new(
          :message('Unsupported options for ' ~ self.^name ~
                   ': ' ~ %options.keys.join(', ')
                  )
        );
      }

      else {

        # GDK_WINDOW_ROOT cannot be used because it covers the entire
        # screen, and is created by the window system. (there can only be one!).
        my N-GdkWindowAttr $attrs .= new(
          :event_mask(0), :wclass(GDK_INPUT_OUTPUT),
          :window_type(GDK_WINDOW_TOPLEVEL), :override_redirect(0)
        );

        # No parent, no extra attributes, toplevel
        $no = _gdk_window_new( Any, $attrs, 0);
      }

      self._set-native-object($no);
    }

    # only after creating the native-object, the gtype is known
    self._set-class-info('GdkWindow');
  }
}

#-------------------------------------------------------------------------------
# no pod. user does not have to know about it.
method _fallback ( $native-sub is copy --> Callable ) {

  my Callable $s;
  try { $s = &::("gdk_window_$native-sub"); };
  try { $s = &::("gdk_$native-sub"); } unless ?$s;
  try { $s = &::($native-sub); } if !$s and $native-sub ~~ m/^ 'gdk_' /;

  self._set-class-name-of-sub('GdkWindow');
  $s = callsame unless ?$s;

  $s;
}

#`{{
#-------------------------------------------------------------------------------
#TM:0:add-filter:
=begin pod
=head2 add-filter

Adds an event filter to I<window>, allowing you to intercept events before they reach GDK. This is a low-level operation and makes it easy to break GDK and/or GTK+, so you have to know what you're doing. Pass C<undefined> for I<window> to get all events for all windows, instead of events for a specific window.

If you are interested in X GenericEvents, bear in mind that C<XGetEventData()> has been already called on the event, and C<XFreeEventData()> must not be called within I<function>.

  method add-filter ( GdkFilterFunc $function, Pointer $data )

=item $function; filter callback
=item $data; data to pass to filter callback
=end pod

method add-filter ( GdkFilterFunc $function, Pointer $data ) {

  gdk_window_add_filter(
    self._get-native-object-no-reffing, $function, $data
  );
}

sub gdk_window_add_filter (
  N-GObject $window, GdkFilterFunc $function, gpointer $data
) is native(&gdk-lib)
  { * }
}}

#-------------------------------------------------------------------------------
#TM:1:beep:
=begin pod
=head2 beep

Emits a short beep associated to I<window> in the appropriate display, if supported. Otherwise, emits a short beep on the display just as C<Gnome::Gdk3::Display.beep()>.

  method beep ( )

=end pod

method beep ( ) {
  gdk_window_beep(self._get-native-object-no-reffing);
}

sub gdk_window_beep (
  N-GObject $window
) is native(&gdk-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:begin-draw-frame:
=begin pod
=head2 begin-draw-frame

Indicates that you are beginning the process of redrawing I<region> on I<window>, and provides you with a B<Gnome::Gdk3::DrawingContext>.

If I<window> is a top level B<Gnome::Gdk3::Window>, backed by a native window implementation, a backing store (offscreen buffer) large enough to contain I<region> will be created. The backing store will be initialized with the background color or background surface for I<window>. Then, all drawing operations performed on I<window> will be diverted to the backing store. When you call C<end_frame()>, the contents of the backing store will be copied to I<window>, making it visible on screen. Only the part of I<window> contained in I<region> will be modified; that is, drawing operations are clipped to I<region>.

The net result of all this is to remove flicker, because the user sees the finished product appear all at once when you call C<end_draw_frame()>. If you draw to I<window> directly without calling C<begin_draw_frame()>, the user may see flicker as individual drawing operations are performed in sequence.

When using GTK+, the widget system automatically places calls to C<begin_draw_frame()> and C<end_draw_frame()> around emissions of the `GtkWidget::draw` signal. That is, if you’re drawing the contents of the widget yourself, you can assume that the widget has a cleared background, is already set as the clip region, and already has a backing store. Therefore in most cases, application code in GTK does not need to call C<begin_draw_frame()> explicitly.

Returns: a B<Gnome::Gdk3::DrawingContext> context that should be used to draw the contents of the window; the returned context is owned by GDK.

  method begin-draw-frame ( cairo_region_t $region --> N-GObject )

=item $region; a Cairo region
=end pod

method begin-draw-frame ( cairo_region_t $region --> N-GObject ) {
  gdk_window_begin_draw_frame(
    self._get-native-object-no-reffing, $region
  )
}

sub gdk_window_begin_draw_frame (
  N-GObject $window, cairo_region_t $region --> N-GObject
) is native(&gdk-lib)
  { * }
}}

#-------------------------------------------------------------------------------
#TM:0:begin-move-drag:
=begin pod
=head2 begin-move-drag

Begins a window move operation (for a toplevel window).

This function assumes that the drag is controlled by the client pointer device, use C<begin_move_drag_for_device()> to begin a drag with a different device.

  method begin-move-drag (
    Int() $button, Int() $root_x, Int() $root_y, UInt $timestamp
  )

=item $button; the button being used to drag, or 0 for a keyboard-initiated drag
=item $root_x; root window X coordinate of mouse click that began the drag
=item $root_y; root window Y coordinate of mouse click that began the drag
=item $timestamp; timestamp of mouse click that began the drag
=end pod

method begin-move-drag (
  Int() $button, Int() $root_x, Int() $root_y, UInt $timestamp
) {
  gdk_window_begin_move_drag(
    self._get-native-object-no-reffing, $button, $root_x, $root_y, $timestamp
  );
}

sub gdk_window_begin_move_drag (
  N-GObject $window, gint $button, gint $root_x, gint $root_y, guint32 $timestamp
) is native(&gdk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:begin-move-drag-for-device:
=begin pod
=head2 begin-move-drag-for-device

Begins a window move operation (for a toplevel window). You might use this function to implement a “window move grip,” for example. The function works best with window managers that support the [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec) but has a fallback implementation for other window managers.

  method begin-move-drag-for-device (
    N-GObject() $device, Int() $button,
    Int() $root_x, Int() $root_y, UInt $timestamp
  )

=item $device; the device used for the operation
=item $button; the button being used to drag, or 0 for a keyboard-initiated drag
=item $root_x; root window X coordinate of mouse click that began the drag
=item $root_y; root window Y coordinate of mouse click that began the drag
=item $timestamp; timestamp of mouse click that began the drag
=end pod

method begin-move-drag-for-device (
  N-GObject() $device, Int() $button,
  Int() $root_x, Int() $root_y, UInt $timestamp
) {
  gdk_window_begin_move_drag_for_device(
    self._get-native-object-no-reffing, $device, $button,
    $root_x, $root_y, $timestamp
  );
}

sub gdk_window_begin_move_drag_for_device (
  N-GObject $window, N-GObject $device, gint $button, gint $root_x, gint $root_y, guint32 $timestamp
) is native(&gdk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:begin-resize-drag:
=begin pod
=head2 begin-resize-drag

Begins a window resize operation (for a toplevel window).

This function assumes that the drag is controlled by the client pointer device, use C<begin_resize_drag_for_device()> to begin a drag with a different device.

  method begin-resize-drag (
    GdkWindowEdge $edge, Int() $button,
    Int() $root_x, Int() $root_y, UInt $timestamp
  )

=item $edge; the edge or corner from which the drag is started
=item $button; the button being used to drag, or 0 for a keyboard-initiated drag
=item $root_x; root window X coordinate of mouse click that began the drag
=item $root_y; root window Y coordinate of mouse click that began the drag
=item $timestamp; timestamp of mouse click that began the drag (use C<gdk_event_get_time()>)
=end pod

method begin-resize-drag (
  GdkWindowEdge $edge, Int() $button,
  Int() $root_x, Int() $root_y, UInt $timestamp
) {
  gdk_window_begin_resize_drag(
    self._get-native-object-no-reffing, $edge, $button, $root_x, $root_y, $timestamp
  );
}

sub gdk_window_begin_resize_drag (
  N-GObject $window, GEnum $edge, gint $button, gint $