2005-06-07 06:05:18 -07:00
/*
* vim : ts = 8 : sw = 3 : sts = 8 : noexpandtab : cino = > 5 n - 3f 0 ^ - 2 { 2
*/
# include "e.h"
/* local subsystem functions */
2005-06-11 23:50:34 -07:00
typedef struct _E_Winlist_Win E_Winlist_Win ;
struct _E_Winlist_Win
{
Evas_Object * bg_object ;
Evas_Object * icon_object ;
E_Border * border ;
} ;
static void _e_winlist_size_adjust ( void ) ;
static void _e_winlist_border_add ( E_Border * bd , E_Zone * zone , E_Desk * desk ) ;
static void _e_winlist_border_del ( E_Border * bd ) ;
static void _e_winlist_activate_nth ( int n ) ;
static void _e_winlist_activate ( void ) ;
static void _e_winlist_deactivate ( void ) ;
static void _e_winlist_show_active ( void ) ;
static int _e_winlist_cb_event_border_add ( void * data , int type , void * event ) ;
static int _e_winlist_cb_event_border_remove ( void * data , int type , void * event ) ;
static int _e_winlist_cb_key_down ( void * data , int type , void * event ) ;
static int _e_winlist_cb_key_up ( void * data , int type , void * event ) ;
2005-06-07 06:05:18 -07:00
/* local subsystem globals */
2005-06-07 06:53:27 -07:00
static E_Popup * winlist = NULL ;
2005-06-11 23:50:34 -07:00
static Evas_Object * bg_object = NULL ;
static Evas_Object * list_object = NULL ;
2005-06-12 09:22:06 -07:00
static Evas_Object * icon_object = NULL ;
2005-06-11 23:50:34 -07:00
static Evas_List * wins = NULL ;
static Evas_List * win_selected = NULL ;
static int hold_count = 0 ;
static int hold_mod = 0 ;
static Evas_List * handlers = NULL ;
static Ecore_X_Window input_window = 0 ;
/* FIXME: gfx are UGLY. theyare test gfx and nothng more atm */
/* FIXME: support optional warp pointer to window */
/* FIXME: add mouse downa nd up handlers and pass events to bindings from them incase mouse binding starst winlist */
2005-06-12 09:22:06 -07:00
/* FIXME: can fix mouse in/out after pop down of ui by disabling al lcrossing event masks on borders and desktop, hide, then re-enable. if mouse is in a border fake a mouse in to make events work :) */
2005-06-07 06:05:18 -07:00
/* externally accessible functions */
int
e_winlist_init ( void )
{
return 1 ;
}
int
e_winlist_shutdown ( void )
{
2005-06-07 06:53:27 -07:00
e_winlist_hide ( ) ;
2005-06-07 06:05:18 -07:00
return 1 ;
}
2005-06-11 23:50:34 -07:00
int
2005-06-07 06:53:27 -07:00
e_winlist_show ( E_Zone * zone )
{
int x , y , w , h ;
Evas_Object * o ;
2005-06-11 23:50:34 -07:00
Evas_List * l ;
E_Desk * desk ;
E_Border * bd ;
2005-06-07 06:53:27 -07:00
2005-06-11 23:50:34 -07:00
if ( winlist ) return 0 ;
2005-06-07 06:53:27 -07:00
2005-06-11 23:50:34 -07:00
/* FIXME: sizes/pos should be config */
2005-06-07 06:53:27 -07:00
w = zone - > w / 2 ;
2005-06-11 23:50:34 -07:00
if ( w > 320 ) w = 320 ;
2005-06-07 06:53:27 -07:00
h = zone - > h / 2 ;
if ( h > 800 ) h = 800 ;
else if ( h < 400 ) h = 400 ;
2005-06-11 23:50:34 -07:00
x = ( zone - > w - w ) / 2 ;
y = ( zone - > h - h ) / 2 ;
2005-06-07 06:53:27 -07:00
winlist = e_popup_new ( zone , x , y , w , h ) ;
if ( ! winlist ) return ;
e_popup_layer_set ( winlist , 255 ) ;
2005-06-11 23:50:34 -07:00
evas_event_freeze ( winlist - > evas ) ;
2005-06-07 06:53:27 -07:00
o = edje_object_add ( winlist - > evas ) ;
2005-06-11 23:50:34 -07:00
bg_object = o ;
2005-06-07 06:53:27 -07:00
e_theme_edje_object_set ( o , " base/theme/winlist " ,
" widgets/winlist/main " ) ;
evas_object_move ( o , 0 , 0 ) ;
evas_object_resize ( o , w , h ) ;
evas_object_show ( o ) ;
e_popup_edje_bg_object_set ( winlist , o ) ;
2005-06-11 23:50:34 -07:00
o = e_box_add ( winlist - > evas ) ;
list_object = o ;
e_box_align_set ( o , 0.5 , 0.0 ) ;
e_box_orientation_set ( o , 0 ) ;
e_box_homogenous_set ( o , 1 ) ;
edje_object_part_swallow ( bg_object , " list_swallow " , o ) ;
2005-06-12 09:22:06 -07:00
edje_object_part_text_set ( bg_object , " title_text " , _ ( " Select a window " ) ) ;
2005-06-11 23:50:34 -07:00
evas_object_show ( o ) ;
desk = e_desk_current_get ( winlist - > zone ) ;
e_box_freeze ( list_object ) ;
for ( l = e_border_focus_stack_get ( ) ; l ; l = l - > next )
{
E_Border * bd ;
bd = l - > data ;
_e_winlist_border_add ( bd , winlist - > zone , desk ) ;
}
e_box_thaw ( list_object ) ;
bd = e_border_focused_get ( ) ;
if ( bd ) e_border_focus_set ( bd , 0 , 0 ) ;
_e_winlist_activate_nth ( 0 ) ;
evas_event_thaw ( winlist - > evas ) ;
_e_winlist_size_adjust ( ) ;
input_window = ecore_x_window_input_new ( zone - > container - > win , 0 , 0 , 1 , 1 ) ;
ecore_x_window_show ( input_window ) ;
ecore_x_pointer_grab ( input_window ) ;
ecore_x_keyboard_grab ( input_window ) ;
handlers = evas_list_append
( handlers , ecore_event_handler_add
( E_EVENT_BORDER_ADD , _e_winlist_cb_event_border_add , NULL ) ) ;
handlers = evas_list_append
( handlers , ecore_event_handler_add
( E_EVENT_BORDER_REMOVE , _e_winlist_cb_event_border_remove , NULL ) ) ;
handlers = evas_list_append
( handlers , ecore_event_handler_add
( ECORE_X_EVENT_KEY_DOWN , _e_winlist_cb_key_down , NULL ) ) ;
handlers = evas_list_append
( handlers , ecore_event_handler_add
( ECORE_X_EVENT_KEY_UP , _e_winlist_cb_key_up , NULL ) ) ;
2005-06-07 06:53:27 -07:00
e_popup_show ( winlist ) ;
2005-06-11 23:50:34 -07:00
return 1 ;
2005-06-07 06:53:27 -07:00
}
void
e_winlist_hide ( void )
{
if ( ! winlist ) return ;
2005-06-11 23:50:34 -07:00
2005-06-12 09:22:06 -07:00
/* FIXME: ensure whatever window is selected is focused after we finish cleanup - seee above for fix to mouse enter events */
2005-06-11 23:50:34 -07:00
evas_event_freeze ( winlist - > evas ) ;
2005-06-07 06:53:27 -07:00
e_popup_hide ( winlist ) ;
2005-06-11 23:50:34 -07:00
e_box_freeze ( list_object ) ;
while ( wins )
{
E_Winlist_Win * ww ;
ww = wins - > data ;
evas_object_del ( ww - > bg_object ) ;
2005-06-12 09:22:06 -07:00
if ( ww - > icon_object ) evas_object_del ( ww - > icon_object ) ;
2005-06-11 23:50:34 -07:00
free ( ww ) ;
wins = evas_list_remove_list ( wins , wins ) ;
}
2005-06-12 09:22:06 -07:00
if ( icon_object )
{
evas_object_del ( icon_object ) ;
icon_object = NULL ;
}
2005-06-11 23:50:34 -07:00
e_box_thaw ( list_object ) ;
win_selected = NULL ;
evas_object_del ( list_object ) ;
list_object = NULL ;
evas_object_del ( bg_object ) ;
bg_object = NULL ;
evas_event_thaw ( winlist - > evas ) ;
2005-06-07 06:53:27 -07:00
e_object_del ( E_OBJECT ( winlist ) ) ;
winlist = NULL ;
2005-06-11 23:50:34 -07:00
hold_count = 0 ;
hold_mod = 0 ;
while ( handlers )
{
ecore_event_handler_del ( handlers - > data ) ;
handlers = evas_list_remove_list ( handlers , handlers ) ;
}
ecore_x_window_del ( input_window ) ;
input_window = 0 ;
2005-06-07 06:53:27 -07:00
}
void
e_winlist_next ( void )
{
2005-06-11 23:50:34 -07:00
_e_winlist_deactivate ( ) ;
win_selected = win_selected - > next ;
if ( ! win_selected ) win_selected = wins ;
_e_winlist_show_active ( ) ;
_e_winlist_activate ( ) ;
2005-06-07 06:53:27 -07:00
}
void
e_winlist_prev ( void )
{
2005-06-11 23:50:34 -07:00
_e_winlist_deactivate ( ) ;
win_selected = win_selected - > prev ;
if ( ! win_selected ) win_selected = evas_list_last ( wins ) ;
_e_winlist_show_active ( ) ;
_e_winlist_activate ( ) ;
2005-06-07 06:53:27 -07:00
}
void
e_winlist_modifiers_set ( int mod )
{
2005-06-11 23:50:34 -07:00
hold_mod = mod ;
hold_count = 0 ;
if ( hold_mod & ECORE_X_MODIFIER_SHIFT ) hold_count + + ;
if ( hold_mod & ECORE_X_MODIFIER_CTRL ) hold_count + + ;
if ( hold_mod & ECORE_X_MODIFIER_ALT ) hold_count + + ;
if ( hold_mod & ECORE_X_MODIFIER_WIN ) hold_count + + ;
}
/* local subsystem functions */
static void
_e_winlist_size_adjust ( void )
{
Evas_Coord mw , mh ;
int x , y , w , h ;
e_box_freeze ( list_object ) ;
e_box_min_size_get ( list_object , & mw , & mh ) ;
edje_extern_object_min_size_set ( list_object , mw , mh ) ;
edje_object_part_swallow ( bg_object , " list_swallow " , list_object ) ;
edje_object_size_min_calc ( bg_object , & mw , & mh ) ;
edje_extern_object_min_size_set ( list_object , - 1 , - 1 ) ;
e_box_thaw ( list_object ) ;
/* FIXME: sizes/pos should be config */
w = winlist - > zone - > w / 2 ;
if ( w > 320 ) w = 320 ;
h = mh ;
if ( h > 800 ) h = 800 ;
x = ( winlist - > zone - > w - w ) / 2 ;
y = ( winlist - > zone - > h - h ) / 2 ;
evas_object_resize ( bg_object , w , h ) ;
e_popup_move_resize ( winlist , x , y , w , h ) ;
}
static void
_e_winlist_border_add ( E_Border * bd , E_Zone * zone , E_Desk * desk )
{
if ( ( bd - > zone ) & &
( bd - > zone = = zone ) & &
( ( bd - > desk = = desk ) | | ( bd - > sticky ) ) )
{
E_Winlist_Win * ww ;
Evas_Coord mw , mh ;
Evas_Object * o ;
ww = calloc ( 1 , sizeof ( E_Winlist_Win ) ) ;
if ( ! ww ) return ;
ww - > border = bd ;
wins = evas_list_append ( wins , ww ) ;
o = edje_object_add ( winlist - > evas ) ;
ww - > bg_object = o ;
e_theme_edje_object_set ( o , " base/theme/winlist " ,
" widgets/winlist/item " ) ;
if ( bd - > client . netwm . name )
edje_object_part_text_set ( o , " title_text " , bd - > client . netwm . name ) ;
else if ( bd - > client . icccm . title )
edje_object_part_text_set ( o , " title_text " , bd - > client . icccm . title ) ;
evas_object_show ( o ) ;
2005-06-12 09:22:06 -07:00
if ( edje_object_part_exists ( ww - > bg_object , " icon_swallow " ) )
{
o = e_border_icon_add ( bd , winlist - > evas ) ;
ww - > icon_object = o ;
edje_object_part_swallow ( ww - > bg_object , " icon_swallow " , o ) ;
evas_object_show ( o ) ;
}
2005-06-11 23:50:34 -07:00
edje_object_size_min_calc ( ww - > bg_object , & mw , & mh ) ;
e_box_pack_end ( list_object , ww - > bg_object ) ;
e_box_pack_options_set ( ww - > bg_object ,
1 , 1 , /* fill */
1 , 0 , /* expand */
0.5 , 0.5 , /* align */
mw , mh , /* min */
9999 , mh /* max */
) ;
}
}
static void
_e_winlist_border_del ( E_Border * bd )
{
Evas_List * l ;
for ( l = wins ; l ; l = l - > next )
{
E_Winlist_Win * ww ;
ww = l - > data ;
if ( ww - > border = = bd )
{
evas_object_del ( ww - > bg_object ) ;
2005-06-12 09:22:06 -07:00
if ( ww - > icon_object ) evas_object_del ( ww - > icon_object ) ;
2005-06-11 23:50:34 -07:00
free ( ww ) ;
wins = evas_list_remove_list ( wins , l ) ;
return ;
}
}
}
static void
_e_winlist_activate_nth ( int n )
{
Evas_List * l ;
_e_winlist_deactivate ( ) ;
l = evas_list_nth_list ( wins , n ) ;
if ( l )
{
win_selected = l ;
_e_winlist_show_active ( ) ;
_e_winlist_activate ( ) ;
}
}
static void
_e_winlist_activate ( void )
{
E_Winlist_Win * ww ;
2005-06-12 09:22:06 -07:00
Evas_Object * o ;
2005-06-11 23:50:34 -07:00
if ( ! win_selected ) return ;
ww = win_selected - > data ;
edje_object_signal_emit ( ww - > bg_object , " active " , " " ) ;
e_border_raise ( ww - > border ) ;
e_border_focus_set ( ww - > border , 1 , 1 ) ;
2005-06-12 09:22:06 -07:00
if ( ww - > border - > client . netwm . name )
edje_object_part_text_set ( bg_object , " title_text " , ww - > border - > client . netwm . name ) ;
else if ( ww - > border - > client . icccm . title )
edje_object_part_text_set ( bg_object , " title_text " , ww - > border - > client . icccm . title ) ;
if ( icon_object )
{
evas_object_del ( icon_object ) ;
icon_object = NULL ;
}
if ( edje_object_part_exists ( bg_object , " icon_swallow " ) )
{
o = e_border_icon_add ( ww - > border , winlist - > evas ) ;
icon_object = o ;
edje_object_part_swallow ( bg_object , " icon_swallow " , o ) ;
evas_object_show ( o ) ;
}
2005-06-11 23:50:34 -07:00
edje_object_signal_emit ( bg_object , " active " , " " ) ;
}
static void
_e_winlist_deactivate ( void )
{
E_Winlist_Win * ww ;
if ( ! win_selected ) return ;
ww = win_selected - > data ;
2005-06-12 09:22:06 -07:00
if ( icon_object )
{
evas_object_del ( icon_object ) ;
icon_object = NULL ;
}
edje_object_part_text_set ( bg_object , " title_text " , " " ) ;
2005-06-11 23:50:34 -07:00
edje_object_signal_emit ( ww - > bg_object , " passive " , " " ) ;
e_border_focus_set ( ww - > border , 0 , 0 ) ;
}
static void
_e_winlist_show_active ( void )
{
/* FIXME: scroll so the selected win is visible */
}
static int
_e_winlist_cb_event_border_add ( void * data , int type , void * event )
{
E_Event_Border_Add * ev ;
ev = event ;
_e_winlist_border_add ( ev - > border , winlist - > zone ,
e_desk_current_get ( winlist - > zone ) ) ;
_e_winlist_size_adjust ( ) ;
}
static int
_e_winlist_cb_event_border_remove ( void * data , int type , void * event )
{
E_Event_Border_Remove * ev ;
ev = event ;
_e_winlist_border_del ( ev - > border ) ;
_e_winlist_size_adjust ( ) ;
}
static int
_e_winlist_cb_key_down ( void * data , int type , void * event )
{
Ecore_X_Event_Key_Down * ev ;
ev = event ;
if ( ev - > win ! = input_window ) return 1 ;
if ( ! strcmp ( ev - > keysymbol , " Up " ) )
e_winlist_prev ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " Down " ) )
e_winlist_next ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " Left " ) )
e_winlist_prev ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " Right " ) )
e_winlist_next ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " Return " ) )
e_winlist_hide ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " space " ) )
e_winlist_hide ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " Escape " ) )
e_winlist_hide ( ) ;
else if ( ! strcmp ( ev - > keysymbol , " 1 " ) )
_e_winlist_activate_nth ( 0 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 2 " ) )
_e_winlist_activate_nth ( 1 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 3 " ) )
_e_winlist_activate_nth ( 2 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 4 " ) )
_e_winlist_activate_nth ( 3 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 5 " ) )
_e_winlist_activate_nth ( 4 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 6 " ) )
_e_winlist_activate_nth ( 5 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 7 " ) )
_e_winlist_activate_nth ( 6 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 8 " ) )
_e_winlist_activate_nth ( 7 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 9 " ) )
_e_winlist_activate_nth ( 8 ) ;
else if ( ! strcmp ( ev - > keysymbol , " 0 " ) )
_e_winlist_activate_nth ( 9 ) ;
else
e_bindings_key_down_event_handle ( E_BINDING_CONTEXT_WINLIST ,
E_OBJECT ( winlist - > zone ) , ev ) ;
return 1 ;
}
static int
_e_winlist_cb_key_up ( void * data , int type , void * event )
{
Ecore_X_Event_Key_Up * ev ;
ev = event ;
if ( ev - > win ! = input_window ) return 1 ;
if ( hold_mod )
{
if ( ( hold_mod & ECORE_X_MODIFIER_SHIFT ) & & ( ! strcmp ( ev - > keysymbol , " Shift_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_SHIFT ) & & ( ! strcmp ( ev - > keysymbol , " Shift_R " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_CTRL ) & & ( ! strcmp ( ev - > keysymbol , " Control_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_CTRL ) & & ( ! strcmp ( ev - > keysymbol , " Control_R " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_ALT ) & & ( ! strcmp ( ev - > keysymbol , " Alt_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_ALT ) & & ( ! strcmp ( ev - > keysymbol , " Alt_R " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_ALT ) & & ( ! strcmp ( ev - > keysymbol , " Meta_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_ALT ) & & ( ! strcmp ( ev - > keysymbol , " Meta_R " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_ALT ) & & ( ! strcmp ( ev - > keysymbol , " Super_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_ALT ) & & ( ! strcmp ( ev - > keysymbol , " Super_R " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_WIN ) & & ( ! strcmp ( ev - > keysymbol , " Super_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_WIN ) & & ( ! strcmp ( ev - > keysymbol , " Super_R " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_WIN ) & & ( ! strcmp ( ev - > keysymbol , " Mode_switch " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_WIN ) & & ( ! strcmp ( ev - > keysymbol , " Meta_L " ) ) ) hold_count - - ;
else if ( ( hold_mod & ECORE_X_MODIFIER_WIN ) & & ( ! strcmp ( ev - > keysymbol , " Meta_R " ) ) ) hold_count - - ;
if ( hold_count < = 0 )
{
e_winlist_hide ( ) ;
return 1 ;
}
}
e_bindings_key_up_event_handle ( E_BINDING_CONTEXT_WINLIST ,
E_OBJECT ( winlist - > zone ) , ev ) ;
return 1 ;
2005-06-07 06:53:27 -07:00
}