
    f*                        d Z ddlmZmZmZ ddlZddlmZmZ ddl	m
Z
  e
        ddlmZmZmZ ddlmZmZ ddlmZ dd	lmZmZ ddlmZ ddlZ ej4                  d
      Z G d de      Z G d d      Z G d d      Z G d de      Z d Z! G d de      Z"d"dZ#d Z$d Z%d Z&d Z'd#dZ(d Z)d"dZ*d$dZ+d Z,d  Z-d! Z.y)%z' Window manipulation and other helpers     )divisionprint_functionunicode_literalsN)sqrtpi)require_gi_versions)GLibGtkGdk)RectVersion)Timer)HandleHandleFunctionWindowUtilsc                   :   e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd2dZd2dZd Zd Zd Zd Zd Zd3dZd Zd Zd4dZd Zd4dZ d4d Z!d! Z"d" Z#d# Z$d$ Z%d% Z&d& Z'd' Z(d( Z)d) Z*d* Z+d+ Z,d, Z-d- Z.d5d.Z/d/ Z0d5d0Z1d1 Z2y)6WindowManipulatoraD  
    Adds resize and move capability to windows.
    Meant for resizing windows without decoration or resize gripper.

    Quirks to remember:

    Keyboard window:
        - Always use threshold when move button was pressed
          in order to support long press to show the touch handles.
        - Never use the threshold for the enlarged touch handles.
          They are only temporarily visible and thus don't need protection.

    IconPalette:
        - Always use threshold when trying to move, otherwise
          clicking to unhide the keyboard window won't work.
    c                    d| _         d| _        d | _        d| _        d| _        d | _        d | _        d | _        d | _        t        j                  | _        d| _        d| _        d| _        d| _        d| _        d | _        d | _        y )N
   Tg      @)2   r   F      )hit_frame_widthdrag_protection_temporary_unlock_timetemporary_unlock_delaymin_window_size_drag_start_pointer_drag_start_offset_drag_start_rect_drag_handler   ALL_drag_handles_drag_active_drag_threshold_drag_snap_threshold_lock_x_axis_lock_y_axis_last_drag_handle_monitor_rectsselfs    5/usr/lib/python3/dist-packages/Onboard/WindowUtils.py__init__zWindowManipulator.__init__<   s    !#&*# '*#'#' #'#'#'#ZZ#(#$$&!$)$)$($(    c                     ||f| _         y Nr   r,   whs      r-   set_min_window_sizez%WindowManipulator.set_min_window_sizeX   s     !1vr/   c                     | j                   S r1   r2   r+   s    r-   get_min_window_sizez%WindowManipulator.get_min_window_size[       ###r/   c                     | j                   S r1   )r   r+   s    r-   get_hit_frame_widthz%WindowManipulator.get_hit_frame_width^   r9   r/   c                     || _         y r1   )r   )r,   enables     r-   enable_drag_protectionz(WindowManipulator.enable_drag_protectiona   s
    %r/   c                     d | _         y r1   )r   r+   s    r-   reset_drag_protectionz'WindowManipulator.reset_drag_protectiond   s
    &*#r/   c                     	 | j                         S # t        $ r- t        dd| j                         | j	                               cY S w xY w)Nr   )get_keyboard_frame_rectAttributeErrorr   get_allocated_widthget_allocated_heightr+   s    r-   get_resize_frame_rectz'WindowManipulator.get_resize_frame_rectg   sN    	5//11 	510021135 5	5s    3AAc                     | j                   S r1   )r    r+   s    r-   get_drag_start_rectz%WindowManipulator.get_drag_start_recto   s    $$$r/   c                     | S r1    r+   s    r-   get_drag_windowz!WindowManipulator.get_drag_windowr       r/   c                     | j                   S r1   r#   r+   s    r-   get_drag_handlesz"WindowManipulator.get_drag_handlesu   s    !!!r/   c                     || _         y r1   rN   )r,   handless     r-   set_drag_handlesz"WindowManipulator.set_drag_handlesx   s
    $r/   c                 "    t         j                  S r1   )r   NORMAL)r,   handles     r-   get_handle_functionz%WindowManipulator.get_handle_function{   s    $$$r/   c                      y)Nr   rJ   r+   s    r-   get_drag_thresholdz$WindowManipulator.get_drag_threshold~   s    r/   c                      y)zA Rectangle in canvas coordinates that must not leave the screen. NrJ   r+   s    r-   get_always_visible_rectz)WindowManipulator.get_always_visible_rect   s    r/   c                     || _         y)z+ Set to False to constraint movement in x. N)r'   r,   locks     r-   lock_x_axiszWindowManipulator.lock_x_axis   
     r/   c                     || _         y)z* Set to True to constraint movement in y. N)r(   r\   s     r-   lock_y_axiszWindowManipulator.lock_y_axis   r_   r/   c                    | j                  |j                        }||t        j                  k(  r| j	                  |j
                         y| j                  ||j
                         | j                  |      }|t        j                  k(  r| j                          y|r<t        j                  | j                         v r| j	                  |j
                         yy)NTF)hit_test_move_resizepointr   MOVEstart_move_window
root_pointstart_resize_windowrV   r   ASPECT_RATIOon_handle_aspect_ratio_pressedrO   )r,   sequencemove_on_backgroundhitfunctions        r-   handle_presszWindowManipulator.handle_press   s    ''7{fkk!&&x':':;  ((h.A.AB33C8~:::779KK40022""8#6#67r/   c                    | j                         sy d}|j                  \  }}|| j                  d   z
  }|| j                  d   z
  }| j                  st	        ||z  ||z  z         }| j
                   }	| j
                  rq| j                  V|| j                  k\  rGd| _        || j                  k\  rd}n.| j                  dxx   |z  cc<   | j                  dxx   |z  cc<   | j                  
d}	nd| _        | xj                  |	z  c_        | j                  r:|r| j                  ||       n| j                  ||||       | j                          y y )NFr      T)is_drag_initiatedrg   r   r$   r   r   r   r%   r&   r   _handle_motion_fallback_handle_motion_systemon_drag_activated)
r,   rk   fallbacksnap_to_cursorx_rooty_rootdxdyddrag_actives
             r-   handle_motionzWindowManipulator.handle_motion   sY   %%'!,,d..q11d..q11   RURU]#A"222K##..6,,,23D/ D555)-//2b82//2b8222:"&K./+, ,,R4**2r>8L ""$ r/   c                    | j                         }|r|j                  \  }}| j                         r+|r
||z
  }||z
  }|j                  d|||j                         y| j                         rS|r'| j                  j                  ||f      s
||z   ||z   }}|j                  | j                  d|||j                         yyy)a  
        Let the window manager do the moving
        This fixes issues like not reaching edges at high move speed
        and not being able to snap off a maximized window.
        Does nothing in force-to-top mode (override redirect or
        type hint "DOCK").
        rq   N)
rK   rg   	is_movingbegin_move_dragtimeis_resizingr    is_point_withinbegin_resize_dragr!   )r,   rz   r{   rw   rk   windowxys           r-   rt   z'WindowManipulator._handle_motion_system   s     %%'&&DAq~~!BABA&&q!Q>!!# "00@@!QH 2vq2v1(():):A)*Ax}}> $ r/   c                 $    | j                          y)z
        Call this when the system drag has ended.
        We need this to kick off the on_drag_done() call for KbdWindow.
        N	stop_dragr+   s    r-   stop_system_dragz"WindowManipulator.stop_system_drag   s    
 	r/   c                    | j                         sy| j                  | j                        }|t        j                  k(  r5| j                  t
        j                  k(  r|dz  }| j                  ||       y| j                  d   |z   | j                  d   z
  }| j                  d   |z   | j                  d   z
  }| j                  t
        j                  k(  rv| j                  r!| j                         j                         d   }| j                  r!| j                         j                         d   }| j                  ||      \  }}d\  }}	n| j!                         \  }
}| j"                  }|j%                         \  }}}}|j'                         \  }}	| j                  t
        j(                  t
        j*                  t
        j,                  fv rt/        |||z
        }| j                  t
        j                  t
        j*                  t
        j0                  fv rt/        |||
z
        }| j                  t
        j2                  t
        j,                  t
        j4                  fv rt7        ||z   ||
z         }| j                  t
        j8                  t
        j0                  t
        j4                  fv rt7        ||	z   ||z         }||||z
  ||z
  f\  }}}}	| j;                  ||||	       y)z, handle dragging for window move and resize Nr   rq   NN)rr   rV   r!   r   ri   r   WESTon_handle_aspect_ratio_motionr   r   re   r'   rK   get_positionr(   limit_positionr8   r    
to_extentsget_sizeNORTH
NORTH_WEST
NORTH_EASTmin
SOUTH_WESTEAST
SOUTH_EASTmaxSOUTH_move_resize)r,   rz   r{   rn   wxwyr   r   r4   r5   wminhminrectx0y0x1y1s                    r-   rs   z)WindowManipulator._handle_motion_fallback   s   %%'++D,=,=>~222  FKK/b..r26))!,r1D4K4KA4NNB))!,r1D4K4KA4NNB  FKK/$$--/<<>qAB$$--/<<>qAB **2r21!1 "557
d,,!%!2BB}}1$$(.(9(9(.(9(9); ; Rd+B$$(.(9(9(.(9(9); ; Rd+B$$(.(9(9(.(9(9); ; R!VR$Y/B$$(.(9(9(.(9(9); ; R!VR$Y/BRVR"W4
1aaAq)r/   c                      y)zk
        Overload this to process start of dragging of
        handles with ASPECT_RATIO function.
        NrJ   r+   s    r-   rj   z0WindowManipulator.on_handle_aspect_ratio_pressed)      
 	r/   c                      y)zi
        Overload this to process motion changes of 
        handles with ASPECT_RATIO function.
        NrJ   )r,   r   r   s      r-   r   z/WindowManipulator.on_handle_aspect_ratio_motion0  r   r/   c                     | j                         }|syd}|s| j                  | j                  |      }|*t        j                  |      }|r|j                  |       yy|j                  d       yz set the mouse cursor N)
get_windowr!   get_drag_cursor_atr   Cursor
set_cursor)r,   rd   allow_drag_cursorsr   cursor_typecursors         r-   set_drag_cursor_atz$WindowManipulator.set_drag_cursor_at7  st    "  (11%8K "ZZ,F!!&)  d#r/   c                 f    | j                         }|sy| j                  |j                  d       yyr   )r   r!   r   )r,   r   s     r-   reset_drag_cursorz#WindowManipulator.reset_drag_cursorJ  s3    "$d# %r/   c                     | j                   }|| j                  |      }||t        j                  k(  r| j	                         rt        j
                  |   S y r1   )r!   rc   r   re   is_drag_activeCURSOR_TYPES)r,   rd   rm   s      r-   r   z$WindowManipulator.get_drag_cursor_atS  sR    ;**513{fkk!T%8%8%:&&s++r/   Nc                 r    | j                  |       t        j                  | _        | j                  | _        y r1   )
start_dragr   re   r!   r)   )r,   rd   s     r-   rf   z#WindowManipulator.start_move_window\  s(    "KK!%!2!2r/   c                 $    | j                          y r1   r   r+   s    r-   stop_move_windowz"WindowManipulator.stop_move_windowa  s    r/   c                 V    | j                  |       || _        | j                  | _        y r1   )r   r!   r)   )r,   rU   rd   s      r-   rh   z%WindowManipulator.start_resize_windowd  s$    "!%!2!2r/   c                 N   d | _         |s-t        j                         }|j                         \  }}}}||f}| j	                         }|j                         \  }}	|| _        |d   |z
  |d   |	z
  g| _        t        j                  |j                         |j                               | _        d| _        | j                         | _        | j                  r:| j                   5t#        j"                         | j                   z
  | j$                  kD  rd | _        | j'                          y )Nr   rq   F)r*   r   get_default_root_windowget_pointerrK   r   r   r   r   from_position_sizer   r    r$   rX   r%   r   r   r   r   on_drag_initiated)
r,   rd   rootwindunnorx   ry   maskr   r   r   s
             r-   r   zWindowManipulator.start_dragi  s   " 113G*1*=*=*?'E664V$E %%'""$1#( #(8a<qA"> $ 7 78K8K8M8>8I!K "  $668 ##**299;444445*.D' 	 r/   c                 &   | j                         r| j                  &| j                  r3 | j                  | j                    nt        j
                         | _        d | _        d | _        d| _        | j                          | j                          y y )NF)rr   r   r   r   r    r   r   r!   r$   move_into_viewon_drag_doner+   s    r-   r   zWindowManipulator.stop_drag  s    !!#**2''%D%%t'<'<= /3iik+&*D# $D %D! # $r/   c                      y)zU
        User controlled drag initiated, but drag hasn't actually begun yet.
        NrJ   r+   s    r-   r   z#WindowManipulator.on_drag_initiated       	r/   c                      y)z,
        Moving/resizing has begun.
        NrJ   r+   s    r-   ru   z#WindowManipulator.on_drag_activated  r   r/   c                      y)zW
        User controlled drag ended.
        overload this in derived classes.
        NrJ   r+   s    r-   r   zWindowManipulator.on_drag_done  r   r/   c                 ,    t        | j                        S )zA Button pressed down on a drag handle, not yet actually dragging )boolr   r+   s    r-   rr   z#WindowManipulator.is_drag_initiated  s    D++,,r/   c                 >    | j                         xr | j                  S )z! Are we actually moving/resizing )rr   r$   r+   s    r-   r   z WindowManipulator.is_drag_active  s    %%'=D,=,==r/   c                 `    | j                         xr | j                  t        j                  k(  S r1   rr   r!   r   re   r+   s    r-   r   zWindowManipulator.is_moving  s%    %%'LD,=,=,LLr/   c                 <    | j                   t        j                  k(  S r1   )r)   r   re   r+   s    r-   
was_movingzWindowManipulator.was_moving  s    %%44r/   c                 `    | j                         xr | j                  t        j                  k7  S r1   r   r+   s    r-   r   zWindowManipulator.is_resizing  s%    %%'MD,=,=&++,MMr/   c                     | j                         }|rF|j                         \  }}| j                  ||      \  }}||k7  s||k7  r| j                  ||       yyy)zu
        If the window has somehow ended up off-screen,
        move the always-visible-rect back into view.
        N)rK   r   r   r   r,   r   r   r   _x_ys         r-   r   z WindowManipulator.move_into_view  sd    
 %%'&&(DAq((A.FBQw"'!!"b) " r/   c                 $    | j                          y r1   )r   r	   idle_add_do_force_into_viewr+   s    r-   force_into_viewz!WindowManipulator.force_into_view  s    r/   c                     | j                         }|j                         \  }}| j                  ||      \  }}||k7  s||k7  r3|j                          | j	                  ||       |j                          yy)z9 Works mostly, but occasionally the window disappears... N)rK   r   r   hider   showr   s         r-   r   z%WindowManipulator._do_force_into_view  sl    %%'""$1$$Q*B7bAgKKMb"%KKM r/   c                 n   | j                         }t        dd|j                         |j                               }|j	                         }|j                         sZ|j                  |j                  kD  r|j                  dz
  |_        |j                  |j                  kD  r|j                  dz
  |_        |S )z?
        Limit the given window rect to fit on screen.
        r   (      )
get_screenr   	get_width
get_heightcopyis_emptyr4   r5   )r,   r   screenlimitsrs        r-   
limit_sizezWindowManipulator.limit_size  s     "aF,,.0A0A0CDIIK ssVXX~hhmssVXX~hhmr/   c                     || j                         }|s6| j                  st        | j                               | _        | j                  }t	        ||||      \  }}||fS )zq
        Limits the given window position to keep the current
        always_visible_rect fully in view.
        )rZ   r*   get_monitor_rectsr   limit_window_position)r,   r   r   visible_rectlimit_rectss        r-   r   z WindowManipulator.limit_position  s`     779L&&&78I&J#--K$Q<E1!tr/   c                    | j                         }| j                         }| j                         }t        |j                  dz  |      }t        |j
                  dz  |      }|\  }}|j                         \  }	}
}}|D ]  }|t        j                  k(  r||	k\  r||	|z   k  r||
k\  r||
|z   k  r|c S |t        j                  k(  r||k  r|||z
  kD  r||
k\  r||
|z   k  r|c S |t        j                  k(  r||k  r|||z
  kD  r||k  r|||z
  kD  r|c S |t        j                  k(  s||	k\  s||	|z   k  s||k  s|||z
  kD  s|c S  |D ]  }|t        j                  k(  r||	|z   k  r||	dz
  k\  r|c S |t        j                  k(  r|||z
  kD  r||dz   k  r|c S |t        j                  k(  r||
|z   k  r|c S |t        j                  k(  s|||z
  kD  s|c S  y )N   rq   )rF   rO   r;   r   r4   r5   r   r   r   r   r   r   r   r   r   r   )r,   rd   canvas_rectrQ   r   r4   r5   r   r   r   r   r   r   rU   s                 r-   rc   z&WindowManipulator.hit_test_move_resize  s   002'')224!?3!?31$//1BB  	"F***7q26z7q26z!M***7q26z7q26z!M***7q26z7q26z!M***7q26z7q26z!M'	",  	"F$rAv:!rAv+!M$rAv:!rAv+!M%rAv:!M%rAv:!M	" r/   c                     | j                         }|j                         }||j                  ||       y t        |d      r|j	                  ||||       y |j	                  ||||       y )Nmove_resize)rK   r   movehasattrr   )r,   r   r   r4   r5   r   gdk_wins          r-   r   zWindowManipulator._move_resize.  sg    %%'##%9
 KK1 v}-""1aA.##Aq!Q/r/   c                    | j                         }|}|}|j                         }|j                         }|d   |j                         kD  r#||j                         k  r|j                         }|d   |d   z   |j	                         k  r)||d   z   |j	                         kD  r|j	                         }|d   |j                         kD  r#||j                         k  r|j                         }|d   |d   z   |j                         k  r)||d   z   |j                         kD  r|j	                         }||k7  s||k7  r|j                  ||       yy)aQ  
        Compiz and potentially other window managers silently ignore
        moves outside of some screen edges. When hitting the edge at
        high speed, onboard gets stuck some distance away from it.
        Fix this by inserting an intermediate move right to the edge.
        Does not help with the edge below unity bar.
        r   rq   N)get_screen_limitsr   r   leftrighttopbottomr   )	r,   r   r   r   r   
one_more_x
one_more_ypossizes	            r-   _insert_edge_movez#WindowManipulator._insert_edge_move@  s&    '')

!!# q6FKKM!FKKM!Jq6DGflln,DGflln,Jq6FJJL FJJL Jq6DGfmmo-DGfmmo-J?jAoKK
J/ .r/   F)Tr1   r   )3__name__
__module____qualname____doc__r.   r6   r8   r;   r>   r@   rF   rH   rK   rO   rR   rV   rX   rZ   r^   ra   ro   r~   rt   r   rs   rj   r   r   r   r   rf   r   rh   r   r   r   ru   r   rr   r   r   r   r   r   r   r   r   r   rc   r   r  rJ   r/   r-   r   r   +   s     )8&$$&+5%"%%!!*-%^>64*l$&$3
3
!B (->M5N
*4
"0d0$0r/   r   c                   8    e Zd ZdZ G d d      Z G d d      Zy)Orientationz enum for screen orientation c                       e Zd Zy)Orientation.LANDSCAPENr  r  r	  rJ   r/   r-   	LANDSCAPEr  b      r/   r  c                       e Zd Zy)Orientation.PORTRAITNr  rJ   r/   r-   PORTRAITr  c  r  r/   r  N)r  r  r	  r
  r  r  rJ   r/   r-   r  r  _  s    'r/   r  c                   p    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zy)WindowRectTrackera  
    Keeps track of the window rectangle when moving/resizing.
    Gtk only updates the position and size asynchrounously on
    configure events and hidden windows return invalid values.
    Auto-show et al need valid values from get_position and
    get_size at all times.
    c                 <    d | _         d | _        d| _        d| _        y )Nr   r   F)_window_rect_origin_client_offset_override_redirectr+   s    r-   r.   zWindowRectTracker.__init__n  s!     $"'r/   c                      y r1   rJ   r+   s    r-   cleanupzWindowRectTracker.cleanupt  s    r/   c                    | j                         }|rzt        j                  j                  |       }t        j                  j	                  |       }| j                         j                         }t        |      dk(  r|dd }t        j                  t        j                        r&t        j                  dj                  |||             | j                  |      }t        j                   ||      | _        || _        |d   |d   z
  |d   |d   z
  f| _        | j)                         | _        t        j                  t        j                        r;t        j                  dj                  || j&                  | j*                               yyy)zw
        Call this on configure event, the only time when
        get_position, get_size, etc. can be trusted.
           rq   Nz/update_window_rect1: pos {}, size {}, origin {}r   zDupdate_window_rect2: pos {}, client_offset {}, screen_orientation {})
is_visibler
   Windowr   r   r   
get_originlen_loggerisEnabledForloggingDEBUGdebugformat_apply_window_scaling_factorr   r   r  r  r  get_screen_orientation_screen_orientation)r,   visibler  r  origins        r-   update_window_rectz$WindowRectTracker.update_window_rectw  sG   
 //#::**40C::&&t,D__&113F6{a##GMM2O &dF3533C8C $ 7 7T BD!DL#)!9s1v#5vay3q67I"JD'+'B'B'DD$##GMM2 6%vc&*&9&9&*&>&> @A 3# r/   c                 F    t         j                  j                  | ||       y r1   )r
   r"  r   )r,   r   r   s      r-   r   zWindowRectTracker.move  s    

a#r/   c                 F    t         j                  j                  | ||       y r1   )r
   r"  resizer3   s      r-   r3  zWindowRectTracker.resize  s    

$1%r/   c                 R    | j                         }|r|j                  ||||       y y r1   )r   r   )r,   r   r   r4   r5   wins         r-   r   zWindowRectTracker.move_resize  s(    ooOOAq!Q' r/   c                     | j                   2t        j                  j                  |       }| j	                  |      }|S | j                   j                         }|S r1   )r  r
   r"  r   r+  )r,   r  s     r-   r   zWindowRectTracker.get_position  sT    $**))$/C33C8C 
 ##002C
r/   c                     | j                   t        j                  j                  |       S | j                   j                         S r1   )r  r
   r"  r   r+   s    r-   r   zWindowRectTracker.get_size  s8    $::&&t,,$$--//r/   c                     | j                   8| j                         }|r%|j                         }t        |      dk(  r|dd  }|S y| j                   S )Nr   rq   r   )r  r   r#  r$  )r,   r5  r/  s      r-   r#  zWindowRectTracker.get_origin  sP    <<//#C)v;!##ABZF<<r/   c                     | j                   S r1   )r  r+   s    r-   get_client_offsetz#WindowRectTracker.get_client_offset  s    """r/   c                     | j                   S r1   )r  r+   s    r-   get_rectzWindowRectTracker.get_rect  s       r/   c                     | j                   S r1   )r  r+   s    r-   get_override_redirectz'WindowRectTracker.get_override_redirect  s    &&&r/   c                 P    || _         | j                         j                  d       y )NT)r  r   set_override_redirect)r,   values     r-   r@  z'WindowRectTracker.set_override_redirect  s    "'//5r/   c                 h    | j                         }|r	 |j                         S y # t        $ r Y y w xY wr1   )r   get_scale_factorrC   )r,   r   s     r-   rC  z"WindowRectTracker.get_scale_factor  sA    //#//11  " s   % 	11c                 l    | j                   r'| j                         }|d|z  }|d   |z  |d   |z  f}|S )zR
        Gdk doesn't scale position of override redirect windows (Trusty)
              ?r   rq   )r  rC  )r,   valuesscales      r-   r+  z.WindowRectTracker._apply_window_scaling_factor  sJ     ""))+E=e )e+VAY->?r/   c                     | j                         }|j                         |j                         k\  rt        j                  S t        j
                  S )a  
        Current orientation of the screen (tablet rotation).
        Only the aspect ratio is taken into account at this time.
        This appears to cover more cases than looking at monitor rotation,
        in particular with multi-monitor screens.
        )r   r   r   r  r  r  r,   r   s     r-   r,  z(WindowRectTracker.get_screen_orientation  sB     "!2!2!44((('''r/   N)r  r  r	  r
  r.   r  r0  r   r3  r   r   r   r#  r:  r<  r>  r@  rC  r+  r,  rJ   r/   r-   r  r  f  sX    (A<$&(
0
 #!'6	(r/   r  c                   b    e Zd Z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y	)WindowRectPersistz4
    Save and restore window position and size.
    c                     t         j                  |        d | _        t               | _        | j                         }|j                  d| j                         y )Nzsize-changed)r  r.   r-  r   _save_position_timerr   connecton_screen_size_changedrI  s     r-   r.   zWindowRectPersist.__init__  sD    ""4(#' $)G! "~t'B'BCr/   c                 8    | j                   j                          y r1   )rM  finishr+   s    r-   r  zWindowRectPersist.cleanup  s    !!((*r/   c                 @    t         j                  j                  |       S )z! This is overloaded in KbdWindow )r
   r"  get_visibler+   s    r-   r!  zWindowRectPersist.is_visible  s    zz%%d++r/   c                 2    t        d| j                  |       y)z! detect screen rotation (tablets)g      ?N)r   on_screen_size_changed_delayedrI  s     r-   rO  z(WindowRectPersist.on_screen_size_changed  s     	c466?r/   c                 $    | j                          y r1   )restore_window_rectrI  s     r-   rU  z0WindowRectPersist.on_screen_size_changed_delayed  s      "r/   c                    | j                   j                          | j                         }| j                  |      }|| _        || _        t        j                  dj                  ||             | j                  |      }|| _        |rM| j                  |j                  |j                         | j                  |j                  |j                         n<| j!                  |j                  |j                  |j                  |j                         |r@|j#                         | _        |j%                         | _        | j                         | _        yy)z3
        Restore window size and position.
        z)restore_window_rect {rect}, {orientation}r   orientationN)rM  rQ  r,  read_window_rectr-  r  r%  r)  r*  on_restore_window_rectset_default_sizer4   r5   r   r   r   r   r   left_topr  )r,   startuprZ  r   s       r-   rW  z%WindowRectPersist.restore_window_rect	  s    	!!((*113$$[1#.  AvTvE	G
 **40   !!$&&$&&1IIdffdff%TVVTVVTVVTVV<
  $		D $DL'+'B'B'DD$	 r/   c                     |S r1   rJ   r,   r   s     r-   r\  z(WindowRectPersist.on_restore_window_rect1  rL   r/   Nc                     || j                   }|| j                  }| j                  |      }| j                  ||       t        j                  dj                  ||             y)z0
        Save window size and position.
        Nz&save_window_rect {rect}, {orientation}rY  )r-  r  on_save_window_rectwrite_window_rectr%  r)  r*  r,   rZ  r   s      r-   save_window_rectz"WindowRectPersist.save_window_rect4  se     22K<$$D ''-{D1>v4[vA	Cr/   c                     |S r1   rJ   ra  s     r-   rc  z%WindowRectPersist.on_save_window_rectF  rL   r/   c                     t               )z\
        Read orientation dependent rect.
        Overload this in derived classes.
        NotImplementedErrorre  s      r-   r[  z"WindowRectPersist.read_window_rectI      
 "##r/   c                     t               )z]
        Write orientation dependent rect.
        Overload this in derived classes.
        ri  re  s      r-   rd  z#WindowRectPersist.write_window_rectP  rk  r/   c                     | j                   j                  d| j                  | j                         | j	                                y)z
        Trigger saving position and size to gsettings
        Delay this a few seconds to avoid excessive disk writes.

        Remember the current rect and rotation as the screen may have been
        rotated when the saving happens.
           N)rM  startrf  r,  r<  r+   s    r-   start_save_position_timerz+WindowRectPersist.start_save_position_timerW  s8     	!!''(,(=(=(,(C(C(E(,	9r/   c                 8    | j                   j                          y r1   )rM  stopr+   s    r-   stop_save_position_timerz*WindowRectPersist.stop_save_position_timerd  s    !!&&(r/   r  r   )r  r  r	  r
  r.   r  r!  rO  rU  rW  r\  rf  rc  r[  rd  rp  rs  rJ   r/   r-   rK  rK    sM    D+,@#&EPC$$$9)r/   rK  c                     | j                         }|rCt        |d      r6|j                         }t        j                         j                  |dd       yyy)a-  
    Set custom X window property to tell unity 3D this is an on-screen
    keyboard that wants to be raised on top of dash. See LP 739812, 915250.
    Since onboard started detecting dash itself this isn't really needed
    for unity anymore. Leave it anyway, it may come in handy in the future.
    get_xidONSCREEN_KEYBOARDrq   N)r   r   ru  oskUtilset_x_property)r   r   xids      r-   set_unity_propertyr{  h  sN     !G7I&//#CHHJ%%c+>B ' r/   c                   >    e Zd ZdZdZdZd Zd Zd Zd Z	d
dZ
d	 Zy)DwellProgress   NrE  c                     | j                   d uS r1   dwell_start_timer+   s    r-   is_dwellingzDwellProgress.is_dwelling  s    $$D00r/   c                 ^    t        j                          | j                  | j                  z   kD  S r1   )r   r  dwell_delayr+   s    r-   is_donezDwellProgress.is_done  s$    yy{T22T5E5EEEEr/   c                 6    t        j                          | _        y r1   )r   r  r+   s    r-   start_dwellingzDwellProgress.start_dwelling  s     $		r/   c                     d | _         y r1   r  r+   s    r-   stop_dwellingzDwellProgress.stop_dwelling  s
     $r/   c                    | j                         r| j                  dk  r	 | j                  dk\  r| j                  ||||       y |j                           |j                  |j                           |j                          |j                          | j                  ||||       |j                          |j                  | j                         |j                          y y )Ng        rE  )r  opacity_draw_dwell_progresssave	rectangleintclip
push_grouppop_group_to_sourcepaint_with_alpharestore)r,   contextr   rgbargba_bgs        r-   drawzDwellProgress.draw  s    ||s"||s"))'4wG!!!488:.""$))'4wG++-((6! r/   c                    |j                         \  }}t        |j                  |j                        dz  }t         dz  }t        j
                         | j                  z
  | j                  z  }	t        |	d      }	|	t        z  dz  }
|r] |j                  |  |j                  ||       |j                  |||ddt        z         |j                          |j                          |j                  ||       |j                  ||||||
z          |j                           |j                  |  |j                          |j                  dddd       |j                  d       |j                          y )Ng       @rE  r   r   rq   )
get_centerr   r4   r5   r   r   r  r  set_source_rgbamove_toarc
close_pathfillfill_preserveset_line_widthstroke)r,   r  r   r  r  xcycradiusalpha0kalphas              r-   r  z"DwellProgress._draw_dwell_progress  s7   __&FB(3.FS3YFt4448H8HHAAsAFSLE'''1B'BFAq2v6""$OOB#KKB? #G##T*!!###Aq!Q/""1%NNr/   ))rq   r   r   g      ?N)r  r  r	  r  r  r  r  r  r  r  r  r  rJ   r/   r-   r}  r}  v  s5     K G1F,%"$r/   r}  c                 |   |}||j                         }|j                         }|xj                  | z  c_        |xj                  |z  c_        d}d}|D ].  }|j                         }	t	        |	j                  |j                               |	_        t        |	j                  |j                         |	j                  z
        |	_        t	        |	j                  |j                               |	_        t        |	j                  |j                         |	j                  z
        |	_        |	j                         \  }
}|j                  |	j                  z
  |j                  |	j                  z
  }}||z  ||z  z   }|||k  s+|}|	}1 |j                  |j                  z
  } |j                  |j                  z
  }| |fS )z]
    Limits the given window position to keep the
    always_visible_rect fully in view.
    N)r  r   r   r   r   r   r   r   r4   r   r   r5   r  )r   r   always_visible_rectr   r   rsdminrsminr   rsccxcyrz   r{   r|   s                  r-   r   r     s]    	A}EEG VVX
	
	! 	F'')Cv{{}-CEv||~56CEvzz|,CEv}}67CE ^^%FBTTCEE\244#%%<BR"r'!A|q4x	  GGaccMGGaccMa4Kr/   c           	         g }| rvt        | j                               D ]X  }| j                  |      }|j                  t	        |j
                  |j                  |j                  |j                               Z |S t        j                         }t	        j                  |j                         |j                         |j                         f      }|j                  |       |S )zv
    Screen limits, one rect per monitor. Monitors may have
    different sizes and arbitrary relative positions.
    )rangeget_n_monitorsget_monitor_geometryappendr   r   r   widthheightr   r   r   r   r   r   )r   rectsir   r   s        r-   r   r     s    
 Ev,,./ 	<A++A.ALLacc133:;	< L	 --/##G$8$8$:!(!2!2!4g6H6H6J KMQLr/   c                 J   | j                         }|r|j                  |j                  |j                        \  }}|j                  |j                  |j                  z   |j                  |j
                  z         \  }}t        j                  ||||      }|S t               }|S )zH
    Convert rect in canvas coordinates to root window coordinates.
    )r   get_root_coordsr   r   r4   r5   r   from_extents)r   r   r   r   r   r   r   s          r-   canvas_to_root_window_rectr    s     !G((8B(($&&)-$&&:B  RR0 K vKr/   c                 ^    | j                         }|r |j                  | }|S  |dd       |S )zI
    Convert point in canvas coordinates to root window coordinates.
    r   )r   r  )r   rd   r   s      r-   canvas_to_root_window_pointr    s>     !G'''/ L 	aLr/   c                 8   | j                         }| j                         }|rx|rv|j                  |      }|j                  |      }|j                  |j
                  f}|j                  |      |j                  |      f}d}|dk(  rd}||fS |dk(  rd}d}||fS y)z6 Geometry and physical size of the monitor at window. Nr   r  rq   )i   i   )   ^   )r  r  )r   r   get_monitor_at_windowr  r  r  get_monitor_width_mmget_monitor_height_mm)r   r   r   monitorr   r  size_mmdevices           r-   get_monitor_dimensionsr    s    !G F6..w7''0"..w7//8: Q;G
 W}	 q[DGW}r/   c                     t        |       \  }}|d   dkD  rR|d   dkD  rJ|d   dkD  rB|d   dkD  r:|d   r|d   |d   z  |d   z  n|d   }|d   r|d   |d   z  |d   z  n|d   }||fS |\  }}||fS )zG
    Convert a physical size in mm to pixels of windows's monitor,
    r   rq   )r  )r   r  fallback_sizeszsz_mmr4   r5   s          r-   physical_to_monitor_pixel_sizer  &  s     'v.IB	!uqyRUQYQx!|a1Qx qEGAJq)*1- 	
 Qx qEGAJq)*1- 	
 a4K 1a4Kr/   c                     t        j                  t         j                  j                  | t         j                  j
                        }|j                          |j                          y)z Show an error dialog )message_typemessage_formatbuttonsN)r
   MessageDialogMessageTypeERRORButtonsTypeOKrundestroy)error_string	error_dlgs     r-   show_error_dialogr  5  sG     !!s/D/D1=*-//*<*<>I MMOr/   c                 ,   t        j                  t         j                  j                  t         j                  j
                        |rj                  |       j                  |        t        j                         }|j                  dfd       j                         j                  |       j                          j                         }|t         j                  j                  k(  r|j!                         nd }j#                          |S )N)r  r  activatec                 V    j                  t        j                  j                        S r1   )responser
   ResponseTyper  )eventquestion_dialogs    r-   <lambda>z(show_ask_string_dialog.<locals>.<lambda>E  s"      !1!1!4!45 r/   )r
   r  r  QUESTIONr  	OK_CANCELset_transient_for
set_markupEntryrN  get_message_areaaddshow_allr  r  r  get_textr  )questionparententryr  textr  s        @r-   show_ask_string_dialogr  >  s    ''S__5M5M030I0IKO))&1x(IIKE	MM* 6 7$$&**51""$H'3+;+;+>+>>5>>DDKr/   c                    |t        d      }t        j                  t        j                  j                  | |t        j
                  j                        }|r|j                  |       |r)|j                  t        j                  j                         |j                         }|j                          |t        j                  j                  k(  S )zG
    Show this dialog to ask confirmation before executing a task.
    Onboard)r  r  titler  )_r
   r  r  r  r  YES_NOr  set_positionWindowPositionCENTERr  r  r  YES)r  r  centerr  dlgr  s         r-   show_confirmation_dialogr  N  s     })


)A)A!)"'$'OO$:$:<C f%++223wwyHKKMs''++++r/   c                    t        j                  t         j                  j                  t	        d      t	        d            }|r?|j                  t        j                  dt         j                  j                               n>|j                  t        j                  dt         j                  j                               dj                  |       }|t	        d      z  }|j                  |       |j                  t	        d	      t         j                  j                         |j                  t	        d
      t         j                  j                        j                          |j!                  dt"        ||       |j%                          y)z+
    Show a "New Input Device" dialog.
    zNew Input Devicez'Onboard has detected a new input device)r  r  r  zinput-mouse)	icon_name	icon_sizezinput-keyboardz<i>{}</i>

z5Do you want to use this device for keyboard scanning?_Cancelz
Use devicer  N)r
   r  r  OTHERr  	set_imageImageIconSizeDIALOGr*  format_secondary_markup
add_buttonr  CANCELACCEPTgrab_defaultrN   _show_new_device_dialog_responser  )nameconfig_string
is_pointercallbackdialog	secondarys         r-   show_new_device_dialogr  c  s*    COO,A,A%&'9%:$%&O$PRF ]-0\\-@-@B 	C 	-=-0\\-@-@B 	C !''-IJKKI
""9- a	lC$4$4$;$;<
aos'7'7'>'>?LLN
NN:?],
OOr/   c                 n    |t         j                  j                  k(  r ||       | j                          y)z- Callback for the "New Input Device" dialog. N)r
   r  r  r  )r  r  r  r  s       r-   r  r  ~  s(    3##***
NNr/   c                  p    t        t        j                  t        j                        } | t        dd      k  S )z% Gtk from 3.14 removes resize grips. r      )r   r
   MAJOR_VERSIONMINOR_VERSION)gtk_versions    r-   gtk_has_resize_grip_supportr    s+    #++S->->?KB''r/   r1   )r  )NFN)/r
  
__future__r   r   r   r   mathr   r   Onboard.Versionr   gi.repositoryr	   r
   r   Onboard.utilsr   r   Onboard.Timerr   Onboard.definitionsr   r   Onboard.oskrw  r'  	getLoggerr%  objectr   r  r  rK  r{  r}  r   r   r  r  r  r  r  r  r  r  r  r  rJ   r/   r-   <module>r&     s   ( . A A   /   ( ( '  6  
'

M
*q0 q0h @( @(F|)) |)~CBF BJ&P"	0 ,*6(r/   