// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

#[cfg(feature = "v3_24")]
#[cfg_attr(docsrs, doc(cfg(feature = "v3_24")))]
use crate::{AnchorHints, Gravity};
use crate::{
    Cursor, Device, Display, DragProtocol, DrawingContext, Event, EventMask, FrameClock,
    FullscreenMode, GLContext, Geometry, InputSource, ModifierType, Rectangle, Screen, Visual,
    WMDecoration, WMFunction, WindowEdge, WindowHints, WindowState, WindowType, WindowTypeHint,
};
use glib::{
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::{boxed::Box as Box_, fmt, mem, mem::transmute, ptr};

glib::wrapper! {
    #[doc(alias = "GdkWindow")]
    pub struct Window(Object<ffi::GdkWindow, ffi::GdkWindowClass>);

    match fn {
        type_ => || ffi::gdk_window_get_type(),
    }
}

impl Window {
    //#[doc(alias = "gdk_window_add_filter")]
    //pub fn add_filter(&self, function: /*Unimplemented*/Fn(/*Unimplemented*/XEvent, &Event) -> /*Ignored*/FilterReturn, data: /*Unimplemented*/Option<Basic: Pointer>) {
    //    unsafe { TODO: call ffi:gdk_window_add_filter() }
    //}

    #[doc(alias = "gdk_window_beep")]
    pub fn beep(&self) {
        unsafe {
            ffi::gdk_window_beep(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_begin_draw_frame")]
    pub fn begin_draw_frame(&self, region: &cairo::Region) -> Option<DrawingContext> {
        unsafe {
            from_glib_none(ffi::gdk_window_begin_draw_frame(
                self.to_glib_none().0,
                region.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_begin_move_drag")]
    pub fn begin_move_drag(&self, button: i32, root_x: i32, root_y: i32, timestamp: u32) {
        unsafe {
            ffi::gdk_window_begin_move_drag(
                self.to_glib_none().0,
                button,
                root_x,
                root_y,
                timestamp,
            );
        }
    }

    #[doc(alias = "gdk_window_begin_move_drag_for_device")]
    pub fn begin_move_drag_for_device(
        &self,
        device: &impl IsA<Device>,
        button: i32,
        root_x: i32,
        root_y: i32,
        timestamp: u32,
    ) {
        unsafe {
            ffi::gdk_window_begin_move_drag_for_device(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
                button,
                root_x,
                root_y,
                timestamp,
            );
        }
    }

    #[doc(alias = "gdk_window_begin_resize_drag")]
    pub fn begin_resize_drag(
        &self,
        edge: WindowEdge,
        button: i32,
        root_x: i32,
        root_y: i32,
        timestamp: u32,
    ) {
        unsafe {
            ffi::gdk_window_begin_resize_drag(
                self.to_glib_none().0,
                edge.into_glib(),
                button,
                root_x,
                root_y,
                timestamp,
            );
        }
    }

    #[doc(alias = "gdk_window_begin_resize_drag_for_device")]
    pub fn begin_resize_drag_for_device(
        &self,
        edge: WindowEdge,
        device: &impl IsA<Device>,
        button: i32,
        root_x: i32,
        root_y: i32,
        timestamp: u32,
    ) {
        unsafe {
            ffi::gdk_window_begin_resize_drag_for_device(
                self.to_glib_none().0,
                edge.into_glib(),
                device.as_ref().to_glib_none().0,
                button,
                root_x,
                root_y,
                timestamp,
            );
        }
    }

    #[doc(alias = "gdk_window_coords_from_parent")]
    pub fn coords_from_parent(&self, parent_x: f64, parent_y: f64) -> (f64, f64) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            ffi::gdk_window_coords_from_parent(
                self.to_glib_none().0,
                parent_x,
                parent_y,
                x.as_mut_ptr(),
                y.as_mut_ptr(),
            );
            (x.assume_init(), y.assume_init())
        }
    }

    #[doc(alias = "gdk_window_coords_to_parent")]
    pub fn coords_to_parent(&self, x: f64, y: f64) -> (f64, f64) {
        unsafe {
            let mut parent_x = mem::MaybeUninit::uninit();
            let mut parent_y = mem::MaybeUninit::uninit();
            ffi::gdk_window_coords_to_parent(
                self.to_glib_none().0,
                x,
                y,
                parent_x.as_mut_ptr(),
                parent_y.as_mut_ptr(),
            );
            (parent_x.assume_init(), parent_y.assume_init())
        }
    }

    #[doc(alias = "gdk_window_create_gl_context")]
    pub fn create_gl_context(&self) -> Result<GLContext, glib::Error> {
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::gdk_window_create_gl_context(self.to_glib_none().0, &mut error);
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "gdk_window_deiconify")]
    pub fn deiconify(&self) {
        unsafe {
            ffi::gdk_window_deiconify(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_destroy")]
    pub fn destroy(&self) {
        unsafe {
            ffi::gdk_window_destroy(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_destroy_notify")]
    pub fn destroy_notify(&self) {
        unsafe {
            ffi::gdk_window_destroy_notify(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_end_draw_frame")]
    pub fn end_draw_frame(&self, context: &DrawingContext) {
        unsafe {
            ffi::gdk_window_end_draw_frame(self.to_glib_none().0, context.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_end_paint")]
    pub fn end_paint(&self) {
        unsafe {
            ffi::gdk_window_end_paint(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_ensure_native")]
    pub fn ensure_native(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_ensure_native(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_focus")]
    pub fn focus(&self, timestamp: u32) {
        unsafe {
            ffi::gdk_window_focus(self.to_glib_none().0, timestamp);
        }
    }

    #[doc(alias = "gdk_window_freeze_updates")]
    pub fn freeze_updates(&self) {
        unsafe {
            ffi::gdk_window_freeze_updates(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_fullscreen")]
    pub fn fullscreen(&self) {
        unsafe {
            ffi::gdk_window_fullscreen(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_fullscreen_on_monitor")]
    pub fn fullscreen_on_monitor(&self, monitor: i32) {
        unsafe {
            ffi::gdk_window_fullscreen_on_monitor(self.to_glib_none().0, monitor);
        }
    }

    #[doc(alias = "gdk_window_geometry_changed")]
    pub fn geometry_changed(&self) {
        unsafe {
            ffi::gdk_window_geometry_changed(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_get_accept_focus")]
    #[doc(alias = "get_accept_focus")]
    pub fn accepts_focus(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_get_accept_focus(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_children")]
    #[doc(alias = "get_children")]
    pub fn children(&self) -> Vec<Window> {
        unsafe {
            FromGlibPtrContainer::from_glib_container(ffi::gdk_window_get_children(
                self.to_glib_none().0,
            ))
        }
    }

    //#[doc(alias = "gdk_window_get_children_with_user_data")]
    //#[doc(alias = "get_children_with_user_data")]
    //pub fn children_with_user_data(&self, user_data: /*Unimplemented*/Option<Basic: Pointer>) -> Vec<Window> {
    //    unsafe { TODO: call ffi:gdk_window_get_children_with_user_data() }
    //}

    #[doc(alias = "gdk_window_get_clip_region")]
    #[doc(alias = "get_clip_region")]
    pub fn clip_region(&self) -> Option<cairo::Region> {
        unsafe { from_glib_full(ffi::gdk_window_get_clip_region(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_cursor")]
    #[doc(alias = "get_cursor")]
    pub fn cursor(&self) -> Option<Cursor> {
        unsafe { from_glib_none(ffi::gdk_window_get_cursor(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_decorations")]
    #[doc(alias = "get_decorations")]
    pub fn decorations(&self) -> Option<WMDecoration> {
        unsafe {
            let mut decorations = mem::MaybeUninit::uninit();
            let ret = from_glib(ffi::gdk_window_get_decorations(
                self.to_glib_none().0,
                decorations.as_mut_ptr(),
            ));
            if ret {
                Some(from_glib(decorations.assume_init()))
            } else {
                None
            }
        }
    }

    #[doc(alias = "gdk_window_get_device_cursor")]
    #[doc(alias = "get_device_cursor")]
    pub fn device_cursor(&self, device: &impl IsA<Device>) -> Option<Cursor> {
        unsafe {
            from_glib_none(ffi::gdk_window_get_device_cursor(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_get_device_events")]
    #[doc(alias = "get_device_events")]
    pub fn device_events(&self, device: &impl IsA<Device>) -> EventMask {
        unsafe {
            from_glib(ffi::gdk_window_get_device_events(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_get_device_position")]
    #[doc(alias = "get_device_position")]
    pub fn device_position(
        &self,
        device: &impl IsA<Device>,
    ) -> (Option<Window>, i32, i32, ModifierType) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            let mut mask = mem::MaybeUninit::uninit();
            let ret = from_glib_none(ffi::gdk_window_get_device_position(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
                x.as_mut_ptr(),
                y.as_mut_ptr(),
                mask.as_mut_ptr(),
            ));
            (
                ret,
                x.assume_init(),
                y.assume_init(),
                from_glib(mask.assume_init()),
            )
        }
    }

    #[doc(alias = "gdk_window_get_device_position_double")]
    #[doc(alias = "get_device_position_double")]
    pub fn device_position_double(
        &self,
        device: &impl IsA<Device>,
    ) -> (Option<Window>, f64, f64, ModifierType) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            let mut mask = mem::MaybeUninit::uninit();
            let ret = from_glib_none(ffi::gdk_window_get_device_position_double(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
                x.as_mut_ptr(),
                y.as_mut_ptr(),
                mask.as_mut_ptr(),
            ));
            (
                ret,
                x.assume_init(),
                y.assume_init(),
                from_glib(mask.assume_init()),
            )
        }
    }

    #[doc(alias = "gdk_window_get_display")]
    #[doc(alias = "get_display")]
    pub fn display(&self) -> Display {
        unsafe { from_glib_none(ffi::gdk_window_get_display(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_drag_protocol")]
    #[doc(alias = "get_drag_protocol")]
    pub fn drag_protocol(&self) -> (DragProtocol, Window) {
        unsafe {
            let mut target = ptr::null_mut();
            let ret = from_glib(ffi::gdk_window_get_drag_protocol(
                self.to_glib_none().0,
                &mut target,
            ));
            (ret, from_glib_full(target))
        }
    }

    #[doc(alias = "gdk_window_get_effective_parent")]
    #[doc(alias = "get_effective_parent")]
    #[must_use]
    pub fn effective_parent(&self) -> Option<Window> {
        unsafe { from_glib_none(ffi::gdk_window_get_effective_parent(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_effective_toplevel")]
    #[doc(alias = "get_effective_toplevel")]
    #[must_use]
    pub fn effective_toplevel(&self) -> Window {
        unsafe {
            from_glib_none(ffi::gdk_window_get_effective_toplevel(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_get_event_compression")]
    #[doc(alias = "get_event_compression")]
    pub fn does_event_compression(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_get_event_compression(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_events")]
    #[doc(alias = "get_events")]
    pub fn events(&self) -> EventMask {
        unsafe { from_glib(ffi::gdk_window_get_events(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_focus_on_map")]
    #[doc(alias = "get_focus_on_map")]
    pub fn gets_focus_on_map(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_get_focus_on_map(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_frame_clock")]
    #[doc(alias = "get_frame_clock")]
    pub fn frame_clock(&self) -> Option<FrameClock> {
        unsafe { from_glib_none(ffi::gdk_window_get_frame_clock(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_frame_extents")]
    #[doc(alias = "get_frame_extents")]
    pub fn frame_extents(&self) -> Rectangle {
        unsafe {
            let mut rect = Rectangle::uninitialized();
            ffi::gdk_window_get_frame_extents(self.to_glib_none().0, rect.to_glib_none_mut().0);
            rect
        }
    }

    #[doc(alias = "gdk_window_get_fullscreen_mode")]
    #[doc(alias = "get_fullscreen_mode")]
    pub fn fullscreen_mode(&self) -> FullscreenMode {
        unsafe { from_glib(ffi::gdk_window_get_fullscreen_mode(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_geometry")]
    #[doc(alias = "get_geometry")]
    pub fn geometry(&self) -> (i32, i32, i32, i32) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            let mut width = mem::MaybeUninit::uninit();
            let mut height = mem::MaybeUninit::uninit();
            ffi::gdk_window_get_geometry(
                self.to_glib_none().0,
                x.as_mut_ptr(),
                y.as_mut_ptr(),
                width.as_mut_ptr(),
                height.as_mut_ptr(),
            );
            (
                x.assume_init(),
                y.assume_init(),
                width.assume_init(),
                height.assume_init(),
            )
        }
    }

    #[doc(alias = "gdk_window_get_group")]
    #[doc(alias = "get_group")]
    #[must_use]
    pub fn group(&self) -> Option<Window> {
        unsafe { from_glib_none(ffi::gdk_window_get_group(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_height")]
    #[doc(alias = "get_height")]
    pub fn height(&self) -> i32 {
        unsafe { ffi::gdk_window_get_height(self.to_glib_none().0) }
    }

    #[doc(alias = "gdk_window_get_modal_hint")]
    #[doc(alias = "get_modal_hint")]
    pub fn is_modal_hint(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_get_modal_hint(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_origin")]
    #[doc(alias = "get_origin")]
    pub fn origin(&self) -> (i32, i32, i32) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            let ret =
                ffi::gdk_window_get_origin(self.to_glib_none().0, x.as_mut_ptr(), y.as_mut_ptr());
            (ret, x.assume_init(), y.assume_init())
        }
    }

    #[doc(alias = "gdk_window_get_parent")]
    #[doc(alias = "get_parent")]
    #[must_use]
    pub fn parent(&self) -> Option<Window> {
        unsafe { from_glib_none(ffi::gdk_window_get_parent(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_pass_through")]
    #[doc(alias = "get_pass_through")]
    pub fn is_pass_through(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_get_pass_through(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_position")]
    #[doc(alias = "get_position")]
    pub fn position(&self) -> (i32, i32) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            ffi::gdk_window_get_position(self.to_glib_none().0, x.as_mut_ptr(), y.as_mut_ptr());
            (x.assume_init(), y.assume_init())
        }
    }

    #[doc(alias = "gdk_window_get_root_coords")]
    #[doc(alias = "get_root_coords")]
    pub fn root_coords(&self, x: i32, y: i32) -> (i32, i32) {
        unsafe {
            let mut root_x = mem::MaybeUninit::uninit();
            let mut root_y = mem::MaybeUninit::uninit();
            ffi::gdk_window_get_root_coords(
                self.to_glib_none().0,
                x,
                y,
                root_x.as_mut_ptr(),
                root_y.as_mut_ptr(),
            );
            (root_x.assume_init(), root_y.assume_init())
        }
    }

    #[doc(alias = "gdk_window_get_root_origin")]
    #[doc(alias = "get_root_origin")]
    pub fn root_origin(&self) -> (i32, i32) {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            ffi::gdk_window_get_root_origin(self.to_glib_none().0, x.as_mut_ptr(), y.as_mut_ptr());
            (x.assume_init(), y.assume_init())
        }
    }

    #[doc(alias = "gdk_window_get_scale_factor")]
    #[doc(alias = "get_scale_factor")]
    pub fn scale_factor(&self) -> i32 {
        unsafe { ffi::gdk_window_get_scale_factor(self.to_glib_none().0) }
    }

    #[doc(alias = "gdk_window_get_screen")]
    #[doc(alias = "get_screen")]
    pub fn screen(&self) -> Screen {
        unsafe { from_glib_none(ffi::gdk_window_get_screen(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_source_events")]
    #[doc(alias = "get_source_events")]
    pub fn source_events(&self, source: InputSource) -> EventMask {
        unsafe {
            from_glib(ffi::gdk_window_get_source_events(
                self.to_glib_none().0,
                source.into_glib(),
            ))
        }
    }

    #[doc(alias = "gdk_window_get_state")]
    #[doc(alias = "get_state")]
    pub fn state(&self) -> WindowState {
        unsafe { from_glib(ffi::gdk_window_get_state(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_support_multidevice")]
    #[doc(alias = "get_support_multidevice")]
    pub fn supports_multidevice(&self) -> bool {
        unsafe {
            from_glib(ffi::gdk_window_get_support_multidevice(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_get_toplevel")]
    #[doc(alias = "get_toplevel")]
    #[must_use]
    pub fn toplevel(&self) -> Window {
        unsafe { from_glib_none(ffi::gdk_window_get_toplevel(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_type_hint")]
    #[doc(alias = "get_type_hint")]
    pub fn type_hint(&self) -> WindowTypeHint {
        unsafe { from_glib(ffi::gdk_window_get_type_hint(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_update_area")]
    #[doc(alias = "get_update_area")]
    pub fn update_area(&self) -> Option<cairo::Region> {
        unsafe { from_glib_full(ffi::gdk_window_get_update_area(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_visible_region")]
    #[doc(alias = "get_visible_region")]
    pub fn visible_region(&self) -> Option<cairo::Region> {
        unsafe { from_glib_full(ffi::gdk_window_get_visible_region(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_visual")]
    #[doc(alias = "get_visual")]
    pub fn visual(&self) -> Visual {
        unsafe { from_glib_none(ffi::gdk_window_get_visual(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_get_width")]
    #[doc(alias = "get_width")]
    pub fn width(&self) -> i32 {
        unsafe { ffi::gdk_window_get_width(self.to_glib_none().0) }
    }

    #[doc(alias = "gdk_window_get_window_type")]
    #[doc(alias = "get_window_type")]
    pub fn window_type(&self) -> WindowType {
        unsafe { from_glib(ffi::gdk_window_get_window_type(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_has_native")]
    pub fn has_native(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_has_native(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_hide")]
    pub fn hide(&self) {
        unsafe {
            ffi::gdk_window_hide(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_iconify")]
    pub fn iconify(&self) {
        unsafe {
            ffi::gdk_window_iconify(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_input_shape_combine_region")]
    pub fn input_shape_combine_region(
        &self,
        shape_region: &cairo::Region,
        offset_x: i32,
        offset_y: i32,
    ) {
        unsafe {
            ffi::gdk_window_input_shape_combine_region(
                self.to_glib_none().0,
                shape_region.to_glib_none().0,
                offset_x,
                offset_y,
            );
        }
    }

    #[doc(alias = "gdk_window_invalidate_maybe_recurse")]
    pub fn invalidate_maybe_recurse(
        &self,
        region: &cairo::Region,
        child_func: Option<&mut dyn (FnMut(&Window) -> bool)>,
    ) {
        let child_func_data: Option<&mut dyn (FnMut(&Window) -> bool)> = child_func;
        unsafe extern "C" fn child_func_func(
            window: *mut ffi::GdkWindow,
            user_data: glib::ffi::gpointer,
        ) -> glib::ffi::gboolean {
            let window = from_glib_borrow(window);
            let callback: *mut Option<&mut dyn (FnMut(&Window) -> bool)> =
                user_data as *const _ as usize as *mut Option<&mut dyn (FnMut(&Window) -> bool)>;
            if let Some(ref mut callback) = *callback {
                callback(&window)
            } else {
                panic!("cannot get closure...")
            }
            .into_glib()
        }
        let child_func = if child_func_data.is_some() {
            Some(child_func_func as _)
        } else {
            None
        };
        let super_callback0: &Option<&mut dyn (FnMut(&Window) -> bool)> = &child_func_data;
        unsafe {
            ffi::gdk_window_invalidate_maybe_recurse(
                self.to_glib_none().0,
                region.to_glib_none().0,
                child_func,
                super_callback0 as *const _ as usize as *mut _,
            );
        }
    }

    #[doc(alias = "gdk_window_invalidate_rect")]
    pub fn invalidate_rect(&self, rect: Option<&Rectangle>, invalidate_children: bool) {
        unsafe {
            ffi::gdk_window_invalidate_rect(
                self.to_glib_none().0,
                rect.to_glib_none().0,
                invalidate_children.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_invalidate_region")]
    pub fn invalidate_region(&self, region: &cairo::Region, invalidate_children: bool) {
        unsafe {
            ffi::gdk_window_invalidate_region(
                self.to_glib_none().0,
                region.to_glib_none().0,
                invalidate_children.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_is_destroyed")]
    pub fn is_destroyed(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_is_destroyed(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_is_input_only")]
    pub fn is_input_only(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_is_input_only(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_is_shaped")]
    pub fn is_shaped(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_is_shaped(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_is_viewable")]
    pub fn is_viewable(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_is_viewable(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_is_visible")]
    pub fn is_visible(&self) -> bool {
        unsafe { from_glib(ffi::gdk_window_is_visible(self.to_glib_none().0)) }
    }

    #[doc(alias = "gdk_window_lower")]
    pub fn lower(&self) {
        unsafe {
            ffi::gdk_window_lower(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_mark_paint_from_clip")]
    pub fn mark_paint_from_clip(&self, cr: &cairo::Context) {
        unsafe {
            ffi::gdk_window_mark_paint_from_clip(
                self.to_glib_none().0,
                mut_override(cr.to_glib_none().0),
            );
        }
    }

    #[doc(alias = "gdk_window_maximize")]
    pub fn maximize(&self) {
        unsafe {
            ffi::gdk_window_maximize(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_merge_child_input_shapes")]
    pub fn merge_child_input_shapes(&self) {
        unsafe {
            ffi::gdk_window_merge_child_input_shapes(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_merge_child_shapes")]
    pub fn merge_child_shapes(&self) {
        unsafe {
            ffi::gdk_window_merge_child_shapes(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_move")]
    #[doc(alias = "move")]
    pub fn move_(&self, x: i32, y: i32) {
        unsafe {
            ffi::gdk_window_move(self.to_glib_none().0, x, y);
        }
    }

    #[doc(alias = "gdk_window_move_region")]
    pub fn move_region(&self, region: &cairo::Region, dx: i32, dy: i32) {
        unsafe {
            ffi::gdk_window_move_region(self.to_glib_none().0, region.to_glib_none().0, dx, dy);
        }
    }

    #[doc(alias = "gdk_window_move_resize")]
    pub fn move_resize(&self, x: i32, y: i32, width: i32, height: i32) {
        unsafe {
            ffi::gdk_window_move_resize(self.to_glib_none().0, x, y, width, height);
        }
    }

    #[cfg(feature = "v3_24")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v3_24")))]
    #[doc(alias = "gdk_window_move_to_rect")]
    pub fn move_to_rect(
        &self,
        rect: &Rectangle,
        rect_anchor: Gravity,
        window_anchor: Gravity,
        anchor_hints: AnchorHints,
        rect_anchor_dx: i32,
        rect_anchor_dy: i32,
    ) {
        unsafe {
            ffi::gdk_window_move_to_rect(
                self.to_glib_none().0,
                rect.to_glib_none().0,
                rect_anchor.into_glib(),
                window_anchor.into_glib(),
                anchor_hints.into_glib(),
                rect_anchor_dx,
                rect_anchor_dy,
            );
        }
    }

    #[doc(alias = "gdk_window_peek_children")]
    pub fn peek_children(&self) -> Vec<Window> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gdk_window_peek_children(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_raise")]
    pub fn raise(&self) {
        unsafe {
            ffi::gdk_window_raise(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_register_dnd")]
    pub fn register_dnd(&self) {
        unsafe {
            ffi::gdk_window_register_dnd(self.to_glib_none().0);
        }
    }

    //#[doc(alias = "gdk_window_remove_filter")]
    //pub fn remove_filter(&self, function: /*Unimplemented*/Fn(/*Unimplemented*/XEvent, &Event) -> /*Ignored*/FilterReturn, data: /*Unimplemented*/Option<Basic: Pointer>) {
    //    unsafe { TODO: call ffi:gdk_window_remove_filter() }
    //}

    #[doc(alias = "gdk_window_reparent")]
    pub fn reparent(&self, new_parent: &Window, x: i32, y: i32) {
        unsafe {
            ffi::gdk_window_reparent(self.to_glib_none().0, new_parent.to_glib_none().0, x, y);
        }
    }

    #[doc(alias = "gdk_window_resize")]
    pub fn resize(&self, width: i32, height: i32) {
        unsafe {
            ffi::gdk_window_resize(self.to_glib_none().0, width, height);
        }
    }

    #[doc(alias = "gdk_window_restack")]
    pub fn restack(&self, sibling: Option<&Window>, above: bool) {
        unsafe {
            ffi::gdk_window_restack(
                self.to_glib_none().0,
                sibling.to_glib_none().0,
                above.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_scroll")]
    pub fn scroll(&self, dx: i32, dy: i32) {
        unsafe {
            ffi::gdk_window_scroll(self.to_glib_none().0, dx, dy);
        }
    }

    #[doc(alias = "gdk_window_set_accept_focus")]
    pub fn set_accept_focus(&self, accept_focus: bool) {
        unsafe {
            ffi::gdk_window_set_accept_focus(self.to_glib_none().0, accept_focus.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_child_input_shapes")]
    pub fn set_child_input_shapes(&self) {
        unsafe {
            ffi::gdk_window_set_child_input_shapes(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_child_shapes")]
    pub fn set_child_shapes(&self) {
        unsafe {
            ffi::gdk_window_set_child_shapes(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_cursor")]
    pub fn set_cursor(&self, cursor: Option<&Cursor>) {
        unsafe {
            ffi::gdk_window_set_cursor(self.to_glib_none().0, cursor.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_decorations")]
    pub fn set_decorations(&self, decorations: WMDecoration) {
        unsafe {
            ffi::gdk_window_set_decorations(self.to_glib_none().0, decorations.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_device_cursor")]
    pub fn set_device_cursor(&self, device: &impl IsA<Device>, cursor: &Cursor) {
        unsafe {
            ffi::gdk_window_set_device_cursor(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
                cursor.to_glib_none().0,
            );
        }
    }

    #[doc(alias = "gdk_window_set_device_events")]
    pub fn set_device_events(&self, device: &impl IsA<Device>, event_mask: EventMask) {
        unsafe {
            ffi::gdk_window_set_device_events(
                self.to_glib_none().0,
                device.as_ref().to_glib_none().0,
                event_mask.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_set_event_compression")]
    pub fn set_event_compression(&self, event_compression: bool) {
        unsafe {
            ffi::gdk_window_set_event_compression(
                self.to_glib_none().0,
                event_compression.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_set_events")]
    pub fn set_events(&self, event_mask: EventMask) {
        unsafe {
            ffi::gdk_window_set_events(self.to_glib_none().0, event_mask.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_focus_on_map")]
    pub fn set_focus_on_map(&self, focus_on_map: bool) {
        unsafe {
            ffi::gdk_window_set_focus_on_map(self.to_glib_none().0, focus_on_map.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_fullscreen_mode")]
    pub fn set_fullscreen_mode(&self, mode: FullscreenMode) {
        unsafe {
            ffi::gdk_window_set_fullscreen_mode(self.to_glib_none().0, mode.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_functions")]
    pub fn set_functions(&self, functions: WMFunction) {
        unsafe {
            ffi::gdk_window_set_functions(self.to_glib_none().0, functions.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_geometry_hints")]
    pub fn set_geometry_hints(&self, geometry: &Geometry, geom_mask: WindowHints) {
        unsafe {
            ffi::gdk_window_set_geometry_hints(
                self.to_glib_none().0,
                geometry.to_glib_none().0,
                geom_mask.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_set_group")]
    pub fn set_group(&self, leader: Option<&Window>) {
        unsafe {
            ffi::gdk_window_set_group(self.to_glib_none().0, leader.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_icon_list")]
    pub fn set_icon_list(&self, pixbufs: &[gdk_pixbuf::Pixbuf]) {
        unsafe {
            ffi::gdk_window_set_icon_list(self.to_glib_none().0, pixbufs.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_icon_name")]
    pub fn set_icon_name(&self, name: Option<&str>) {
        unsafe {
            ffi::gdk_window_set_icon_name(self.to_glib_none().0, name.to_glib_none().0);
        }
    }

    //#[doc(alias = "gdk_window_set_invalidate_handler")]
    //pub fn set_invalidate_handler<P: Fn(&Window) + 'static>(&self, handler: P) {
    //    unsafe { TODO: call ffi:gdk_window_set_invalidate_handler() }
    //}

    #[doc(alias = "gdk_window_set_keep_above")]
    pub fn set_keep_above(&self, setting: bool) {
        unsafe {
            ffi::gdk_window_set_keep_above(self.to_glib_none().0, setting.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_keep_below")]
    pub fn set_keep_below(&self, setting: bool) {
        unsafe {
            ffi::gdk_window_set_keep_below(self.to_glib_none().0, setting.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_modal_hint")]
    pub fn set_modal_hint(&self, modal: bool) {
        unsafe {
            ffi::gdk_window_set_modal_hint(self.to_glib_none().0, modal.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_opacity")]
    pub fn set_opacity(&self, opacity: f64) {
        unsafe {
            ffi::gdk_window_set_opacity(self.to_glib_none().0, opacity);
        }
    }

    #[doc(alias = "gdk_window_set_opaque_region")]
    pub fn set_opaque_region(&self, region: Option<&cairo::Region>) {
        unsafe {
            ffi::gdk_window_set_opaque_region(
                self.to_glib_none().0,
                mut_override(region.to_glib_none().0),
            );
        }
    }

    #[doc(alias = "gdk_window_set_override_redirect")]
    pub fn set_override_redirect(&self, override_redirect: bool) {
        unsafe {
            ffi::gdk_window_set_override_redirect(
                self.to_glib_none().0,
                override_redirect.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_set_pass_through")]
    pub fn set_pass_through(&self, pass_through: bool) {
        unsafe {
            ffi::gdk_window_set_pass_through(self.to_glib_none().0, pass_through.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_role")]
    pub fn set_role(&self, role: &str) {
        unsafe {
            ffi::gdk_window_set_role(self.to_glib_none().0, role.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_shadow_width")]
    pub fn set_shadow_width(&self, left: i32, right: i32, top: i32, bottom: i32) {
        unsafe {
            ffi::gdk_window_set_shadow_width(self.to_glib_none().0, left, right, top, bottom);
        }
    }

    #[doc(alias = "gdk_window_set_skip_pager_hint")]
    pub fn set_skip_pager_hint(&self, skips_pager: bool) {
        unsafe {
            ffi::gdk_window_set_skip_pager_hint(self.to_glib_none().0, skips_pager.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_skip_taskbar_hint")]
    pub fn set_skip_taskbar_hint(&self, skips_taskbar: bool) {
        unsafe {
            ffi::gdk_window_set_skip_taskbar_hint(self.to_glib_none().0, skips_taskbar.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_source_events")]
    pub fn set_source_events(&self, source: InputSource, event_mask: EventMask) {
        unsafe {
            ffi::gdk_window_set_source_events(
                self.to_glib_none().0,
                source.into_glib(),
                event_mask.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_set_startup_id")]
    pub fn set_startup_id(&self, startup_id: &str) {
        unsafe {
            ffi::gdk_window_set_startup_id(self.to_glib_none().0, startup_id.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_support_multidevice")]
    pub fn set_support_multidevice(&self, support_multidevice: bool) {
        unsafe {
            ffi::gdk_window_set_support_multidevice(
                self.to_glib_none().0,
                support_multidevice.into_glib(),
            );
        }
    }

    #[doc(alias = "gdk_window_set_title")]
    pub fn set_title(&self, title: &str) {
        unsafe {
            ffi::gdk_window_set_title(self.to_glib_none().0, title.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_transient_for")]
    pub fn set_transient_for(&self, parent: &Window) {
        unsafe {
            ffi::gdk_window_set_transient_for(self.to_glib_none().0, parent.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_set_type_hint")]
    pub fn set_type_hint(&self, hint: WindowTypeHint) {
        unsafe {
            ffi::gdk_window_set_type_hint(self.to_glib_none().0, hint.into_glib());
        }
    }

    #[doc(alias = "gdk_window_set_urgency_hint")]
    pub fn set_urgency_hint(&self, urgent: bool) {
        unsafe {
            ffi::gdk_window_set_urgency_hint(self.to_glib_none().0, urgent.into_glib());
        }
    }

    #[doc(alias = "gdk_window_shape_combine_region")]
    pub fn shape_combine_region(
        &self,
        shape_region: Option<&cairo::Region>,
        offset_x: i32,
        offset_y: i32,
    ) {
        unsafe {
            ffi::gdk_window_shape_combine_region(
                self.to_glib_none().0,
                shape_region.to_glib_none().0,
                offset_x,
                offset_y,
            );
        }
    }

    #[doc(alias = "gdk_window_show")]
    pub fn show(&self) {
        unsafe {
            ffi::gdk_window_show(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_show_unraised")]
    pub fn show_unraised(&self) {
        unsafe {
            ffi::gdk_window_show_unraised(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_show_window_menu")]
    pub fn show_window_menu(&self, event: &mut Event) -> bool {
        unsafe {
            from_glib(ffi::gdk_window_show_window_menu(
                self.to_glib_none().0,
                event.to_glib_none_mut().0,
            ))
        }
    }

    #[doc(alias = "gdk_window_stick")]
    pub fn stick(&self) {
        unsafe {
            ffi::gdk_window_stick(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_thaw_updates")]
    pub fn thaw_updates(&self) {
        unsafe {
            ffi::gdk_window_thaw_updates(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_unfullscreen")]
    pub fn unfullscreen(&self) {
        unsafe {
            ffi::gdk_window_unfullscreen(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_unmaximize")]
    pub fn unmaximize(&self) {
        unsafe {
            ffi::gdk_window_unmaximize(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_unstick")]
    pub fn unstick(&self) {
        unsafe {
            ffi::gdk_window_unstick(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_withdraw")]
    pub fn withdraw(&self) {
        unsafe {
            ffi::gdk_window_withdraw(self.to_glib_none().0);
        }
    }

    #[doc(alias = "gdk_window_constrain_size")]
    pub fn constrain_size(
        geometry: &mut Geometry,
        flags: WindowHints,
        width: i32,
        height: i32,
    ) -> (i32, i32) {
        assert_initialized_main_thread!();
        unsafe {
            let mut new_width = mem::MaybeUninit::uninit();
            let mut new_height = mem::MaybeUninit::uninit();
            ffi::gdk_window_constrain_size(
                geometry.to_glib_none_mut().0,
                flags.into_glib(),
                width,
                height,
                new_width.as_mut_ptr(),
                new_height.as_mut_ptr(),
            );
            (new_width.assume_init(), new_height.assume_init())
        }
    }

    #[doc(alias = "create-surface")]
    pub fn connect_create_surface<F: Fn(&Self, i32, i32) -> cairo::Surface + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn create_surface_trampoline<
            F: Fn(&Window, i32, i32) -> cairo::Surface + 'static,
        >(
            this: *mut ffi::GdkWindow,
            width: libc::c_int,
            height: libc::c_int,
            f: glib::ffi::gpointer,
        ) -> *mut cairo::ffi::cairo_surface_t {
            let f: &F = &*(f as *const F);
            f(&from_glib_borrow(this), width, height).to_glib_full()
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"create-surface\0".as_ptr() as *const _,
                Some(transmute::<_, unsafe extern "C" fn()>(
                    create_surface_trampoline::<F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    //#[doc(alias = "from-embedder")]
    //pub fn connect_from_embedder<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
    //    Out offscreen_x: *.Double
    //    Out offscreen_y: *.Double
    //}

    //#[doc(alias = "moved-to-rect")]
    //pub fn connect_moved_to_rect<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
    //    Unimplemented flipped_rect: *.Pointer
    //    Unimplemented final_rect: *.Pointer
    //}

    #[doc(alias = "pick-embedded-child")]
    pub fn connect_pick_embedded_child<F: Fn(&Self, f64, f64) -> Option<Window> + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn pick_embedded_child_trampoline<
            F: Fn(&Window, f64, f64) -> Option<Window> + 'static,
        >(
            this: *mut ffi::GdkWindow,
            x: libc::c_double,
            y: libc::c_double,
            f: glib::ffi::gpointer,
        ) -> *mut ffi::GdkWindow {
            let f: &F = &*(f as *const F);
            f(&from_glib_borrow(this), x, y) /*Not checked*/
                .to_glib_none()
                .0
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"pick-embedded-child\0".as_ptr() as *const _,
                Some(transmute::<_, unsafe extern "C" fn()>(
                    pick_embedded_child_trampoline::<F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    //#[doc(alias = "to-embedder")]
    //pub fn connect_to_embedder<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
    //    Out embedder_x: *.Double
    //    Out embedder_y: *.Double
    //}

    #[doc(alias = "cursor")]
    pub fn connect_cursor_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_cursor_trampoline<F: Fn(&Window) + 'static>(
            this: *mut ffi::GdkWindow,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(&from_glib_borrow(this))
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::cursor\0".as_ptr() as *const _,
                Some(transmute::<_, unsafe extern "C" fn()>(
                    notify_cursor_trampoline::<F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl fmt::Display for Window {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Window")
    }
}
