Check-in [d02dcfd679]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added support for making layouts invisible.
Timelines: family | ancestors | descendants | both | dev1.x
Files: files | file ages | folders
SHA1:d02dcfd679f05d9751b592e67f4a56147d0010cd
User & Date: manuv 2013-07-28 01:29:17
Context
2013-07-28
12:14
Fixed the sporadic recognitions of key bindings, especially the ones with modifiers. The problem turned out to be a lack of additional grabs with the various combinations of the lock modifiers; without these, the Caps Lock, Num Lock, etc. totally screw up the key binding logic because the X server doesn't even recognize them and, therefore, doesn't generate the necessary keyboard events.

Got the idea for this from a cursory perusal of the code for xbindkeys. And now (at long last) key bindings work flawlessly! Getting close to the 0.2.0 release... check-in: 17ccc163e4 user: manuv tags: dev1.x

01:29
Added support for making layouts invisible. check-in: d02dcfd679 user: manuv tags: dev1.x
2013-07-22
17:40
Added Xinerama support to minxlib::window::screen() so that it returns the screen index based on a window's location, i.e., this function now always returns the physical screen a window is on. check-in: 083960bf79 user: manuv tags: dev1.x
Changes

Changes to core/hooks.py.

68
69
70
71
72
73
74



75
76
77
78
79
80
81
...
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
...
300
301
302
303
304
305
306










307
308
309
310
311
312
313
...
363
364
365
366
367
368
369










370
371
372
373
374
375
376
    as the keys, in Minx, keys are strings that name the different hooks
    that Minx supports (e.g., 'manage_hook', 'x_create_notify', and so
    on). If you name your hooks using a non-string type, those hooks
    will be added to the map but simply be ignored.

    """




    # Constructor
    def __init__(self):
        """Create an empty hook map.

        @return An empty hook map.

        When a new hooks object is created, it will have no hook
................................................................................
        instance and we don't want duplicate entries of the same
        function in our hook map (because each hook should be called
        once and only once per triggering).

        Priorities should be integers in the range [1, 100]. Higher
        numbers will insert f into the beginning of the list. If the
        priority p is not supplied, it will be assigned a default
        priority. Passing a non-integral value or an out-of-range value
        for the parameter p will also result in the priority for f
        being set to the default priority.















        @note As mentioned earlier, although you can use any
        (reasonable) type for the hook map's keys, in Minx, we use
        strings as the keys. That is, pass a string as the first
        parameter k.

        """
        if p == None or not isinstance(p, int) or p < 1 or p > 100:
           p = self.default_priority()
        if k not in self._hooks:
           self._hooks[k] = priority_queue()
















        if self._hooks[k].add(f, p):
           logger.info('added hook: [{}, {}, {}]'.format(k, f.__name__, p))

    # Remove all hooks for specified name
    def remove(self, k):
        """Remove all hooks for specified name.

................................................................................

        The above example is contrived because if that is all your Minx
        start-up file contained, there would be no manage_hook
        installed and, so, no need to check to ensure that
        my_manage_hook() would execute first. Furthermore, usually,
        only a single manage_hook would be needed; there's no point to
        having multiple manage hooks.











        Nonetheless, the example serves to illustrate how and why you
        might want to use the hooks.max_priority() function.

        Note that if the hook map does not contain any hooks for the
        key k, this function will return a negative number.

................................................................................

        The above example is contrived because if that is all your Minx
        start-up file contained, there would be no manage_hook
        installed and, so, no need to check to ensure that
        my_manage_hook() would execute last. Furthermore, usually,
        only a single manage_hook would be needed; there's no point to
        having multiple manage hooks.











        Nonetheless, the example serves to illustrate how and why you
        might want to use the hooks.min_priority() function.

        If the hook map does not contain any hooks for the key k, this
        function will return a negative number.








>
>
>







 







|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







<
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
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
160
161
162
163
164
165
166
167
168
169
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
    as the keys, in Minx, keys are strings that name the different hooks
    that Minx supports (e.g., 'manage_hook', 'x_create_notify', and so
    on). If you name your hooks using a non-string type, those hooks
    will be added to the map but simply be ignored.

    """

    MIN_PRIORITY = 0
    MAX_PRIORITY = 101

    # Constructor
    def __init__(self):
        """Create an empty hook map.

        @return An empty hook map.

        When a new hooks object is created, it will have no hook
................................................................................
        instance and we don't want duplicate entries of the same
        function in our hook map (because each hook should be called
        once and only once per triggering).

        Priorities should be integers in the range [1, 100]. Higher
        numbers will insert f into the beginning of the list. If the
        priority p is not supplied, it will be assigned a default
        priority. Passing a non-integral value for the parameter p will
        also result in the priority for f being set to the default
        priority.

        To add a hook at the highest priority, pass MAX_PRIORITY as the
        value of p. Similarly, to add a hook at the lowest priority, pass
        MIN_PRIORITY as the value of p. Alternatively, to add hooks at
        the highest or lowest priorities, you can pass values greater
        than hundred or less than one respectively (however, using
        MAX_PRIORITY and MIN_PRIORITY is probably clearer).

        Here is a snippet of code illustrating how to add a hook for some
        event 'foo' so that it is the highest priority hook:

        @verbatim
            wm.hooks.add('foo', my_foo_hook, wm.hooks.MAX_PRIORITY)
        @endverbatim

        @note As mentioned earlier, although you can use any
        (reasonable) type for the hook map's keys, in Minx, we use
        strings as the keys. That is, pass a string as the first
        parameter k.

        """


        if k not in self._hooks:
           self._hooks[k] = priority_queue()

        if p == None or not isinstance(p, int):
           p = self.default_priority()
        elif p < 1:
           p = self.min_priority(k)
           if p == -1:
              p = self.default_priority() - 1
           else:
              p = max(1, p - 1)
        elif p > 100:
           p = self.max_priority(k)
           if p == -1:
              p = self.default_priority() + 1
           else:
              p = min(p + 1, 100)

        if self._hooks[k].add(f, p):
           logger.info('added hook: [{}, {}, {}]'.format(k, f.__name__, p))

    # Remove all hooks for specified name
    def remove(self, k):
        """Remove all hooks for specified name.

................................................................................

        The above example is contrived because if that is all your Minx
        start-up file contained, there would be no manage_hook
        installed and, so, no need to check to ensure that
        my_manage_hook() would execute first. Furthermore, usually,
        only a single manage_hook would be needed; there's no point to
        having multiple manage hooks.

        Moreover, to add a hook at the highest priority, you can simply
        pass MAX_PRIORITY to the call to hooks.add() instead of going
        about it yourself. For example, to add the highest priority hook
        for some event 'foo', you could just call the hooks.add() method
        as shown below:

        @verbatim
            wm.hooks.add('foo', my_foo_hook, wm.hooks.MAX_PRIORITY)
        @endverbatim

        Nonetheless, the example serves to illustrate how and why you
        might want to use the hooks.max_priority() function.

        Note that if the hook map does not contain any hooks for the
        key k, this function will return a negative number.

................................................................................

        The above example is contrived because if that is all your Minx
        start-up file contained, there would be no manage_hook
        installed and, so, no need to check to ensure that
        my_manage_hook() would execute last. Furthermore, usually,
        only a single manage_hook would be needed; there's no point to
        having multiple manage hooks.

        Moreover, to add a hook at the lowest priority, you can simply
        pass MIN_PRIORITY to the call to hooks.add() instead of going
        about it yourself. For example, to add the lowest priority hook
        for some event 'foo', you could just call the hooks.add() method
        as shown below:

        @verbatim
            wm.hooks.add('foo', my_foo_hook, wm.hooks.MIN_PRIORITY)
        @endverbatim

        Nonetheless, the example serves to illustrate how and why you
        might want to use the hooks.min_priority() function.

        If the hook map does not contain any hooks for the key k, this
        function will return a negative number.

Changes to layout/base.py.

38
39
40
41
42
43
44

45
46
47
48
49






























































50
51
52
53
54
55
56
..
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

#------------------------------- IMPORTS --------------------------------

# Standard library
import logging

# Minx

from minx.core import minxlib

#-------------------------- MODULE LOGGER ------------------------------

logger = logging.getLogger(__name__)































































#-------------------------------- CLASS ---------------------------------

class base:
    """A base class for Minx layouts.

    This class implements a base class from which all Minx layout classes
................................................................................
        properties on the newly created window and then maps it on screen.

        @note As mentioned earlier, this class is not meant to be
        instantiated directly. Thus, this constructor must only be called
        by subclasses.

        """






        x, y, w, h = p.geometry()[:4] # don't need border width
        if r != None: # use supplied rectangle instead of entire parent window
           x, y, w, h = r

        self.window = m._display.create_window(p, x, y, w, h)

        name = 'minx.layout.{}.{}'.format(self.__class__.__name__,
                                          self.window.id)
        self.window.set_properties({'class': 'minx.layout', 'name' : name})
        self.window.select_events(minxlib.substructure_redirect_mask |
                                  minxlib.substructure_notify_mask)
        self.window.show()

    # Convert layout to string
    def __str__(self):
        """Return layout's name.

        This method will convert the layout object to a human-readable
        string representation (which is useful for debugging as well as







>


|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>











<







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
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183

#------------------------------- IMPORTS --------------------------------

# Standard library
import logging

# Minx
import minx.core.layman
from minx.core import minxlib

#---------------------------- MODULE LOGGER -----------------------------

logger = logging.getLogger(__name__)

#--------------------------- EVENT HANDLERS -----------------------------

# Since layouts use X windows to manage their windows, the layout window
# itself will be visible when a layout has no windows to manage. We don't
# want that; we want layouts to be invisible. To effect that
# invisibility, we map the layout's window when a window is added to the
# layout and unmap it when it no longer has any visible windows.
#
# The following event handlers take care of the above-mentioned strategy
# for keeping layouts invisible.
#
# NOTE: Rather than rely on the event dispatching implemented in xevents,
# we add our own hooks for the relevant X events because we don't want
# layout subclasses to be able to override this mechanism nor require
# them to have to call base class methods in order to ensure correct
# operation of things such as layout invisibility.

# Need the layout manager maintained by the main window manager object so
# that we can find the layouts for different windows.
_layouts = None

# When a window is reparented, show its layout if the layout isn't
# already visible.
def _on_reparent(e):
    try:
        logger.debug('window {} reparented by {}'.
                     format(e.target.id, e.new_parent.id))

        layout = _layouts.find(e.new_parent)
        logger.debug('window {} being managed by layout {}'.
                     format(e.target.id, layout))

        if not layout.window.is_mapped():
           logger.debug('showing layout {}'.format(layout))
           layout.window.show()

    except minx.core.layman.unknown_layout:
        pass

# When a window is unmapped, also unmap its layout if the layout has no
# more visible windows.
def _on_unmap(e):
    try:
        logger.debug('window {} unmapped'.format(e.target.id))

        layout = _layouts.find(e.parent)
        logger.debug('window {} being managed by layout {}'.
                     format(e.target.id, layout))

        for w in layout.window.children():
            if w.is_mapped():
               logger.debug('layout {} has visible child {}; no need to hide'.
                            format(layout, w.id))
               return

        logger.debug('hiding layout {} because it has no visible children'.
                     format(layout))
        layout.window.hide()

    except minx.core.layman.unknown_layout:
        pass

#-------------------------------- CLASS ---------------------------------

class base:
    """A base class for Minx layouts.

    This class implements a base class from which all Minx layout classes
................................................................................
        properties on the newly created window and then maps it on screen.

        @note As mentioned earlier, this class is not meant to be
        instantiated directly. Thus, this constructor must only be called
        by subclasses.

        """
        global _layouts
        if _layouts == None:
           _layouts = m.layouts
           m.hooks.add('x_reparent_notify', _on_reparent, m.hooks.MAX_PRIORITY)
           m.hooks.add(   'x_unmap_notify', _on_unmap,    m.hooks.MAX_PRIORITY)

        x, y, w, h = p.geometry()[:4] # don't need border width
        if r != None: # use supplied rectangle instead of entire parent window
           x, y, w, h = r

        self.window = m._display.create_window(p, x, y, w, h)

        name = 'minx.layout.{}.{}'.format(self.__class__.__name__,
                                          self.window.id)
        self.window.set_properties({'class': 'minx.layout', 'name' : name})
        self.window.select_events(minxlib.substructure_redirect_mask |
                                  minxlib.substructure_notify_mask)


    # Convert layout to string
    def __str__(self):
        """Return layout's name.

        This method will convert the layout object to a human-readable
        string representation (which is useful for debugging as well as

Changes to minxlib/root_window.cc.

119
120
121
122
123
124
125






126
127
128
129
130
131
132
...
184
185
186
187
188
189
190

191
192
193
194
195
196
197
//----------------------- WINDOW VISIBILITY ----------------------------

void root_window::show()
{
    logger.warning() << "attempting to show screen " << m_screen
                     << "'s root window " << m_id ;
}







bool root_window::is_mapped()
{
    return true ;
}

//------------------------ WINDOW GEOMETRY -----------------------------
................................................................................
{
    py::class_<root_window, py::bases<window> >("root_window", py::no_init).
        def("set_properties",   &root_window::set_properties ).
        def("reparent",         &root_window::reparent       ).
        def("parent",           &root_window::parent         ).
        def("screen",           &root_window::screen         ).
        def("show",             &root_window::show           ).

        def("is_mapped",        &root_window::is_mapped      ).
        def("move_resize",      &root_window::move_resize    ).
        def("configure",        &root_window::configure      ).
        def("set_border_attr",  &root_window::set_border_attr).
        def("geometry",         &root_window::geometry       ).
        def("focus",            &root_window::focus          ).
        def("kill",             &root_window::kill           ).







>
>
>
>
>
>







 







>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
//----------------------- WINDOW VISIBILITY ----------------------------

void root_window::show()
{
    logger.warning() << "attempting to show screen " << m_screen
                     << "'s root window " << m_id ;
}

void root_window::hide()
{
    logger.warning() << "attempting to hide screen " << m_screen
                     << "'s root window " << m_id ;
}

bool root_window::is_mapped()
{
    return true ;
}

//------------------------ WINDOW GEOMETRY -----------------------------
................................................................................
{
    py::class_<root_window, py::bases<window> >("root_window", py::no_init).
        def("set_properties",   &root_window::set_properties ).
        def("reparent",         &root_window::reparent       ).
        def("parent",           &root_window::parent         ).
        def("screen",           &root_window::screen         ).
        def("show",             &root_window::show           ).
        def("hide",             &root_window::hide           ).
        def("is_mapped",        &root_window::is_mapped      ).
        def("move_resize",      &root_window::move_resize    ).
        def("configure",        &root_window::configure      ).
        def("set_border_attr",  &root_window::set_border_attr).
        def("geometry",         &root_window::geometry       ).
        def("focus",            &root_window::focus          ).
        def("kill",             &root_window::kill           ).

Changes to minxlib/root_window.hh.

157
158
159
160
161
162
163




164
165
166










167
168
169
170
171
172
173
        window object was created.
    */
    int screen() ;

    /**
        @brief  Show the window, i.e., map it.
        @return Nothing.




    */
    void show() ;











    /**
        @brief  Check if root window is currently mapped or not.
        @return True (root windows are always mapped).
    */
    bool is_mapped() ;

    /**







>
>
>
>



>
>
>
>
>
>
>
>
>
>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
        window object was created.
    */
    int screen() ;

    /**
        @brief  Show the window, i.e., map it.
        @return Nothing.

        This is an override of minxlib::window::show(). Since root
        windows are always visible, this function simply logs a warning
        to the Minx log.
    */
    void show() ;

    /**
        @brief  Hide this window, i.e., unmap it.
        @return Nothing.

        This is an override of minxlib::window::hide(). Since root
        windows are always visible and cannot be unmapped, this function
        simply logs a warning to the Minx log.
    */
    void hide() ;

    /**
        @brief  Check if root window is currently mapped or not.
        @return True (root windows are always mapped).
    */
    bool is_mapped() ;

    /**

Changes to minxlib/window.cc.

198
199
200
201
202
203
204



























205
206
207
208
209
210
211
...
333
334
335
336
337
338
339






340
341
342
343
344
345
346
...
497
498
499
500
501
502
503

504
505
506
507

508
509
510
511
512
513
514
        logger.error() << "unable to query tree for window " << m_id ;
        return window(m_display, 0) ; // throw exception instead?
    }

    logger.debug() << "window " << m_id << "'s parent = " << parent_id ;
    return window(m_display, parent_id) ;
}




























int window::screen()
{
    XWindowAttributes attr ;
    Status s = XGetWindowAttributes(m_display, m_id, &attr) ;
    if (!s) {
        logger.error() << "unable to get screen index for window " << m_id ;
................................................................................
//----------------------- WINDOW VISIBILITY ----------------------------

void window::show()
{
    logger.debug() << "mapping window " << m_id ;
    XMapWindow(m_display, m_id) ;
}







bool window::is_mapped()
{
    XWindowAttributes attr ;
    Status s = XGetWindowAttributes(m_display, m_id, &attr) ;
    if (!s) {
        logger.error() << "unable to check map state for window " << m_id ;
................................................................................
        def(py::self == py::other<Window>()  ).
        def(py::self != py::other<Window>()  ).
        def_readonly("id",      &window::m_id).
        def("properties",       &window::properties     ).
        def("set_properties",   &window::set_properties ).
        def("reparent",         &window::reparent       ).
        def("parent",           &window::parent         ).

        def("screen",           &window::screen         ).
        def("select_events",    &window::select_events  ).
        def("grab_key",         &window::grab_key       ).
        def("show",             &window::show           ).

        def("is_mapped",        &window::is_mapped      ).
        def("move_resize",      &window::move_resize    ).
        def("configure",        &window::configure      ).
        def("set_border_attr",  &window::set_border_attr).
        def("geometry",         &window::geometry       ).
        def("focus",            &window::focus          ).
        def("kill",             &window::kill           ).







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







 







>




>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
        logger.error() << "unable to query tree for window " << m_id ;
        return window(m_display, 0) ; // throw exception instead?
    }

    logger.debug() << "window " << m_id << "'s parent = " << parent_id ;
    return window(m_display, parent_id) ;
}

std::vector<window> window::children()
{
    logger.debug() << "getting " << m_id << "'s children" ;

    std::vector<window> windows ;

    Window  root, parent ;
    Window* children = 0 ;
    unsigned int num_children ;
    Status s = XQueryTree(m_display, m_id,
                          &root, &parent, &children, &num_children) ;
    if (s) {
        if (children) {
            windows.reserve(num_children) ;
            for (unsigned int i = 0; i < num_children; ++i)
                windows.push_back(window(m_display, children[i])) ;
            XFree(children) ;
        }
    }
    else
        logger.error() << "unable to query tree for window " << m_id ;

    logger.debug() << "window " << m_id << " has " << windows.size()
                   << " children" ;
    return windows ;
}

int window::screen()
{
    XWindowAttributes attr ;
    Status s = XGetWindowAttributes(m_display, m_id, &attr) ;
    if (!s) {
        logger.error() << "unable to get screen index for window " << m_id ;
................................................................................
//----------------------- WINDOW VISIBILITY ----------------------------

void window::show()
{
    logger.debug() << "mapping window " << m_id ;
    XMapWindow(m_display, m_id) ;
}

void window::hide()
{
    logger.debug() << "unmapping window " << m_id ;
    XUnmapWindow(m_display, m_id) ;
}

bool window::is_mapped()
{
    XWindowAttributes attr ;
    Status s = XGetWindowAttributes(m_display, m_id, &attr) ;
    if (!s) {
        logger.error() << "unable to check map state for window " << m_id ;
................................................................................
        def(py::self == py::other<Window>()  ).
        def(py::self != py::other<Window>()  ).
        def_readonly("id",      &window::m_id).
        def("properties",       &window::properties     ).
        def("set_properties",   &window::set_properties ).
        def("reparent",         &window::reparent       ).
        def("parent",           &window::parent         ).
        def("children",         &window::children       ).
        def("screen",           &window::screen         ).
        def("select_events",    &window::select_events  ).
        def("grab_key",         &window::grab_key       ).
        def("show",             &window::show           ).
        def("hide",             &window::hide           ).
        def("is_mapped",        &window::is_mapped      ).
        def("move_resize",      &window::move_resize    ).
        def("configure",        &window::configure      ).
        def("set_border_attr",  &window::set_border_attr).
        def("geometry",         &window::geometry       ).
        def("focus",            &window::focus          ).
        def("kill",             &window::kill           ).

Changes to minxlib/window.hh.

219
220
221
222
223
224
225











226
227
228
229
230
231
232
...
391
392
393
394
395
396
397






398
399
400
401
402
403
404
        XQueryTree() fails, this function will return a window object
        with the id member set to zero. Eventually, on XQueryTree()
        failure, X will generate a protocol error; that's why we don't
        bother throwing an exception.
    */
    virtual window parent() ;












    /**
        @brief  Get screen number of this window.
        @return Window's screen number.

        This function returns the zero-based index of the physical
        screen this window is on. If Xinerama is active and this window
        overlaps two or more screens, this function will return the
................................................................................

    /**
        @brief  Show the window, i.e., map it.
        @return Nothing.
    */
    virtual void show() ;







    /**
        @brief  Check if window is currently mapped or not.
        @return True if window is mapped, false otherwise.

        This function uses XGetWindowAttributes() and checks the value
        of the XWindowAttributes's map_state field to see if the window
        is mapped or not. It'll return true if map_state equals







>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
        XQueryTree() fails, this function will return a window object
        with the id member set to zero. Eventually, on XQueryTree()
        failure, X will generate a protocol error; that's why we don't
        bother throwing an exception.
    */
    virtual window parent() ;

    /**
        @brief  Get this window's children.
        @return Window's children.

        This function uses XQueryTree() to determine the list of child
        windows of the X window encapsulated by this object. If the call
        to XQueryTree() fails, this function will return an empty list
        and, eventually, X will generate a protocol error.
    */
    std::vector<window> children() ;

    /**
        @brief  Get screen number of this window.
        @return Window's screen number.

        This function returns the zero-based index of the physical
        screen this window is on. If Xinerama is active and this window
        overlaps two or more screens, this function will return the
................................................................................

    /**
        @brief  Show the window, i.e., map it.
        @return Nothing.
    */
    virtual void show() ;

    /**
        @brief  Hide this window, i.e., unmap it.
        @return Nothing.
    */
    virtual void hide() ;

    /**
        @brief  Check if window is currently mapped or not.
        @return True if window is mapped, false otherwise.

        This function uses XGetWindowAttributes() and checks the value
        of the XWindowAttributes's map_state field to see if the window
        is mapped or not. It'll return true if map_state equals