Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, April 2008
Detetcting application activate/deactivate events


Message 1 in thread

Hi Everybody, 

I am converting a Delphi application that relied on getting these events to acquire and release audio devices. Other than the list of event types, I couldn't see anything in Qt docs for this, so I tried the code below. 

The problem is that these events are occurring when the main window opens another form with itself as parent, and when QMessageBox is called with a NULL first parameter. 

Thanks in advance for any hints, or a pointer to better doco on WHEN the different types of events are delivered to WHICH type of objects. 

Tony Rietwyk, 

<code>

In the main window constructor: 

	qApp->installEventFilter( this );

The eventFilter is:

bool TRisingMain::eventFilter(QObject *obj,  QEvent *event)
{
	if (obj == qApp  &&  !inActivationEvent)
	{
		if (event->type() == QEvent::ApplicationActivate)
		{
			// This gets called when the application starts, and when you switch back. 
			inActivationEvent = true;
			qDebug() << "application activated";
			frmAudio.startMidi( activated );
			activated = true;
			inActivationEvent = false;
		}

		else if (event->type() == QEvent::ApplicationDeactivate)
		{
			// This gets called when the application closes, and when you switch away. 
			inActivationEvent = true;
			qDebug() << "application deactivated";
			frmAudio.stopMidi();
			inActivationEvent = false;
		}
	}

	return QMainWindow::eventFilter(obj, event);
}

</code>

--
 [ signature omitted ] 

Message 2 in thread

Just discovered this myself today.

You want to create an event() function override, and handle the
QEvent::WindowActivate and  QEvent::WindowDeactivate event types.

Tony Rietwyk wrote:
> Hi Everybody, 
>
> I am converting a Delphi application that relied on getting these events to acquire and release audio devices. Other than the list of event types, I couldn't see anything in Qt docs for this, so I tried the code below. 
>
> The problem is that these events are occurring when the main window opens another form with itself as parent, and when QMessageBox is called with a NULL first parameter. 
>
> Thanks in advance for any hints, or a pointer to better doco on WHEN the different types of events are delivered to WHICH type of objects. 
>
> Tony Rietwyk, 
>
> <code>
>
> In the main window constructor: 
>
> 	qApp->installEventFilter( this );
>
> The eventFilter is:
>
> bool TRisingMain::eventFilter(QObject *obj,  QEvent *event)
> {
> 	if (obj == qApp  &&  !inActivationEvent)
> 	{
> 		if (event->type() == QEvent::ApplicationActivate)
> 		{
> 			// This gets called when the application starts, and when you switch back. 
> 			inActivationEvent = true;
> 			qDebug() << "application activated";
> 			frmAudio.startMidi( activated );
> 			activated = true;
> 			inActivationEvent = false;
> 		}
>
> 		else if (event->type() == QEvent::ApplicationDeactivate)
> 		{
> 			// This gets called when the application closes, and when you switch away. 
> 			inActivationEvent = true;
> 			qDebug() << "application deactivated";
> 			frmAudio.stopMidi();
> 			inActivationEvent = false;
> 		}
> 	}
>
> 	return QMainWindow::eventFilter(obj, event);
> }
>
> </code>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>   


-- 
 [ signature omitted ] 

Message 3 in thread

Ignore this. My bad. Only works for Qtopia.

Bill KING wrote:
> Just discovered this myself today.
>
> You want to create an event() function override, and handle the
> QEvent::WindowActivate and  QEvent::WindowDeactivate event types.
>
> Tony Rietwyk wrote:
>   
>> Hi Everybody, 
>>
>> I am converting a Delphi application that relied on getting these events to acquire and release audio devices. Other than the list of event types, I couldn't see anything in Qt docs for this, so I tried the code below. 
>>
>> The problem is that these events are occurring when the main window opens another form with itself as parent, and when QMessageBox is called with a NULL first parameter. 
>>
>> Thanks in advance for any hints, or a pointer to better doco on WHEN the different types of events are delivered to WHICH type of objects. 
>>
>> Tony Rietwyk, 
>>
>> <code>
>>
>> In the main window constructor: 
>>
>> 	qApp->installEventFilter( this );
>>
>> The eventFilter is:
>>
>> bool TRisingMain::eventFilter(QObject *obj,  QEvent *event)
>> {
>> 	if (obj == qApp  &&  !inActivationEvent)
>> 	{
>> 		if (event->type() == QEvent::ApplicationActivate)
>> 		{
>> 			// This gets called when the application starts, and when you switch back. 
>> 			inActivationEvent = true;
>> 			qDebug() << "application activated";
>> 			frmAudio.startMidi( activated );
>> 			activated = true;
>> 			inActivationEvent = false;
>> 		}
>>
>> 		else if (event->type() == QEvent::ApplicationDeactivate)
>> 		{
>> 			// This gets called when the application closes, and when you switch away. 
>> 			inActivationEvent = true;
>> 			qDebug() << "application deactivated";
>> 			frmAudio.stopMidi();
>> 			inActivationEvent = false;
>> 		}
>> 	}
>>
>> 	return QMainWindow::eventFilter(obj, event);
>> }
>>
>> </code>
>>
>> --
>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
>> List archive and information: http://lists.trolltech.com/qt-interest/
>>
>>
>>   
>>     
>
>
>   


-- 
 [ signature omitted ] 

Message 4 in thread

Bill wrote: 

> Ignore this. My bad. Only works for Qtopia.
> 
> Bill KING wrote:
> > Just discovered this myself today.
> >
> > You want to create an event() function override, and handle the
> > QEvent::WindowActivate and  QEvent::WindowDeactivate event types.
> >

That's alright Bill. 

To clarify, I need the events that fire when you switch between applications, not between windows of the same application. I also need to know which object to listen on, if not qApp. 

Thanks, 

> > Tony Rietwyk wrote:
> >   
> >> Hi Everybody, 
> >>
> >> I am converting a Delphi application that relied on 
> getting these events to acquire and release audio devices. 
> Other than the list of event types, I couldn't see anything 
> in Qt docs for this, so I tried the code below. 
> >>
> >> The problem is that these events are occurring when the 
> main window opens another form with itself as parent, and 
> when QMessageBox is called with a NULL first parameter. 
> >>
> >> Thanks in advance for any hints, or a pointer to better 
> doco on WHEN the different types of events are delivered to 
> WHICH type of objects. 
> >>
> >> Tony Rietwyk, 
> >>
> >> <code>
> >>
> >> In the main window constructor: 
> >>
> >> 	qApp->installEventFilter( this );
> >>
> >> The eventFilter is:
> >>
> >> bool TRisingMain::eventFilter(QObject *obj,  QEvent *event)
> >> {
> >> 	if (obj == qApp  &&  !inActivationEvent)
> >> 	{
> >> 		if (event->type() == QEvent::ApplicationActivate)
> >> 		{
> >> 			// This gets called when the 
> application starts, and when you switch back. 
> >> 			inActivationEvent = true;
> >> 			qDebug() << "application activated";
> >> 			frmAudio.startMidi( activated );
> >> 			activated = true;
> >> 			inActivationEvent = false;
> >> 		}
> >>
> >> 		else if (event->type() == QEvent::ApplicationDeactivate)
> >> 		{
> >> 			// This gets called when the 
> application closes, and when you switch away. 
> >> 			inActivationEvent = true;
> >> 			qDebug() << "application deactivated";
> >> 			frmAudio.stopMidi();
> >> 			inActivationEvent = false;
> >> 		}
> >> 	}
> >>
> >> 	return QMainWindow::eventFilter(obj, event);
> >> }
> >>
> >> </code>

--
 [ signature omitted ] 

Message 5 in thread

Tony,

I ran into the same issue, and solved it through use of timers.  Below is
the code I used, hope it helps...

-jim


// It seems that Qt Deactivates and re-Activates the application every time
// a global window is opened and closed (this includes dialogs such as the 
// progress dialog).  These events happen in rapid succession, ending with
// the app in an active state.  To actually catch a true deactivation we
have
// set up a timer that will be enabled on deactivation and disabled on
// activation. Thus when the application truly looses focus the timer will 
// be active and fire immediately and we will then test if we need to 
// change certain application states (i.e. save-all when app looses focus).

bool MyQApplication::event(QEvent *event)
{
	bool result = false;

	switch (event->type()) {		
		case QEvent::ApplicationActivate:
			// Clear the timer event
			if (mDeactivateTimer)
			{
				killTimer(mDeactivateTimer);
				mDeactivateTimer = 0;
			}
			break;
			
		case QEvent::ApplicationDeactivate:
			// Clear the timer event
			if (mDeactivateTimer)
			{
				killTimer(mDeactivateTimer);
				mDeactivateTimer = 0;
			}

			// (Re)set a new timer event
			mDeactivateTimer = startTimer(0);
			break;
			
		default:
			result = QApplication::event(event);
			break;
	}
	
	return result;
}

void MyQApplication::timerEvent(QTimerEvent *event)
{
	if (mDeactivateTimer == event->timerId())
	{
		// The application has truly lost focus.
		killTimer(mDeactivateTimer);
		mDeactivateTimer = 0;

		// Do your deactivation logic here...

		if (DoSaveAllOnApplicationDeactivate())
		{
			SaveAllEditors();
		}
	}
}

-----Original Message-----
From: Tony Rietwyk [mailto:tony.rietwyk@xxxxxxxxxxxxxxxx] 
Sent: Thursday, April 03, 2008 12:10 AM
To: qt-interest@xxxxxxxxxxxxx
Subject: RE: Detetcting application activate/deactivate events

Bill wrote: 

> Ignore this. My bad. Only works for Qtopia.
> 
> Bill KING wrote:
> > Just discovered this myself today.
> >
> > You want to create an event() function override, and handle the
> > QEvent::WindowActivate and  QEvent::WindowDeactivate event types.
> >

That's alright Bill. 

To clarify, I need the events that fire when you switch between
applications, not between windows of the same application. I also need to
know which object to listen on, if not qApp. 

Thanks, 

> > Tony Rietwyk wrote:
> >   
> >> Hi Everybody, 
> >>
> >> I am converting a Delphi application that relied on 
> getting these events to acquire and release audio devices. 
> Other than the list of event types, I couldn't see anything 
> in Qt docs for this, so I tried the code below. 
> >>
> >> The problem is that these events are occurring when the 
> main window opens another form with itself as parent, and 
> when QMessageBox is called with a NULL first parameter. 
> >>
> >> Thanks in advance for any hints, or a pointer to better 
> doco on WHEN the different types of events are delivered to 
> WHICH type of objects. 
> >>
> >> Tony Rietwyk, 
> >>
> >> <code>
> >>
> >> In the main window constructor: 
> >>
> >> 	qApp->installEventFilter( this );
> >>
> >> The eventFilter is:
> >>
> >> bool TRisingMain::eventFilter(QObject *obj,  QEvent *event)
> >> {
> >> 	if (obj == qApp  &&  !inActivationEvent)
> >> 	{
> >> 		if (event->type() == QEvent::ApplicationActivate)
> >> 		{
> >> 			// This gets called when the 
> application starts, and when you switch back. 
> >> 			inActivationEvent = true;
> >> 			qDebug() << "application activated";
> >> 			frmAudio.startMidi( activated );
> >> 			activated = true;
> >> 			inActivationEvent = false;
> >> 		}
> >>
> >> 		else if (event->type() == QEvent::ApplicationDeactivate)
> >> 		{
> >> 			// This gets called when the 
> application closes, and when you switch away. 
> >> 			inActivationEvent = true;
> >> 			qDebug() << "application deactivated";
> >> 			frmAudio.stopMidi();
> >> 			inActivationEvent = false;
> >> 		}
> >> 	}
> >>
> >> 	return QMainWindow::eventFilter(obj, event);
> >> }
> >>
> >> </code>

--
 [ signature omitted ] 

Message 6 in thread

Am Donnerstag, 3. April 2008 schrieb Tony Rietwyk:
> I am converting a Delphi application that relied on getting these events to
> acquire and release audio devices. Other than the list of event types, I
> couldn't see anything in Qt docs for this, so I tried the code below.

Why don't you just access the sound-device in a way that it can be shared?
On linux the alsa-driver has the dmix-plugin as default since some versions, 
which allows for several apps to open the same sound-device parallel without 
any change in the app (if you access it by alsa and not by 
oss-compatibility).

And the new phonon should "make it right" too...

Arnold
-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 7 in thread

I would still like to see an answer to the original question for other
reasons. I have figured out how to detect which mode my application is in,
but it would be nice to get an event when my whole application is activated
or deactivated (is the main application receiving user input events and has
the highlighted window frame).

Keith
**Please do not reply to me, reply to the list.**


On 04-03-2008 3:35 AM, "Arnold Krille" wrote:

> Am Donnerstag, 3. April 2008 schrieb Tony Rietwyk:
>> I am converting a Delphi application that relied on getting these events to
>> acquire and release audio devices. Other than the list of event types, I
>> couldn't see anything in Qt docs for this, so I tried the code below.
> 
> Why don't you just access the sound-device in a way that it can be shared?
> On linux the alsa-driver has the dmix-plugin as default since some versions,
> which allows for several apps to open the same sound-device parallel without
> any change in the app (if you access it by alsa and not by
> oss-compatibility).
> 
> And the new phonon should "make it right" too...
> 
> Arnold


--
 [ signature omitted ] 

Message 8 in thread

Am Donnerstag, 3. April 2008 schrieb Keith Esau:
> I would still like to see an answer to the original question for other
> reasons. I have figured out how to detect which mode my application is in,
> but it would be nice to get an event when my whole application is activated
> or deactivated (is the main application receiving user input events and has
> the highlighted window frame).

In the times of multi-user (and pretty soon multi-input), what does "app gets 
activated" mean?

Better solve the underlying problem, not just cure the symptoms...

Have fun,

Arnold
-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 9 in thread

Arnold wrote:

> Why don't you just access the sound-device in a way that it 
> can be shared?
> On linux the alsa-driver has the dmix-plugin as default since 
> some versions, 
> which allows for several apps to open the same sound-device 
> parallel without 
> any change in the app (if you access it by alsa and not by 
> oss-compatibility).

I need inputs as well as outputs, so sharing doesn't make sense. 

> And the new phonon should "make it right" too...

My understanding is that phonon is OK for midi and wave output, but it only supports video input (mpeg), not the other two - especially wave input for spectral analysis? 

Also I did not want to base my development on beta versions. 

Regards, 

Tony

--
 [ signature omitted ] 

Message 10 in thread

Hi Tony

As for your original question, on Windows at least I think you need to 
intercept the WM_ACTIVATEAPP message. Presumably this will get sent to 
whatever window is currently active in your app. I'm not sure if there's a 
corresponding Qt event for this but a quick look at Qt Assistant shows:

QEvent::ApplicationActivate
The application has been made available to the user.

and

QEvent::ApplicationDeactivate
The application has been suspended, and is unavailable to the user.

Perhaps that's what you need.

As far as cross-platform audio i/o goes you may want to consider the 
open-source PortAudio project if you havn't already:
http://www.portaudio.com

Cheers

Ross
(Melbourne, AU)


----- Original Message ----- 
From: "Tony Rietwyk" <tony.rietwyk@xxxxxxxxxxxxxxxx>
To: <qt-interest@xxxxxxxxxxxxx>
Sent: Friday, April 04, 2008 8:26 AM
Subject: RE: Detetcting application activate/deactivate events


Arnold wrote:

> Why don't you just access the sound-device in a way that it
> can be shared?
> On linux the alsa-driver has the dmix-plugin as default since
> some versions,
> which allows for several apps to open the same sound-device
> parallel without
> any change in the app (if you access it by alsa and not by
> oss-compatibility).

I need inputs as well as outputs, so sharing doesn't make sense.

> And the new phonon should "make it right" too...

My understanding is that phonon is OK for midi and wave output, but it only 
supports video input (mpeg), not the other two - especially wave input for 
spectral analysis?

Also I did not want to base my development on beta versions.

Regards,

Tony

--
 [ signature omitted ] 

Message 11 in thread

Ross wrote: 

> As for your original question, on Windows at least I think 
> you need to 
> intercept the WM_ACTIVATEAPP message. Presumably this will 
> get sent to 
> whatever window is currently active in your app. I'm not sure 
> if there's a 
> corresponding Qt event for this but a quick look at Qt 
> Assistant shows:
> 
> QEvent::ApplicationActivate
> The application has been made available to the user.
> 
> and
> 
> QEvent::ApplicationDeactivate
> The application has been suspended, and is unavailable to the user.
> 
> Perhaps that's what you need.

I am listening for those QEvents on qApp, but they are also being sent whenever focus switches between top-level windows of the application. I may try overriding QApplication itself, and listening for that message on Windows. 

> As far as cross-platform audio i/o goes you may want to consider the 
> open-source PortAudio project if you havn't already:
> http://www.portaudio.com

Yes, but I found it difficult to incorporate the asynchronous inputs, with my Qt code. 

Tony.

--
 [ signature omitted ] 

Message 12 in thread

Hi Tony

>> QEvent::ApplicationActivate
>> The application has been made available to the user.
>>
>> and
>>
>> QEvent::ApplicationDeactivate
>> The application has been suspended, and is unavailable to the user.
>>
>> Perhaps that's what you need.
>
>I am listening for those QEvents on qApp, but they are also being sent 
>whenever focus switches between top-level windows of the >application.

Although the documentation's description of those events is a bit vague, to 
me that sounds like you're seeing a bug in Qt. I would definitely discuss 
that with Trolltech support if I were you.


>> As far as cross-platform audio i/o goes you may want to consider the
>> open-source PortAudio project if you havn't already:
>> http://www.portaudio.com
>
>Yes, but I found it difficult to incorporate the asynchronous inputs, with 
>my Qt code.

Obviously I don't know your system's, requirements but in general I don't 
think this is a simple thing to do, mainly due to the real-time requirements 
of audio streaming, the non-real-time nature of desktop GUI code, and the 
fact that the usual mechanisms for communicating between threads use 
blocking primitives (like Mutexes) which should generally be avoided in 
real-time code. I'm not sure whether Qt's interthread queuing code is any 
better in this regard.

I generally isolate the asynchronous audio processing as if it were a 
different thread and use lock-free FIFO queues when communicating between 
asynchronous audio callbacks and the GUI. Usually this means I have a QTimer 
to poll the queues coming back from the real-time context. In some 
situations you can get away with using PortAudio's internal queuing and its 
blocking i/o API -- polling the streams to see if they need more data.

Best wishes

Ross.







--
 [ signature omitted ] 

Message 13 in thread

Am Donnerstag, 3. April 2008 schrieb Tony Rietwyk:
> Arnold wrote:
> > Why don't you just access the sound-device in a way that it
> > can be shared?
> > On linux the alsa-driver has the dmix-plugin as default since
> > some versions,
> > which allows for several apps to open the same sound-device
> > parallel without
> > any change in the app (if you access it by alsa and not by
> > oss-compatibility).
> I need inputs as well as outputs, so sharing doesn't make sense.

Why should the sense of sharing vanish when you also need inputs? While all 
the outputs get mixed together with sharing, all the inputs get the same 
signal. voila.

> > And the new phonon should "make it right" too...
> My understanding is that phonon is OK for midi and wave output, but it only
> supports video input (mpeg), not the other two - especially wave input for
> spectral analysis?

The input-part of phonon is not yet ready. That is right. But it is being 
worked on.

> Also I did not want to base my development on beta versions.

Is your release sooner than Qt4.4?

Arnold
-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 14 in thread

Hi Arnold, 

> What about QEvent::WindowActivate, QEvent::WindowDeactivate, 
> QEvent::ApplicationActivate and QEvent::ApplicationDeactivate. Did you try to 
> check for them in an event-handler?

Please refer to my original post - I thought the code does what you are suggesting. 

> Am Donnerstag, 3. April 2008 schrieb Tony Rietwyk:
> > Arnold wrote:
> > > Why don't you just access the sound-device in a way that it
> > > can be shared?
> > > On linux the alsa-driver has the dmix-plugin as default since
> > > some versions,
> > > which allows for several apps to open the same sound-device
> > > parallel without
> > > any change in the app (if you access it by alsa and not by
> > > oss-compatibility).
> > I need inputs as well as outputs, so sharing doesn't make sense.
> 
> Why should the sense of sharing vanish when you also need 
> inputs? While all 
> the outputs get mixed together with sharing, all the inputs 
> get the same 
> signal. voila.

Another consideration that I didn't explicitly mention is that I already HAVE a working windows solution. I haven't seen anything in the Microsoft docs to indicate how to open a midi or wave input device in shared mode. If you can provide a reference for your suggestion, I would appreciate it very much. 

> > > And the new phonon should "make it right" too...
> > My understanding is that phonon is OK for midi and wave 
> output, but it only
> > supports video input (mpeg), not the other two - especially 
> wave input for
> > spectral analysis?
> 
> The input-part of phonon is not yet ready. That is right. But 
> it is being 
> worked on.
> 
> > Also I did not want to base my development on beta versions.
> 
> Is your release sooner than Qt4.4?

No. But I have already been stung by changes to symbol font code (task 184442) that works in 4.3.1 and has been removed in later releases. I am yet to find a workaround in 4.3.4, and will probably have to regress, since a fix has been pushed out to 4.5. 

Tony.

--
 [ signature omitted ] 

Message 15 in thread

Please reply to the list...

Am Donnerstag, 3. April 2008 schrieben Sie:
> > In the times of multi-user (and pretty soon multi-input),
> > what does "app gets
> > activated" mean?
> > Better solve the underlying problem, not just cure the symptoms...
> I don't understand what you mean by multi-user (a server?), and
> multi-input?

Multi-user means that it is rather common that several user are accessing one 
system at the same time. Either by several screen/key/mouse-sets or via 
thin-clients.

Multi-input means that there are several projects emerging that allow multiple 
pointers on one screen. When several mouse-pointers are on the screen, there 
is not only one app "active" (= has the focus).

> Maybe application activated is a Windows only concept:
> http://msdn2.microsoft.com/en-us/library/system.windows.application.activat
>e d.aspx

I think "application activated" is a bad concept because it tries to get 
events to trigger actions to circumvent deeper problems.

> If so, what do the Qt events of the same name represent? The one line
> descriptions in QEvent are pretty vague!

What about QEvent::WindowActivate, QEvent::WindowDeactivate, 
QEvent::ApplicationActivate and QEvent::ApplicationDeactivate. Did you try to 
check for them in an event-handler?

Have fun,

Arnold
-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.