nsIIdleService 的实现与应用

本文详细解析Mozilla的nsIIdleService接口在Windows系统中的实现方式,包括获取空闲时间、修改离开状态等核心功能,并展示了如何在实际应用中使用此接口。文章深入探讨了接口的跨平台实现、利用observer机制简化服务实现的特点,以及通过实例代码展示其在自动设置QQ“离开”功能的应用场景。

在 Mozilla 中有一个服务可以实现对系统消息的侦听,就是 nsIIdleService 接口。

该接口主要实现的功能是:设置一个时间段,当你在这个时间段内没有对计算机进行操作(键盘触发和鼠标操作)时,它会侦听到一个 idle 的消息,而你可以对这个消息做处理,做你想要实现的效果。

其实,就是在 QQ 中实现的“离开”的自动设置的功能。

分析源码,涉及到 nsITimer 及其相关内容,对这部分还不是很懂,继续研究中。

经过一番分析,终于找到它是如何侦听系统消息的了。 图一中所示代码是在windows下实现的接口中的 idleTime 的获取过程。其中,通过GetLastInputInfo获取最后的 input event 的时间。

正是在这个函数中,实现在对 windows 系统消息的捕获,nsIIdleService 在实现接口的时候利用该属性与设定的侦听的延迟时间做比较,从而进行触发,如此想来,就很是简单了。图二中所示代码是 nsIIdleService 中实现的 checkAwayState 方法。

图一:在 windows 中实现的 GetIdleTime 方法

NS_IMETHODIMP
nsIdleServiceWin: : GetIdleTime( PRUint32 * aTimeDiff)
{
    LASTINPUTINFO inputInfo;
    inputInfo. cbSize = sizeof ( inputInfo) ;
    if ( ! : : GetLastInputInfo( & inputInfo) )
        return NS_ERROR_FAILURE;

    * aTimeDiff = GetTickCount( ) - inputInfo. dwTime;
    return NS_OK;
}


关 于windows 对消息事件的处理,可参阅 Keyboard Input

图二: 在 nsIdleService.cpp 中实现的修改 away state 的方法

void
nsIdleService: : CheckAwayState( )
{
    // Get the idle time.

    PRUint32 idleTime;
    if ( NS_FAILED( GetIdleTime( & idleTime) ) )
        return ;

    nsAutoString timeStr;
    timeStr. AppendInt( idleTime) ;

    // Change state first, and save observers that need notification, so

    // removing things will always work without upsetting notifications.

    nsCOMArray< nsIObserver> idleListeners;
    nsCOMArray< nsIObserver> hereListeners;
    for ( PRUint32 i = 0; i < mArrayListeners. Length( ) ; i+ + )
    {
        IdleListener& curListener = mArrayListeners. ElementAt( i) ;
        if ( ( curListener. reqIdleTime * 1000 < = idleTime) & &
            ! curListener. isIdle)
        {
            curListener. isIdle = PR_TRUE;
            idleListeners. AppendObject( curListener. observer) ;
        }
        else if ( ( curListener. reqIdleTime * 1000 > idleTime) & &
                 curListener. isIdle)
        {
            curListener. isIdle = PR_FALSE;
            hereListeners. AppendObject( curListener. observer) ;
        }
    }

    // Notify listeners gone idle:

    for ( PRInt32 i = 0; i < idleListeners. Count ( ) ; i+ + )
    {
        idleListeners[ i] - > Observe( this , OBSERVER_TOPIC_IDLE, timeStr. get( ) ) ;
    }

    // Notify listeners that came back:

    for ( PRInt32 i = 0; i < hereListeners. Count ( ) ; i+ + )
    {
        hereListeners[ i] - > Observe( this , OBSERVER_TOPIC_BACK, timeStr. get( ) ) ;
    }
}


在 这段源代码的分析中,可以看到 mozilla 在实现一个接口的思想。它的跨平台的实现,也显现了出来。而对服务的实现,也是利用 observer 机制很简单就实现了。真是佩服。

我要好好消化下。

在应用方面,mozilla 官网上的实例很不错。如图三所示:

var idleService = Components. classes [ "@mozilla.org/widget/idleservice;1" ]
                            . getService( Components. interfaces. nsIIdleService)
var idleObserver = {
  observe: function ( subject, topic, data ) {
    alert ( "topic: " + topic + "/ndata: " + data ) ;
  }
} ;
idleService. addIdleObserver( idleObserver, 60) ; // one minute

// ...

// Don't forget to remove the observer using removeIdleObserver!

idleService. removeIdleObserver( idleObserver, 60) ;


第一次这样研究 mozilla 里的 xpcom ,我想这仅仅是一个开始,我将坚持下去,深入的理解这个庞大强悍的 Gecko 内核。

加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值