BlackBerry Platform Support Events: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=Introduction=
[[Category:BlackBerry]]


The BlackBerry platform support library, <span class="caps">BPS</span>, provides an <span class="caps">API</span> for system events. In Qt, <span class="caps">BPS</span> events are integrated into Qt’s event loop, i.e. Qt receives and consumes <span class="caps">BPS</span> events. One example in which Qt consumes a <span class="caps">BPS</span> event is the <span class="caps">NAVIGATOR</span>_EXIT event – when receiving that event, Qt will trigger quitting the application. See [https://developer.blackberry.com/native/documentation/cascades/device_platform/bps/ Handling <span class="caps">BPS</span> events] ''[developer.blackberry.com]'' article for more details.
= Introduction =


=Receiving <span class="caps">BPS</span> events=
The BlackBerry platform support library, BPS, provides an API for system events. In Qt, BPS events are integrated into Qt's event loop, i.e. Qt receives and consumes BPS events. One example in which Qt consumes a BPS event is the NAVIGATOR_EXIT event - when receiving that event, Qt will trigger quitting the application. See &quot;Handling BPS events&amp;quot;:https://developer.blackberry.com/native/documentation/cascades/device_platform/bps/ article for more details.


Since <span class="caps">BPS</span> events are integrated into Qt’s event loop, how is it possible as a user to still receive <span class="caps">BPS</span> events? An application should '''never''' call [https://developer.blackberry.com/native/reference/com.qnx.doc.bps.lib_ref/com.qnx.doc.bps.lib_ref/topic/bps_get_event.html bps_get_event()] ''[developer.blackberry.com]'' itself, as that would ‘steal’ the events from Qt, and Qt would miss out on important events like the above mentioned <span class="caps">NAVIGATOR</span>_EXIT.
= Receiving BPS events =


Instead, Qt offers to install '''native event filters'''. Once a native event filter is installed, Qt will forward all <span class="caps">BPS</span> events to that native event filter. So the solution for receiving <span class="caps">BPS</span> events is to install a native event filter and process the <span class="caps">BPS</span> events in the event filter function.
Since BPS events are integrated into Qt's event loop, how is it possible as a user to still receive BPS events? An application should '''never''' call &quot;bps_get_event()&quot;:https://developer.blackberry.com/native/reference/com.qnx.doc.bps.lib_ref/com.qnx.doc.bps.lib_ref/topic/bps_get_event.html itself, as that would 'steal' the events from Qt, and Qt would miss out on important events like the above mentioned NAVIGATOR_EXIT.


The following example shows how to install native event filters to process a <span class="caps">NAVIGATOR</span>_SWIPE_DOWN event. The Qt4 and the Qt5 versions are a bit different, therefore the two code examples.
Instead, Qt offers to install '''native event filters'''. Once a native event filter is installed, Qt will forward all BPS events to that native event filter. So the solution for receiving BPS events is to install a native event filter and process the BPS events in the event filter function.
 
The following example shows how to install native event filters to process a NAVIGATOR_SWIPE_DOWN event. The Qt4 and the Qt5 versions are a bit different, therefore the two code examples.


Native event filters are installed on a per-thread basis, as each thread in Qt has its own event dispatcher. Each thread only receives the native events requested in that thread. If your code that installs the native event filter is running in multiple threads, this needs to be considered, especially in Qt4 version, in which the previous event filter pointer then needs to be stored on a per-thread basis, and not as a global variable.
Native event filters are installed on a per-thread basis, as each thread in Qt has its own event dispatcher. Each thread only receives the native events requested in that thread. If your code that installs the native event filter is running in multiple threads, this needs to be considered, especially in Qt4 version, in which the previous event filter pointer then needs to be stored on a per-thread basis, and not as a global variable.


Note that this wiki page is about '''native events''' only, e.g. <span class="caps">BPS</span> events on the BlackBerry platform. Receiving normal '''QEvents''' is an entirely unrelated matter, see [http://doc.qt.io/qt-4.8/qcoreapplication.html#notify the documentation of QCoreApplication::notify()] ''[qt.io]'' for details about that.
Note that this wiki page is about '''native events''' only, e.g. BPS events on the BlackBerry platform. Receiving normal '''QEvents''' is an entirely unrelated matter, see &quot;the documentation of QCoreApplication::notify()&quot;:http://doc.qt.io/qt-4.8/qcoreapplication.html#notify for details about that.
 
=Qt4 Example=
 
First, install the native event filter. Note that the previous event filter needs to be remembered, as the native event filters form a chain – one event filter always needs to pass on the native event to the previous filter in the chain, otherwise the event gets lost!
 
Afterwards, make sure <span class="caps">BPS</span> delivers navigator events to the current thread. For certain types of events, like navigator and virtual keyboard events, Qt will already have requested the events, but I can’t hurt to request them twice:
 
Other event types, such as mmrenderer events, are not automatically requested by Qt, there you have to call the appropriate ''foo_request_events()'' function yourself.<br /> Note that it is not necessary to call ''bps_initialize()'' yourself, Qt already does that for you. But again, it doesn’t hurt either.<br /> Lastly, let’s have a look at the event filter function:
 
Note that in Qt4, native event filters should never be removed once installed, as that will easily break the chain. Instead of removing a native event filter, simply don’t do any event processing in it anymore, apart from passing the event on to the previous element in the chain.
 
=Qt5 Example=
 
The <span class="caps">API</span> for native event filters in Qt5 has been improved, the brittle event filter chaining is no longer exposed.
 
Instead of an event filter function like in Qt4, there is an event filter object:


Installing the event filter is easy:<br />
= Qt4 Example =


Afterwards, make sure <span class="caps">BPS</span> delivers navigator events to the current thread. For certain types of events, like navigator and virtual keyboard events, Qt will already have requested the events, but I can’t hurt to request them twice:
First, install the native event filter. Note that the previous event filter needs to be remembered, as the native event filters form a chain - one event filter always needs to pass on the native event to the previous filter in the chain, otherwise the event gets lost!


Other event types, such as mmrenderer events, are not automatically requested by Qt, there you have to call the appropriate ''foo_request_events()'' function yourself.<br /> Note that it is not necessary to call ''bps_initialize()'' yourself, Qt already does that for you. But again, it doesn’t hurt either.
<code><br />static QAbstractEventDispatcher::EventFilter s_previousEventFilter = 0;<br />s_previousEventFilter = QAbstractEventDispatcher::instance()<s>&gt;setEventFilter(s_eventFilter);<br /></code>
<br />Afterwards, make sure BPS delivers navigator events to the current thread. For certain types of events, like navigator and virtual keyboard events, Qt will already have requested the events, but I can't hurt to request them twice:
<br /><code><br />navigator_request_events();<br /></code>
<br />Other event types, such as mmrenderer events, are not automatically requested by Qt, there you have to call the appropriate ''foo_request_events()'' function yourself.<br />Note that it is not necessary to call ''bps_initialize()'' yourself, Qt already does that for you. But again, it doesn't hurt either.<br />Lastly, let's have a look at the event filter function:
<br /><code><br />static bool s_eventFilter(void '''message)<br />{<br /> bps_event_t''' const event = static_cast&amp;lt;bps_event_t *&gt;(message);
<br /> if (event &amp;&amp; bps_event_get_domain(event)  navigator_get_domain()) &amp;#123;
        const int id = bps_event_get_code(event);
        if (id  NAVIGATOR_SWIPE_DOWN)<br /> qDebug() &lt;&lt; &quot;The user swiped down!&quot;;<br /> }
<br /> if (s_previousEventFilter)<br /> return s_previousEventFilter(message);<br /> else<br /> return false;<br />}<br /></code>
<br />Note that in Qt4, native event filters should never be removed once installed, as that will easily break the chain. Instead of removing a native event filter, simply don't do any event processing in it anymore, apart from passing the event on to the previous element in the chain.
<br />h1. Qt5 Example
<br />The API for native event filters in Qt5 has been improved, the brittle event filter chaining is no longer exposed.
<br />Instead of an event filter function like in Qt4, there is an event filter object:
<br /><code><br />class MyEventFilter : public QAbstractNativeEventFilter<br />{<br /> bool nativeEventFilter(const QByteArray &amp;eventType, void *message, long '''result) Q_DECL_OVERRIDE<br /> {<br /> Q_UNUSED(eventType);<br /> Q_UNUSED(result);
<br /> bps_event_t''' const event = static_cast&amp;lt;bps_event_t *&gt;(message);<br /> if (event &amp;&amp; bps_event_get_domain(event)  navigator_get_domain()) &amp;#123;
        const int id = bps_event_get_code(event);
        if (id  NAVIGATOR_SWIPE_DOWN)<br /> qDebug() &lt;&lt; &quot;The user swiped down!&quot;;<br /> }
<br /> return false; // Do not filter out the event<br /> }<br />};<br /></code>
<br />Installing the event filter is easy:<br /><code><br />MyEventFilter *filter = …;<br />QCoreApplication::eventDispatcher()</s>&gt;installNativeEventFilter(filter);<br /></code>


In Qt5, native event filters can easily be removed again by calling QAbstractEventDispatcher::removeNativeEventFilter().
Afterwards, make sure BPS delivers navigator events to the current thread. For certain types of events, like navigator and virtual keyboard events, Qt will already have requested the events, but I can't hurt to request them twice:


===Categories:===
<code><br />navigator_request_events();<br /></code>


* [[:Category:BlackBerry|BlackBerry]]
Other event types, such as mmrenderer events, are not automatically requested by Qt, there you have to call the appropriate ''foo_request_events()'' function yourself.<br />Note that it is not necessary to call ''bps_initialize()'' yourself, Qt already does that for you. But again, it doesn't hurt either.

Revision as of 09:52, 24 February 2015


Introduction

The BlackBerry platform support library, BPS, provides an API for system events. In Qt, BPS events are integrated into Qt's event loop, i.e. Qt receives and consumes BPS events. One example in which Qt consumes a BPS event is the NAVIGATOR_EXIT event - when receiving that event, Qt will trigger quitting the application. See "Handling BPS events&quot;:https://developer.blackberry.com/native/documentation/cascades/device_platform/bps/ article for more details.

Receiving BPS events

Since BPS events are integrated into Qt's event loop, how is it possible as a user to still receive BPS events? An application should never call "bps_get_event()":https://developer.blackberry.com/native/reference/com.qnx.doc.bps.lib_ref/com.qnx.doc.bps.lib_ref/topic/bps_get_event.html itself, as that would 'steal' the events from Qt, and Qt would miss out on important events like the above mentioned NAVIGATOR_EXIT.

Instead, Qt offers to install native event filters. Once a native event filter is installed, Qt will forward all BPS events to that native event filter. So the solution for receiving BPS events is to install a native event filter and process the BPS events in the event filter function.

The following example shows how to install native event filters to process a NAVIGATOR_SWIPE_DOWN event. The Qt4 and the Qt5 versions are a bit different, therefore the two code examples.

Native event filters are installed on a per-thread basis, as each thread in Qt has its own event dispatcher. Each thread only receives the native events requested in that thread. If your code that installs the native event filter is running in multiple threads, this needs to be considered, especially in Qt4 version, in which the previous event filter pointer then needs to be stored on a per-thread basis, and not as a global variable.

Note that this wiki page is about native events only, e.g. BPS events on the BlackBerry platform. Receiving normal QEvents is an entirely unrelated matter, see "the documentation of QCoreApplication::notify()":http://doc.qt.io/qt-4.8/qcoreapplication.html#notify for details about that.

Qt4 Example

First, install the native event filter. Note that the previous event filter needs to be remembered, as the native event filters form a chain - one event filter always needs to pass on the native event to the previous filter in the chain, otherwise the event gets lost!

<br />static QAbstractEventDispatcher::EventFilter s_previousEventFilter = 0;<br />s_previousEventFilter = QAbstractEventDispatcher::instance()<s>&gt;setEventFilter(s_eventFilter);<br />


Afterwards, make sure BPS delivers navigator events to the current thread. For certain types of events, like navigator and virtual keyboard events, Qt will already have requested the events, but I can't hurt to request them twice:


<br />navigator_request_events();<br />


Other event types, such as mmrenderer events, are not automatically requested by Qt, there you have to call the appropriate foo_request_events() function yourself.
Note that it is not necessary to call bps_initialize() yourself, Qt already does that for you. But again, it doesn't hurt either.
Lastly, let's have a look at the event filter function:


<br />static bool s_eventFilter(void '''message)<br />{<br /> bps_event_t''' const event = static_cast&amp;lt;bps_event_t *&gt;(message);
<br /> if (event &amp;&amp; bps_event_get_domain(event)  navigator_get_domain()) &amp;#123;
        const int id = bps_event_get_code(event);
        if (id  NAVIGATOR_SWIPE_DOWN)<br /> qDebug() &lt;&lt; &quot;The user swiped down!&quot;;<br /> }
<br /> if (s_previousEventFilter)<br /> return s_previousEventFilter(message);<br /> else<br /> return false;<br />}<br />


Note that in Qt4, native event filters should never be removed once installed, as that will easily break the chain. Instead of removing a native event filter, simply don't do any event processing in it anymore, apart from passing the event on to the previous element in the chain.
h1. Qt5 Example
The API for native event filters in Qt5 has been improved, the brittle event filter chaining is no longer exposed.
Instead of an event filter function like in Qt4, there is an event filter object:


<br />class MyEventFilter : public QAbstractNativeEventFilter<br />{<br /> bool nativeEventFilter(const QByteArray &amp;eventType, void *message, long '''result) Q_DECL_OVERRIDE<br /> {<br /> Q_UNUSED(eventType);<br /> Q_UNUSED(result);
<br /> bps_event_t''' const event = static_cast&amp;lt;bps_event_t *&gt;(message);<br /> if (event &amp;&amp; bps_event_get_domain(event)  navigator_get_domain()) &amp;#123;
        const int id = bps_event_get_code(event);
        if (id  NAVIGATOR_SWIPE_DOWN)<br /> qDebug() &lt;&lt; &quot;The user swiped down!&quot;;<br /> }
<br /> return false; // Do not filter out the event<br /> }<br />};<br />


Installing the event filter is easy:

<br />MyEventFilter *filter = ;<br />QCoreApplication::eventDispatcher()</s>&gt;installNativeEventFilter(filter);<br />

Afterwards, make sure BPS delivers navigator events to the current thread. For certain types of events, like navigator and virtual keyboard events, Qt will already have requested the events, but I can't hurt to request them twice:

<br />navigator_request_events();<br />

Other event types, such as mmrenderer events, are not automatically requested by Qt, there you have to call the appropriate foo_request_events() function yourself.
Note that it is not necessary to call bps_initialize() yourself, Qt already does that for you. But again, it doesn't hurt either.