@ -134,8 +134,6 @@ struct window {
struct widget * widget ;
struct widget * widget ;
struct widget * focus_widget ;
struct widget * focus_widget ;
uint32_t widget_grab_button ;
struct window * menu ;
struct window * menu ;
void * user_data ;
void * user_data ;
@ -166,6 +164,9 @@ struct input {
int32_t x , y , sx , sy ;
int32_t x , y , sx , sy ;
struct wl_list link ;
struct wl_list link ;
struct widget * grab ;
uint32_t grab_button ;
struct wl_data_device * data_device ;
struct wl_data_device * data_device ;
struct data_offer * drag_offer ;
struct data_offer * drag_offer ;
struct data_offer * selection_offer ;
struct data_offer * selection_offer ;
@ -190,6 +191,7 @@ struct frame {
struct menu {
struct menu {
struct window * window ;
struct window * window ;
struct widget * widget ;
struct widget * widget ;
struct input * input ;
const char * * entries ;
const char * * entries ;
uint32_t time ;
uint32_t time ;
int current ;
int current ;
@ -1349,13 +1351,6 @@ frame_motion_handler(struct widget *widget,
return frame_get_pointer_image_for_location ( data , input ) ;
return frame_get_pointer_image_for_location ( data , input ) ;
}
}
static void
break_grab ( struct window * window )
{
window - > focus_widget = NULL ;
window - > widget_grab_button = 0 ;
}
static void
static void
frame_button_handler ( struct widget * widget ,
frame_button_handler ( struct widget * widget ,
struct input * input , uint32_t time ,
struct input * input , uint32_t time ,
@ -1378,7 +1373,7 @@ frame_button_handler(struct widget *widget,
if ( ! window - > shell_surface )
if ( ! window - > shell_surface )
break ;
break ;
input_set_pointer_image ( input , time , POINTER_DRAGGING ) ;
input_set_pointer_image ( input , time , POINTER_DRAGGING ) ;
break_grab ( window ) ;
input_ungrab ( input , time ) ;
wl_shell_surface_move ( window - > shell_surface ,
wl_shell_surface_move ( window - > shell_surface ,
input_get_input_device ( input ) ,
input_get_input_device ( input ) ,
time ) ;
time ) ;
@ -1393,7 +1388,7 @@ frame_button_handler(struct widget *widget,
case WINDOW_RESIZING_BOTTOM_RIGHT :
case WINDOW_RESIZING_BOTTOM_RIGHT :
if ( ! window - > shell_surface )
if ( ! window - > shell_surface )
break ;
break ;
break_grab ( window ) ;
input_ungrab ( input , time ) ;
wl_shell_surface_resize ( window - > shell_surface ,
wl_shell_surface_resize ( window - > shell_surface ,
input_get_input_device ( input ) ,
input_get_input_device ( input ) ,
time , location ) ;
time , location ) ;
@ -1436,7 +1431,7 @@ static void
window_set_focus_widget ( struct window * window , struct widget * focus ,
window_set_focus_widget ( struct window * window , struct widget * focus ,
struct input * input , uint32_t time , int32_t x , int32_t y )
struct input * input , uint32_t time , int32_t x , int32_t y )
{
{
struct widget * old ;
struct widget * old , * widget ;
int pointer = POINTER_LEFT_PTR ;
int pointer = POINTER_LEFT_PTR ;
if ( focus = = window - > focus_widget )
if ( focus = = window - > focus_widget )
@ -1444,15 +1439,22 @@ window_set_focus_widget(struct window *window, struct widget *focus,
old = window - > focus_widget ;
old = window - > focus_widget ;
if ( old ) {
if ( old ) {
if ( old - > leave_handler )
widget = old ;
old - > leave_handler ( old , input , old - > user_data ) ;
if ( input - > grab )
widget = input - > grab ;
if ( widget - > leave_handler )
widget - > leave_handler ( old , input , widget - > user_data ) ;
window - > focus_widget = NULL ;
window - > focus_widget = NULL ;
}
}
if ( focus ) {
if ( focus ) {
if ( focus - > enter_handler )
widget = focus ;
pointer = focus - > enter_handler ( focus , input , time ,
if ( input - > grab )
x , y , focus - > user_data ) ;
widget = input - > grab ;
if ( widget - > enter_handler )
pointer = widget - > enter_handler ( focus , input , time ,
x , y ,
widget - > user_data ) ;
window - > focus_widget = focus ;
window - > focus_widget = focus ;
input_set_pointer_image ( input , time , pointer ) ;
input_set_pointer_image ( input , time , pointer ) ;
@ -1474,19 +1476,44 @@ input_handle_motion(void *data, struct wl_input_device *input_device,
input - > sx = sx ;
input - > sx = sx ;
input - > sy = sy ;
input - > sy = sy ;
if ( ! window - > focus_widget | | ! window - > widget_ grab_button) {
if ( ! ( input - > grab & & input - > grab_button ) ) {
widget = widget_find_widget ( window - > widget , sx , sy ) ;
widget = widget_find_widget ( window - > widget , sx , sy ) ;
window_set_focus_widget ( window , widget , input , time , sx , sy ) ;
window_set_focus_widget ( window , widget , input , time , sx , sy ) ;
}
}
widget = window - > focus_widget ;
if ( input - > grab )
widget = input - > grab ;
else
widget = window - > focus_widget ;
if ( widget & & widget - > motion_handler )
if ( widget & & widget - > motion_handler )
pointer = widget - > motion_handler ( widget , input , time , sx , sy ,
pointer = widget - > motion_handler ( window - > focus_widget ,
input , time , sx , sy ,
widget - > user_data ) ;
widget - > user_data ) ;
input_set_pointer_image ( input , time , pointer ) ;
input_set_pointer_image ( input , time , pointer ) ;
}
}
void
input_grab ( struct input * input , struct widget * widget , uint32_t button )
{
input - > grab = widget ;
input - > grab_button = button ;
}
void
input_ungrab ( struct input * input , uint32_t time )
{
struct widget * widget ;
input - > grab = NULL ;
if ( input - > pointer_focus ) {
widget = widget_find_widget ( input - > pointer_focus - > widget ,
input - > sx , input - > sy ) ;
window_set_focus_widget ( input - > pointer_focus , widget ,
input , time , input - > sx , input - > sy ) ;
}
}
static void
static void
input_handle_button ( void * data ,
input_handle_button ( void * data ,
struct wl_input_device * input_device ,
struct wl_input_device * input_device ,
@ -1496,24 +1523,18 @@ input_handle_button(void *data,
struct window * window = input - > pointer_focus ;
struct window * window = input - > pointer_focus ;
struct widget * widget ;
struct widget * widget ;
if ( window - > focus_widget & & window - > widget_ grab_button = = 0 & & state )
if ( window - > focus_widget & & input - > grab = = NULL & & state )
window - > widget_grab_button = button ;
input_grab ( input , window - > focus_widget , button ) ;
widget = window - > focus_widget ;
widget = window - > focus_widget ;
if ( widget & & widget - > button_handler )
if ( widget & & widget - > button_handler )
( * widget - > button_handler ) ( widget ,
( * input - > grab - > button_handler ) ( widget ,
input , time ,
input , time ,
button , state ,
button , state ,
widget - > user_data ) ;
input - > grab - > user_data ) ;
if ( window - > focus_widget & &
if ( input - > grab & & input - > grab_button = = button & & ! state )
window - > widget_grab_button = = button & & ! state ) {
input_ungrab ( input , time ) ;
window - > widget_grab_button = 0 ;
widget = widget_find_widget ( window - > widget ,
input - > sx , input - > sy ) ;
window_set_focus_widget ( window , widget , input , time ,
input - > sx , input - > sy ) ;
}
}
}
static void
static void
@ -1554,7 +1575,7 @@ input_remove_pointer_focus(struct input *input, uint32_t time)
if ( ! window )
if ( ! window )
return ;
return ;
window_set_focus_widget ( window , NULL , NULL , 0 , 0 , 0 ) ;
window_set_focus_widget ( window , NULL , input , 0 , 0 , 0 ) ;
input - > pointer_focus = NULL ;
input - > pointer_focus = NULL ;
input - > current_pointer_image = POINTER_UNSET ;
input - > current_pointer_image = POINTER_UNSET ;
@ -2051,11 +2072,15 @@ static void
handle_popup_done ( void * data , struct wl_shell_surface * shell_surface )
handle_popup_done ( void * data , struct wl_shell_surface * shell_surface )
{
{
struct window * window = data ;
struct window * window = data ;
struct menu * menu = window_get_user_data ( window ) ;
struct menu * menu = window - > widget - > user_data ;
/* FIXME: Need more context in this event, at least the input
/* FIXME: Need more context in this event, at least the input
* device . Or just use wl_callback . */
* device . Or just use wl_callback . And this really needs to
* be a window vfunc that the menu can set . And we need the
* time . */
menu - > func ( window - > parent , menu - > current , window - > parent - > user_data ) ;
menu - > func ( window - > parent , menu - > current , window - > parent - > user_data ) ;
input_ungrab ( menu - > input , 0 ) ;
window_destroy ( window ) ;
window_destroy ( window ) ;
}
}
@ -2294,7 +2319,7 @@ window_create_transient(struct display *display, struct window *parent,
return window ;
return window ;
}
}
static int
static void
menu_set_item ( struct menu * menu , int sy )
menu_set_item ( struct menu * menu , int sy )
{
{
int next ;
int next ;
@ -2304,8 +2329,6 @@ menu_set_item(struct menu *menu, int sy)
menu - > current = next ;
menu - > current = next ;
widget_schedule_redraw ( menu - > widget ) ;
widget_schedule_redraw ( menu - > widget ) ;
}
}
return POINTER_LEFT_PTR ;
}
}
static int
static int
@ -2313,7 +2336,12 @@ menu_motion_handler(struct widget *widget,
struct input * input , uint32_t time ,
struct input * input , uint32_t time ,
int32_t x , int32_t y , void * data )
int32_t x , int32_t y , void * data )
{
{
return menu_set_item ( data , y ) ;
struct menu * menu = data ;
if ( widget = = menu - > widget )
menu_set_item ( data , y ) ;
return POINTER_LEFT_PTR ;
}
}
static int
static int
@ -2321,13 +2349,21 @@ menu_enter_handler(struct widget *widget,
struct input * input , uint32_t time ,
struct input * input , uint32_t time ,
int32_t x , int32_t y , void * data )
int32_t x , int32_t y , void * data )
{
{
return menu_set_item ( data , y ) ;
struct menu * menu = data ;
if ( widget = = menu - > widget )
menu_set_item ( data , y ) ;
return POINTER_LEFT_PTR ;
}
}
static void
static void
menu_leave_handler ( struct widget * widget , struct input * input , void * data )
menu_leave_handler ( struct widget * widget , struct input * input , void * data )
{
{
menu_set_item ( data , - 200 ) ;
struct menu * menu = data ;
if ( widget = = menu - > widget )
menu_set_item ( data , - 200 ) ;
}
}
static void
static void
@ -2338,11 +2374,13 @@ menu_button_handler(struct widget *widget,
{
{
struct menu * menu = data ;
struct menu * menu = data ;
/* Either relase after press-drag-release or click-motion-click. */
if ( state = = 0 & & time - menu - > time > 500 ) {
if ( state = = 0 & & time - menu - > time > 500 ) {
/* Either relase after press-drag-release or
* click - motion - click . */
menu - > func ( menu - > window - > parent ,
menu - > func ( menu - > window - > parent ,
menu - > current , menu - > window - > parent - > user_data ) ;
menu - > current , menu - > window - > parent - > user_data ) ;
window_destroy ( widget - > window ) ;
input_ungrab ( input , time ) ;
window_destroy ( menu - > widget - > window ) ;
}
}
}
}
@ -2409,8 +2447,10 @@ window_create_menu(struct display *display,
menu - > widget = window_add_widget ( menu - > window , menu ) ;
menu - > widget = window_add_widget ( menu - > window , menu ) ;
menu - > entries = entries ;
menu - > entries = entries ;
menu - > count = count ;
menu - > count = count ;
menu - > current = - 1 ;
menu - > time = time ;
menu - > time = time ;
menu - > func = func ;
menu - > func = func ;
menu - > input = input ;
window - > type = TYPE_MENU ;
window - > type = TYPE_MENU ;
window - > x = x ;
window - > x = x ;
window - > y = y ;
window - > y = y ;
@ -2426,6 +2466,8 @@ window_create_menu(struct display *display,
widget_set_motion_handler ( menu - > widget , menu_motion_handler ) ;
widget_set_motion_handler ( menu - > widget , menu_motion_handler ) ;
widget_set_button_handler ( menu - > widget , menu_button_handler ) ;
widget_set_button_handler ( menu - > widget , menu_button_handler ) ;
input_grab ( input , menu - > widget , 0 ) ;
return window ;
return window ;
}
}