Check-in [d1c87b1563]
Not logged in

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

Overview
Comment:Updated various bits of documentation (most of it concetrated in minx.core.hooks and minx.core.layman).
Timelines: family | ancestors | descendants | both | dev1.x
Files: files | file ages | folders
SHA1:d1c87b15635d15d6e2eb0e49ceb7e13b8a3ff651
User & Date: manuv 2013-08-03 00:27:16
Context
2013-08-03
00:39
Added layouts section to main API page. check-in: 2c9b74f1ab user: manuv tags: dev1.x
00:27
Updated various bits of documentation (most of it concetrated in minx.core.hooks and minx.core.layman). check-in: d1c87b1563 user: manuv tags: dev1.x
2013-08-01
19:12
  • Added some basic info about layouts to minx.core.wm doc string.
  • Updated hooks-list.wiki with info about new hooks.
  • Fixed a bug in layman.receptive_layout(): have to add layout returned by receptive_layout_hook to layouts list.
  • In layman.find(), added ability to search for layouts based on their names. (Noticed we needed this ability when writing sample code to illustrate layouts usage.)
  • Removed unnecessary warnings from minxlib::window, which were simply cluttering the log.
  • Other minor edits elsewhere.
check-in: 3740586cc4 user: manuv tags: dev1.x
Changes

Changes to core/hooks.py.

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
131
132
133
134
135
136
137


































138
139
140
141
142
143
144
...
638
639
640
641
642
643
644

645
646
647
648

        When a new hooks object is created, it will have no hook
        functions in it. Clients (i.e., other Minx classes and
        functions or end-user configuration code) will have to then add
        hook functions to the hook map.

        @note In general, there should be no need in end-user code to
        create a hooks object. Rather end-users should use the hooks
        attribute of the @ref minx.core.wm.wm "main window manager object".
        Refer to the <a href="../wiki/hooks-howto.wiki">Hooks HOWTO</a>
        for more on typical usage patterns for this class.

        """
        self._hooks = {}

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

        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.

        """
................................................................................

##############################################
# Editor config:                             #
##############################################
# Local Variables:                           #
# indent-tabs-mode: nil                      #
# py-indent-offset: 4                        #

# End:                                       #
##############################################
# vim: set expandtab shiftwidth=4 tabstop=4: #
##############################################







|







 







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







 







>




83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
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
170
171
172
173
174
175
176
177
178
...
672
673
674
675
676
677
678
679
680
681
682
683

        When a new hooks object is created, it will have no hook
        functions in it. Clients (i.e., other Minx classes and
        functions or end-user configuration code) will have to then add
        hook functions to the hook map.

        @note In general, there should be no need in end-user code to
        create a hooks object. Rather, end-users should use the hooks
        attribute of the @ref minx.core.wm.wm "main window manager object".
        Refer to the <a href="../wiki/hooks-howto.wiki">Hooks HOWTO</a>
        for more on typical usage patterns for this class.

        """
        self._hooks = {}

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

        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

        In general, you should not care about the order in which hooks
        execute. That is, you should implement hook functions so that the
        final result is the same regardless of the order of their
        execution. Having said that, however, such idealism is not always
        feasible, and, depending on the specific situation, perhaps not
        even wholly desirable. Thus, if you do need to control the order
        in which your hooks execute, you should be aware that the order
        in which you add hooks can be significant, especially if you use
        MIN_PRIORITY and MAX_PRIORITY.

        For example, let's say you have two hooks A and B for some key
        "foo" and want to execute A before B and B before every other
        hook for "foo." If you add the hooks in the following order:

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

        B will end up at a higher priority than A and will execute before
        A instead of the other way around. This is because, MIN_PRIORITY
        and MAX_PRIORITY look at the current minimum and maximum
        priorities and are not absolute values. To achieve the effect
        described above, you should first add B and then A.
        Alternatively, you could also do the following:

        @verbatim
            wm.hooks.add('foo', A, wm.hooks.MAX_PRIORITY)
            wm.hooks.add('foo', B, wm.hooks.max_priority('foo'))
        @endverbatim

        The above code will first add A at the current highest priority
        for "foo" and then add B at the same priority as A.

        @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.

        """
................................................................................

##############################################
# Editor config:                             #
##############################################
# Local Variables:                           #
# indent-tabs-mode: nil                      #
# py-indent-offset: 4                        #
# python-indent: 4                           #
# End:                                       #
##############################################
# vim: set expandtab shiftwidth=4 tabstop=4: #
##############################################

Changes to core/layman.py.

168
169
170
171
172
173
174




175










176

177
178
179
180
181
182
183
184
185
186
187
188
            @li Trigger the <tt>receptive_layout_hook</tt>.
            @li Failing that, check the focused layout.
            @li Failing that, search the remaining layouts.
            @li Failing that, create a new default layout.

        The <tt>receptive_layout_hook</tt> gives end-user code an
        opportunity to fine-tune the layout to be used for each window.















        If the above-mentioned hook is not defined or if it returns None,

        we check if the layout with the window that is currently focused
        is on the same screen as the new window and is willing to manage
        it. If so, this function will return the currently focused layout
        as the receptive layout, i.e., the layout that will manage the
        new window.

        If no window has the input focus, or if the focused layout is not
        on the same screen as the new window, or if it is unwilling to
        manage the new window, then we search the layout manager's
        remaining layouts for a layout that is on the same screen as the
        new window and is willing to manage it.








>
>
>
>

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







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
            @li Trigger the <tt>receptive_layout_hook</tt>.
            @li Failing that, check the focused layout.
            @li Failing that, search the remaining layouts.
            @li Failing that, create a new default layout.

        The <tt>receptive_layout_hook</tt> gives end-user code an
        opportunity to fine-tune the layout to be used for each window.
        If you have multiple functions for this hook, only the return
        value of the first one will be considered. That is, use only one
        hook for this; in fact, you shouldn't need an entire chain of
        hooks for the <tt>receptive_layout_hook</tt>.

        Minx will only accept the return value of the
        <tt>receptive_layout_hook</tt> if all of the following conditions
        are true:

            @li The return value is not None.
            @li It is an instance of the
                @ref minx.layout.base.base "minx.layout.base" class.
            @li The layout is on the same screen as w.
            @li The layout is willing to manage w.

        If the above-mentioned hook is not defined or if it returns
        something not fulfilling the above conditions, we check if the
        layout with the window that is currently focused is on the same
        screen as the new window and is willing to manage it. If so, this
        function will return the currently focused layout as the
        receptive layout, i.e., the layout that will manage the new
        window.

        If no window has the input focus, or if the focused layout is not
        on the same screen as the new window, or if it is unwilling to
        manage the new window, then we search the layout manager's
        remaining layouts for a layout that is on the same screen as the
        new window and is willing to manage it.

Changes to core/wm.py.

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
        #!/usr/bin/env python
        import minx
        minx.core.wm().start()
    @endverbatim

    Of course, the above code requires the minx package to be in your
    Python path. But, assuming that is the case, it would start Minx
    with the default keybindings, hooks, and other settings.

    To make simple customizations, create an instance of the
    @ref minx.core.config.config "config" class and pass that to the wm
    constructor:

    @verbatim
        #!/usr/bin/env python
................................................................................
            @li layouts

        The @ref minx.core.config.config "config" object specifies
        various settings such as the border colors, sizes, etc. To
        customize these settings, you will (typically) create a config
        object, change its various attributes, and pass that object into
        this constructor. (Alternatively, you could first create a wm
        object and then access its config attribute; however, the former
        approach is the preferred style.)

        If you don't supply a config object, the window manager will use
        default settings.

        The wm object's @ref minx.core.hooks.hooks "hooks" attribute
        maps names of hook functions (i.e., strings) to prioritized
        lists of callables. Minx will trigger these hooks at appropriate
        points in its event processing workflow. Minx uses hooks both
        internally (to handle various events) and "externally" (to allow
        end-users to customize its behaviour).







|







 







|
<
<
|
<







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
...
231
232
233
234
235
236
237
238


239

240
241
242
243
244
245
246
        #!/usr/bin/env python
        import minx
        minx.core.wm().start()
    @endverbatim

    Of course, the above code requires the minx package to be in your
    Python path. But, assuming that is the case, it would start Minx
    with the default key bindings, hooks, and other settings.

    To make simple customizations, create an instance of the
    @ref minx.core.config.config "config" class and pass that to the wm
    constructor:

    @verbatim
        #!/usr/bin/env python
................................................................................
            @li layouts

        The @ref minx.core.config.config "config" object specifies
        various settings such as the border colors, sizes, etc. To
        customize these settings, you will (typically) create a config
        object, change its various attributes, and pass that object into
        this constructor. (Alternatively, you could first create a wm
        object and then access its config attribute.) If you don't supply


        a config object, the window manager will use default settings.


        The wm object's @ref minx.core.hooks.hooks "hooks" attribute
        maps names of hook functions (i.e., strings) to prioritized
        lists of callables. Minx will trigger these hooks at appropriate
        points in its event processing workflow. Minx uses hooks both
        internally (to handle various events) and "externally" (to allow
        end-users to customize its behaviour).

Changes to layout/full.py.

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
        When you create a full layout object, you should supply the main
        window manager object so that the layout can access the X server
        connection, any config settings it needs, etc. Additionally, the
        layout needs to know its parent window.

        Since Minx layouts are X windows, this constructor will create a
        child window of the specified parent, set appropriate properties
        to mark it as a layout, set the event mask, etc., and then map
        the layout window.

        """
        base.__init__(self, wm, parent)

    # Reparent notification
    def reparented(self, w):
        """Reparent notification.







|
<







71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
        When you create a full layout object, you should supply the main
        window manager object so that the layout can access the X server
        connection, any config settings it needs, etc. Additionally, the
        layout needs to know its parent window.

        Since Minx layouts are X windows, this constructor will create a
        child window of the specified parent, set appropriate properties
        to mark it as a layout, set the event mask, etc.


        """
        base.__init__(self, wm, parent)

    # Reparent notification
    def reparented(self, w):
        """Reparent notification.

Changes to minxlib/keymap.hh.

156
157
158
159
160
161
162











163
164
165
166
167
168
169
    debugging. That is, it doesn't convey anything particularly useful
    to its caller; what we want is to see it in Minx's log so we can
    double-check using the xmodmap program that the key binding mapping
    will work correctly.
*/
uint32_t ignore_lock_modifiers(XModifierKeymap* m, Display* d) ;












void pythonize() ;

} // namespace keymap
} // namespace minxlib

//----------------------------------------------------------------------








>
>
>
>
>
>
>
>
>
>
>







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
    debugging. That is, it doesn't convey anything particularly useful
    to its caller; what we want is to see it in Minx's log so we can
    double-check using the xmodmap program that the key binding mapping
    will work correctly.
*/
uint32_t ignore_lock_modifiers(XModifierKeymap* m, Display* d) ;

/**
    @ingroup grp_minxlib_keymap
    @brief  Setup keymap module's logger.
    @return Nothing.

    The keymap module does not really have anything exposed to Minx's
    Python core via @boostpylink. However, we do use the Python-based
    logging infrastructure. That's why we need this "pythonization"
    function, which is meant to be called by the Boost.Python
    initialization code in python.cc.
*/
void pythonize() ;

} // namespace keymap
} // namespace minxlib

//----------------------------------------------------------------------

Changes to minxlib/logging.hh.

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    /**
        @brief  Create a logger object for the specified class.
        @param  name minxlib class for which we want a logger.
        @return A logger object for the specified class.

        This function returns a logger object that can be used by the
        named class to send log messages to the Minx log. It is meant to
        be called by the Pythonize functions of the minxlib::display,
        minxlib::window, minxlib::event, and minxlib::exception classes.
        The <em>.cc</em> files for these classes should define a static
        global <tt>logger</tt> object that is initialized by calling
        this function in the Pythonize function of the above-mentioned
        classes.

        See the sample code in the class description for intended usage
        pattern.
    */
    static logging get_logger(const std::string& name) ;








|
|
|
|
|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    /**
        @brief  Create a logger object for the specified class.
        @param  name minxlib class for which we want a logger.
        @return A logger object for the specified class.

        This function returns a logger object that can be used by the
        named class to send log messages to the Minx log. It is meant to
        be called by the Pythonize functions of the various minxlib
        modules that send log messages to the Minx log. The <em>.cc</em>
        files for these modules should define a static global
        <tt>logger</tt> object that is initialized by calling this
        function in the Pythonize function of the above-mentioned
        classes.

        See the sample code in the class description for intended usage
        pattern.
    */
    static logging get_logger(const std::string& name) ;