
    EgyF                         d dl mZmZmZmZmZ d dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlmZ d dlZd dlmZmZmZ d dlmZ d dlmZ  G d dej4                        Zy)	    )GdkGObjectGLibGioCScreensaverN)Stage)utilssettingstrackers)FocusNavigator)DEBUGc                   &    e Zd ZdZdej
                  j                  deffiZ fdZ	d Z
d Zd%dZd Zd&d	Zd
 Zd Zd Zd Zd&dZd Zd Zd&dZd Zd Zd Zd Zd Zd&dZd Zd&dZd Zd Z d Z!d Z"d Z#d Z$d  Z%d! Z&d" Z'd# Z(d$ Z) xZ*S )'ScreensaverManagerz
    The ScreensaverManager is the central point where most major decision are made,
    and where ScreensaverService requests are acted upon.
    active-changedNc                    t         t        |           d| _        d | _        d | _        d| _        d| _        d| _        d| _	        d| _
        dt        _        dt        _        dt        _        t               | _        t"        j$                  | _        t)        j*                         j-                  | j&                  d| j.                         t"        j0                  | _        t#        j4                  |        y )Nr   Fzidle-changed)superr   __init__activated_timestampstage	old_stagestage_refresh_id
refreshingrefresh_againfb_pidfb_failed_to_startstatusActiveLockedAwaker   	focus_nav
singletonsSessionClientsession_clientr   con_tracker_getconnecton_session_idle_changedCinnamonClientcinnamon_clientLoginClientResolver)self	__class__s    */usr/share/cinnamon-screensaver/manager.pyr   zScreensaverManager.__init__   s     $02#$ 
 !""' ')(66  "**4+>+>+9+/+G+G	I  *88&&t,    c                 "    t         j                  S )zS
        Return if we're Locked - we could be Active without being locked.
        )r   r   r*   s    r,   	is_lockedzScreensaverManager.is_locked;   s     }}r-   c                     |r-dt         _        t         j                  r| j                          y y dt         _        t         j                  r| j	                          y y )NTF)r   r   UseFallbackspawn_fallback_windowkill_fallback_window)r*   lockeds     r,   
set_lockedzScreensaverManager.set_lockedA   sI     FM!!**, " "FM!!))+ "r-   c                 6   t         j                  sI| j                  d|      r6| j                          t	        j
                         r| j                  d       yyt	        j
                         r| j                  d       | j                  j                  |       y)a  
        Initiate locking (activating first if necessary.)  Return True if we were
        already active and just need to set the lock flag (or we were already locked
        as well).  Return False if we're not active, and need to construct a stage, etc...
        TF)	r   r   
set_activestop_lock_delayr	   user_can_lockr6   r   set_message)r*   msgs     r,   lockzScreensaverManager.lockK   sv     }}tS)$$&&&(OOD)  ""$%JJ""3' r-   c                 ^    | j                  d       | j                  d       dt        _        y)z5
        Initiate unlocking and deactivating
        FN)r8   r6   r   r   r/   s    r,   unlockzScreensaverManager.unlockc   s#     	r-   c                    |rlt         j                  s?| j                  j                          t        j
                  j                  t         j                        | _        t        j                  j                  t         j                        t         _
        | j                  j                  d      r| j                  sIt        j                  j                         j!                          | j#                  || j$                         y| j                  j'                  | j$                         | j                  j)                  |       ydt         _        y| j                  j)                  |       y| j                  ra| j                  j+                          | j-                          t        j                  j                         j+                          g t         _        dt         _
        y)a  
        Activates or deactivates the screensaver.  Activation involves:
            - sending a request to Cinnamon to exit Overview or Expo -
              this could prevent a successful screen grab and keep the
              screensaver from activating.
            - grabbing the keyboard and mouse.
            - creating the screensaver Stage.
        Deactivation involves:
            - destroying the screensaver stage.
            - releasing our keyboard and mouse grabs.
        FTN)r   r   r(   exit_expo_and_overviewr   EventGrabbernewDebuggrab_helperScreenscreen	grab_rootr   r   Applicationget_defaultholdspawn_stageon_spawn_stage_completeactivater;   releasedespawn_stagefocusWidgets)r*   activer<   s      r,   r8   zScreensaverManager.set_activek   sF    ==$$;;=#/#<#<#@#@#N  , 3 3 7 7 E##--e4::335::<((d.J.JK   

++D,H,HI

..s3$)FM 

&&s+zz  ((*""$++-557&(# FMr-   c                 "    t         j                  S )zh
        Return whether we're Active or not (showing) - this is not
        necessarily Locked.
        )r   r   r/   s    r,   
get_activezScreensaverManager.get_active   s    
 }}r-   c                 v    | j                   dk7  r*t        t        j                         | j                   z
        S y)zI
        Return how long we've been activated, or 0 if we're not
        r   )r   inttimer/   s    r,   get_active_timez"ScreensaverManager.get_active_time   s1     ##q(tyy{T%=%==>>r-   c                 "   t         j                  syt         j                  s!t        d       t        d       t        d       t         j                  r| j
                  j                         rjt         j                  st        d       | j
                  j                          | j                  j                          | j
                  j                          yt        d       t        j                         j                  d| j                         y)a:  
        Called upon any key, motion or button event, does different things
        depending on our current state.

        If we're idle:
            - do nothing

        If we're locked:
            - show the unlock widget (if it's already visible, this also has
              the effect of resetting the unlock timeout - see Stage.py)
            - show the mouse pointer, so the user can navigate the unlock screen.

        If we're Active but not Locked, simply deactivate (destroying the Stage
        and returning the screensaver back to idle mode.)
        Nz+*******************************************zmanager: user activity, waking:z&manager: locked, raising unlock widgetz/manager: not locked, queueing idle deactivationidle-deactivate)r   r   r   r   r   r   initialize_pamraise_unlock_widgetrE   release_mousemaybe_update_layoutr   timer_tracker_getadd_idleidle_deactivater/   s    r,   simulate_user_activityz)ScreensaverManager.simulate_user_activity   s      }}||?@34?@==TZZ668<<>?JJ**,**,JJ**,CD&&(112C262F2FHr-   c                 l    | j                  d       t        j                         j                  d       y)NFrZ   )r8   r   r_   cancelr/   s    r,   ra   z"ScreensaverManager.idle_deactivate   s)    ""$++,=>r-   c                 $   	 t        | |      | _        | j                  j                  |       y# t        $ rW t	        d       t        j                          | j                  j                          dt        _
        | j                          Y yw xY w)z
        Create the Stage and begin fading it in.  This may run quickly, in the case of
        user-initiated activation, or slowly, when the session has gone idle.
        z#Could not spawn screensaver stage:
FN)r   r   rN   	Exceptionprint	traceback	print_excrE   rO   r   r   cancel_timers)r*   away_messagecallbacks      r,   rL   zScreensaverManager.spawn_stage   sp    
	!t\2DJJJ) 	!89!$$&!FM 	!s   ,/ ABBc                     | j                   dkD  ry t        d       | j                  j                         r| j	                  |        y | j                  j                  d| j                         y )Nr   z!manager: spawning fallback windowrealize)r   r   r   get_realized_real_spawn_fallback_windowr%   r/   s    r,   r3   z(ScreensaverManager.spawn_fallback_window   sQ    ;;?12::""$,,T2JJy$*J*JKr-   c                 R   d }d }t        j                         d d }g }	 t        j                  ddg      j	                  d      }|j                  d      D ]  }|j                  |      rfd|v r9d|v r5|j                         d   j                  dd	      }|j                  |       Qd|v sV|j                         d   j                  dd	      }zd|v s|j                  |j                         d   j                  dd	              |j                          |+t        dd
      D ]  }t        |      |vst        |      } n |	 t        j                  d   }|	|dk7  rdnd}||gS # t        $ r!}t        dt        |      z         Y d }~Jd }~ww xY w# t         $ r d}Y Iw xY w)N   wz-hzutf-8
zcinnamon-sessiontty       z(Failed to get tty numbers using w -h: %sXDG_VTNR721)r   get_user_name
subprocesscheck_outputdecodesplit
startswithreplaceappendsortrangestrrf   rg   osenvironKeyError)	r*   session_ttyterm_ttyusernameused_tty
tty_outputlineies	            r,   get_tty_valszScreensaverManager.get_tty_vals   s   %%'+	G#00#t=DDWMJ"((. H??8,)T1etm&*jjl1o&=&=eR&H 4$#'::<?#:#:5"#Ed]OODJJLO$;$;E2$FGH MMOq! A1vX-#&q6 " jj4 )S0scH+&&  	G<s1vEFF	G  "!"s=   BE+ ,(E+ A"E+ 8E+ 	F +	F4FFF&%F&c                 l   | j                   dkD  ry | j                         \  }}t        j                  j	                  t
        j                  d      dt        | j                  j                         j                               d|d|g}t        j                  r|j                  d       	 t        j                  |      d   | _         	 | j                  j)                  | j*                         y # t        j                   $ r+}d| _        t%        d|j&                  z  d	       Y d }~`d }~ww xY w#  Y y xY w)
Nr   zcs-backup-lockerz--xidz--termz	--sessionz--debugTz0Could not start screensaver fallback process: %s)flush)r   r   r   pathjoinconfig	pkglibdirr   r   
get_windowget_xidr   rD   r   r   spawn_asyncErrorr   rg   messagedisconnect_by_funcrp   )r*   r   datar   r   argvr   s          r,   rp   z.ScreensaverManager._real_spawn_fallback_window  s    ;;? $ 1 1 3+ GGLL))+=>S..088:;h	
 <<KK	"	^**403DK
	JJ))$*J*JK zz 	^&*D#DqyyPX\]]	^	s$   *C. %D/ .D,!D''D,/D3c                 2   | j                   dk(  r| j                  sy t        d       	 t        d       | j                   dkD  r!t        j                  | j                   d       n| j                  rt        d      	 t        j                  | j                   t&        j(                         d| _        d| _         y # t
        $ r t        d       t        j                  j                  t        d            }|j                  t        d             |j                  t        j                  d	             |j                  t        j                  j                         t        j                   j#                         j%                  d
|       Y w xY w#  Y xY w)Nr   z manager: killing fallback windowz2manager: checking if fallback window exists first.zFallback window failed to startzVmanager: fallback window terminated before the main screensaver, something went wrong!z-Cinnamon Screensaver has experienced an errorzThe 'cs-backup-locker' process terminated before the screensaver did. Please report this issue and try to describe any actions you may have performed prior to this occurring.zdialog-error)namezcinnamon-screensaverF)r   r   r   r   killProcessLookupErrorr   NotificationrC   _set_bodyset_icon
ThemedIconset_priorityNotificationPriorityURGENTrI   rJ   send_notificationsignalSIGTERM)r*   notifications     r,   r4   z'ScreensaverManager.kill_fallback_window-  s?   ;;!D$;$;01	bFG{{QQ'((()JKK	GGDKK0 #(# " 		bjk++//2a0bcL!!! %N #O P !!#..n"EF%%c&>&>&E&EFOO'');;<RT`a		b	s   AB9 <.F 9CFFFc                 x   | j                          | j                  j                  d| j                         | j                  rK| j                  j                          | j                  j                          d| _        | j                          dt        _	        | j                  dd       | j                          y)a<  
        Called after the stage become visible.  All user events are now
        redirected to GrabHelper, our status is updated, our active timer
        is started, and emit an active-changed signal (Which is listened to
        by our ConsoleKit client if we're using it, and our own ScreensaverService.)
        zneeds-refreshNTr   )
grab_stager   r%   queue_refresh_stager   hidedestroy_stagestage_refreshedr   r   emitstart_timersr/   s    r,   rM   z*ScreensaverManager.on_spawn_stage_completeL  s     	

?D,D,DE>>NN!NN((*!DN  "		"D)r-   c                    | j                   j                          | j                   j                          t        j                  dk(  }dt        _        |r| j                  dd       | j                          | j                   j                          d| _         t        j                  rEt        j                         j                          t        j                         j                          yy)zw
        The stage is destroyed, our status
        is updated, timer is canceled and active-changed is fired.
        TFr   N)r   cancel_unlockingr   r   r   r   rj   r   rD   r   r$   dump_connections_listr_   dump_timer_list)r*   
was_actives     r,   rP   z ScreensaverManager.despawn_stagea  s    
 	

##%

]]d*
II&.

  "
 <<$$&<<>&&(88: r-   c                     | j                   R| j                  j                  | j                   j                         t        j
                  j                         d       yy)z
        Makes a hard grab on the Stage window, all keyboard and mouse events are dispatched or eaten
        by us now.
        NT)r   rE   move_to_windowr   r   rF   rJ   r/   s    r,   r   zScreensaverManager.grab_stagey  sF    
 ::!++DJJ,A,A,CSZZE[E[E]`de "r-   c                     | j                   dkD  r&t        j                  | j                          d| _         t        d       t	        j
                  | j                  t        j                        | _         y)z
        Queues a complete refresh of the stage, resizing the screen if necessary,
        reconstructing the individual monitor objects, etc...
        r   zmanager: queuing stage refresh)priorityN)r   r   source_remover   r   idle_add_update_full_stage_on_idlePRIORITY_DEFAULT)r*   r   s     r,   r   z&ScreensaverManager.queue_refresh_stage  sY    
   1$!!$"7"78$%D!./ !%d.M.MX\XmXm nr-   c                     d| _         | j                  rd| _        y t        j                          d| _        | j                          y)Nr   TF)r   r   r   r   r   refresh_stage)r*   r   s     r,   r   z-ScreensaverManager._update_full_stage_on_idle  s;     !??!%D		r-   c                     t        d       | j                          d| _        | j                  r"d| _        t        d       | j	                          | j                          y )Nzmanager: stage refresh completeFz4Got refresh signal while refreshing, doing it again.)r   r   r   r   r   rb   r/   s    r,   r   z"ScreensaverManager.stage_refreshed  sN    /0!&DHI$$&##%r-   c                 X   | j                   yt        d       | j                   j                          | j                          g t        _        | j                  j                          | j                   j                  }| j                   | _	        | j                  || j                         y)a  
        Tells the stage to check its canvas size and make sure its windows are up-to-date.  This is called
        when our login manager tells us its "Active" property has changed.  We are always connected to the
        login manager, so we first check if we have a stage.
        NzStage: refreshing)r   r   r   rj   r   rQ   rE   rO   rk   r   rL   rM   )r*   r   rk   s      r,   r   z ScreensaverManager.refresh_stage  s     ::!"

##%   "zz..t'C'CDr-   c                 V    t        j                          | _        | j                          y)z
        Stamps our current time starts our lock delay timer (the elapsed time to allow after
        activation, to lock the computer.)
        N)rW   r   start_lock_delayr/   s    r,   r   zScreensaverManager.start_timers  s    
 $(99; r-   c                 2    d| _         | j                          y)zU
        Zeros out our activated timestamp and cancels our lock delay timer.
        r   N)r   r9   r/   s    r,   rj   z ScreensaverManager.cancel_timers  s     $% r-   c                 X    | j                          | j                  j                          y)zX
        Return to sleep (not Awake) - hides the pointer and the unlock widget.
        N)r   r   r   r/   s    r,   r   z#ScreensaverManager.cancel_unlocking  s     	

##%r-   c                 <    t        d       | j                  d       y)zJ
        Updates the lock status when our timer has hit its limit
        z+manager: locking after delay ('lock-delay')TF)r   r6   r/   s    r,   on_lock_delay_timeoutz(ScreensaverManager.on_lock_delay_timeout  s     	;<r-   c                 
   t        j                         syt        j                         syt        j                         }|dk(  r| j                          yt        j                         j                  d|| j
                         y)z
        Setup the lock delay timer based on user prefs - if there is
        no delay, or if idle locking isn't enabled, we run the callback
        immediately, or simply return, respectively.
        Nr   idle-lock-delay)	r
   get_idle_lock_enabledr	   r:   get_idle_lock_delayr   r   r_   start_seconds)r*   
lock_delays     r,   r   z#ScreensaverManager.start_lock_delay  sj     --/""$113
?&&(&&(667H7A7;7Q7QSr-   c                 J    t        j                         j                  d       y)z/
        Cancels the lock delay timer.
        r   N)r   r_   rd   r/   s    r,   r9   z"ScreensaverManager.stop_lock_delay  s     	""$++,=>r-   c                 :    | j                   j                  |       y)zL
        Forwards a captured key event to the stage->unlock dialog.
        N)r   queue_dialog_key_event)r*   events     r,   r   z)ScreensaverManager.queue_dialog_key_event  s     	

))%0r-   c                 :    | j                   j                  |       y)z>
        Forwards a tab event to the focus navigator.
        N)r    navigate)r*   shifteds     r,   propagate_tab_eventz&ScreensaverManager.propagate_tab_event  s     	(r-   c                 8    | j                   j                          y)zO
        Forwards an activation event (return) to the focus navigator.
        N)r    activate_focusr/   s    r,   propagate_activationz'ScreensaverManager.propagate_activation	  s     	%%'r-   c                 6    | j                   j                         S )zN
        Returns the currently focused widget from the FocusNavigator
        )r    get_focused_widgetr/   s    r,   r   z%ScreensaverManager.get_focused_widget  s     ~~0022r-   c                 |    t        dt        |      z         |r#t        j                  s| j	                  d       yyy)z
        Call back for the session client - initiates a slow fade-in
        for the stage when the session goes idle.  Cancels the stage fade-in
        if idle becomes False before it has completed its animation.
        z"manager: session idle-changed - %sTN)r   r   r   r   r8   )r*   proxyidles      r,   r&   z*ScreensaverManager.on_session_idle_changed  s2     	2SY>?OOD! &4r-   )rw   )N)+__name__
__module____qualname____doc__r   SignalFlagsRUN_LASTbool__gsignals__r   r0   r6   r=   r?   r8   rT   rX   rb   ra   rL   r3   r   rp   r4   rM   rP   r   r   r   r   r   r   rj   r   r   r   r9   r   r   r   r   r&   __classcell__)r+   s   @r,   r   r      s    
 	7..77xHL-<,0'R$HL!	L%'N6>*;0fo&E* &S*?1)(3	"r-   r   )gi.repositoryr   r   r   r   r   rW   rh   r   r   r~   r   	constantscr   r   r   r!   utilr	   r
   r   util.focusNavigatorr   
util.utilsr   Objectr    r-   r,   <module>r      sJ    @ ?   	        * * . J" J"r-   