1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// 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

use crate::Widget;
use crate::Window;
use glib::object::IsA;
use glib::translate::*;
use std::fmt;

glib::wrapper! {
    /// A [`WindowGroup`][crate::WindowGroup] restricts the effect of grabs to windows
    /// in the same group, thereby making window groups almost behave
    /// like separate applications.
    ///
    /// A window can be a member in at most one window group at a time.
    /// Windows that have not been explicitly assigned to a group are
    /// implicitly treated like windows of the default window group.
    ///
    /// GtkWindowGroup objects are referenced by each window in the group,
    /// so once you have added all windows to a GtkWindowGroup, you can drop
    /// the initial reference to the window group with `g_object_unref()`. If the
    /// windows in the window group are subsequently destroyed, then they will
    /// be removed from the window group and drop their references on the window
    /// group; when all window have been removed, the window group will be
    /// freed.
    ///
    /// # Implements
    ///
    /// [`WindowGroupExt`][trait@crate::prelude::WindowGroupExt], [`trait@glib::ObjectExt`]
    #[doc(alias = "GtkWindowGroup")]
    pub struct WindowGroup(Object<ffi::GtkWindowGroup, ffi::GtkWindowGroupClass>);

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

impl WindowGroup {
    pub const NONE: Option<&'static WindowGroup> = None;

    /// Creates a new [`WindowGroup`][crate::WindowGroup] object. Grabs added with
    /// [`WidgetExt::grab_add()`][crate::prelude::WidgetExt::grab_add()] only affect windows within the same [`WindowGroup`][crate::WindowGroup].
    ///
    /// # Returns
    ///
    /// a new [`WindowGroup`][crate::WindowGroup].
    #[doc(alias = "gtk_window_group_new")]
    pub fn new() -> WindowGroup {
        assert_initialized_main_thread!();
        unsafe { from_glib_full(ffi::gtk_window_group_new()) }
    }
}

impl Default for WindowGroup {
    fn default() -> Self {
        Self::new()
    }
}

/// Trait containing all [`struct@WindowGroup`] methods.
///
/// # Implementors
///
/// [`WindowGroup`][struct@crate::WindowGroup]
pub trait WindowGroupExt: 'static {
    /// Adds a window to a [`WindowGroup`][crate::WindowGroup].
    /// ## `window`
    /// the [`Window`][crate::Window] to add
    #[doc(alias = "gtk_window_group_add_window")]
    fn add_window(&self, window: &impl IsA<Window>);

    /// Returns the current grab widget for `device`, or [`None`] if none.
    /// ## `device`
    /// a [`gdk::Device`][crate::gdk::Device]
    ///
    /// # Returns
    ///
    /// The grab widget, or [`None`]
    #[doc(alias = "gtk_window_group_get_current_device_grab")]
    #[doc(alias = "get_current_device_grab")]
    fn current_device_grab(&self, device: &gdk::Device) -> Option<Widget>;

    /// Gets the current grab widget of the given group,
    /// see [`WidgetExt::grab_add()`][crate::prelude::WidgetExt::grab_add()].
    ///
    /// # Returns
    ///
    /// the current grab widget of the group
    #[doc(alias = "gtk_window_group_get_current_grab")]
    #[doc(alias = "get_current_grab")]
    fn current_grab(&self) -> Option<Widget>;

    /// Returns a list of the `GtkWindows` that belong to `self`.
    ///
    /// # Returns
    ///
    /// A
    ///  newly-allocated list of windows inside the group.
    #[doc(alias = "gtk_window_group_list_windows")]
    fn list_windows(&self) -> Vec<Window>;

    /// Removes a window from a [`WindowGroup`][crate::WindowGroup].
    /// ## `window`
    /// the [`Window`][crate::Window] to remove
    #[doc(alias = "gtk_window_group_remove_window")]
    fn remove_window(&self, window: &impl IsA<Window>);
}

impl<O: IsA<WindowGroup>> WindowGroupExt for O {
    fn add_window(&self, window: &impl IsA<Window>) {
        unsafe {
            ffi::gtk_window_group_add_window(
                self.as_ref().to_glib_none().0,
                window.as_ref().to_glib_none().0,
            );
        }
    }

    fn current_device_grab(&self, device: &gdk::Device) -> Option<Widget> {
        unsafe {
            from_glib_none(ffi::gtk_window_group_get_current_device_grab(
                self.as_ref().to_glib_none().0,
                device.to_glib_none().0,
            ))
        }
    }

    fn current_grab(&self) -> Option<Widget> {
        unsafe {
            from_glib_none(ffi::gtk_window_group_get_current_grab(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn list_windows(&self) -> Vec<Window> {
        unsafe {
            FromGlibPtrContainer::from_glib_container(ffi::gtk_window_group_list_windows(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn remove_window(&self, window: &impl IsA<Window>) {
        unsafe {
            ffi::gtk_window_group_remove_window(
                self.as_ref().to_glib_none().0,
                window.as_ref().to_glib_none().0,
            );
        }
    }
}

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