summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-10-18 19:23:38 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-10-19 02:46:25 +0900
commita3aa1ed7f047fde6c1e2bb87bd2b7431ef9b7b27 (patch)
tree06d6529bc2697bd04c2bf3dc7abea3574bae9973 /src/modules
parentd17e0d39369b0c6a9dfb596688a38615dd25922d (diff)
ecore-evas - handle mouse out then in due to click-to-focus passive grabs
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/ecore_evas/engines/x/ecore_evas_x.c188
1 files changed, 129 insertions, 59 deletions
diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c
index 7140ca67c8..20ed6e2265 100644
--- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c
+++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c
@@ -54,6 +54,8 @@ struct _Ecore_Evas_Engine_Data_X11 {
54 Ecore_X_Pixmap mask; 54 Ecore_X_Pixmap mask;
55 Ecore_X_GC gc; 55 Ecore_X_GC gc;
56 Ecore_X_XRegion *damages; 56 Ecore_X_XRegion *damages;
57 Ecore_Timer *outdelay;
58 Ecore_X_Event_Mouse_Out out_ev;
57 Ecore_X_Sync_Counter sync_counter; 59 Ecore_X_Sync_Counter sync_counter;
58 Ecore_X_Window leader; 60 Ecore_X_Window leader;
59 Ecore_X_Sync_Counter netwm_sync_counter; 61 Ecore_X_Sync_Counter netwm_sync_counter;
@@ -1036,48 +1038,89 @@ _ecore_evas_x_event_client_message(void *data EINA_UNUSED, int type EINA_UNUSED,
1036} 1038}
1037 1039
1038static Eina_Bool 1040static Eina_Bool
1041_fake_out(void *data)
1042{
1043 Ecore_Evas *ee = data;
1044 Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
1045 Ecore_X_Event_Mouse_Out *e = &(edata->out_ev);
1046
1047 edata->outdelay = NULL;
1048
1049 ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers);
1050 _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
1051 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
1052 evas_event_feed_mouse_cancel(ee->evas, e->time, NULL);
1053 evas_event_feed_mouse_out(ee->evas, e->time, NULL);
1054 if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
1055 if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
1056 ee->in = EINA_FALSE;
1057 return EINA_FALSE;
1058}
1059
1060static Eina_Bool
1039_ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) 1061_ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1040{ 1062{
1041 Ecore_Evas *ee; 1063 Ecore_Evas *ee;
1042 Ecore_X_Event_Mouse_In *e; 1064 Ecore_X_Event_Mouse_In *e;
1065 Ecore_Evas_Engine_Data_X11 *edata;
1043 1066
1044 e = event; 1067 e = event;
1045 ee = ecore_event_window_match(e->win); 1068 ee = ecore_event_window_match(e->win);
1046 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */ 1069 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
1047 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; 1070 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1048/* { */ 1071 edata = ee->engine.data;
1049/* time_t t; */ 1072/*
1050/* char *ct; */ 1073 {
1051 1074 time_t t;
1052/* const char *modes[] = { */ 1075 char *ct;
1053/* "MODE_NORMAL", */ 1076
1054/* "MODE_WHILE_GRABBED", */ 1077 const char *modes[] = {
1055/* "MODE_GRAB", */ 1078 "MODE_NORMAL",
1056/* "MODE_UNGRAB" */ 1079 "MODE_WHILE_GRABBED",
1057/* }; */ 1080 "MODE_GRAB",
1058/* const char *details[] = { */ 1081 "MODE_UNGRAB"
1059/* "DETAIL_ANCESTOR", */ 1082 };
1060/* "DETAIL_VIRTUAL", */ 1083 const char *details[] = {
1061/* "DETAIL_INFERIOR", */ 1084 "DETAIL_ANCESTOR",
1062/* "DETAIL_NON_LINEAR", */ 1085 "DETAIL_VIRTUAL",
1063/* "DETAIL_NON_LINEAR_VIRTUAL", */ 1086 "DETAIL_INFERIOR",
1064/* "DETAIL_POINTER", */ 1087 "DETAIL_NON_LINEAR",
1065/* "DETAIL_POINTER_ROOT", */ 1088 "DETAIL_NON_LINEAR_VIRTUAL",
1066/* "DETAIL_DETAIL_NONE" */ 1089 "DETAIL_POINTER",
1067/* }; */ 1090 "DETAIL_POINTER_ROOT",
1068/* t = time(NULL); */ 1091 "DETAIL_DETAIL_NONE"
1069/* ct = ctime(&t); */ 1092 };
1070/* ct[strlen(ct) - 1] = 0; */ 1093 t = time(NULL);
1071/* printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n", */ 1094 ct = ctime(&t);
1072/* e->win, e->event_win, */ 1095 ct[strlen(ct) - 1] = 0;
1073/* ct, */ 1096 printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n",
1074/* modes[e->mode], */ 1097 e->win, e->event_win,
1075/* details[e->detail]); */ 1098 ct,
1076/* } */ 1099 modes[e->mode],
1100 details[e->detail]);
1101 }
1102 */
1077 // disable. causes more problems than it fixes 1103 // disable. causes more problems than it fixes
1078 // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) || 1104 // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) ||
1079 // (e->mode == ECORE_X_EVENT_MODE_UNGRAB)) 1105 // (e->mode == ECORE_X_EVENT_MODE_UNGRAB))
1080 // return 0; 1106 // return 0;
1107
1108 // handle click to focus passive buton grab side-effects
1109 if ((e->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
1110 (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) &&
1111 (edata->outdelay))
1112 {
1113 ecore_timer_del(edata->outdelay);
1114 edata->outdelay = NULL;
1115 return 0;
1116 }
1117 if (edata->outdelay)
1118 {
1119 ecore_timer_del(edata->outdelay);
1120 edata->outdelay = NULL;
1121 _fake_out(ee);
1122 }
1123
1081 /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */ 1124 /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
1082 if (!ee->in) 1125 if (!ee->in)
1083 { 1126 {
@@ -1095,46 +1138,68 @@ _ecore_evas_x_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void
1095{ 1138{
1096 Ecore_Evas *ee; 1139 Ecore_Evas *ee;
1097 Ecore_X_Event_Mouse_Out *e; 1140 Ecore_X_Event_Mouse_Out *e;
1141 Ecore_Evas_Engine_Data_X11 *edata;
1098 1142
1099 e = event; 1143 e = event;
1100 ee = ecore_event_window_match(e->win); 1144 ee = ecore_event_window_match(e->win);
1101 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; 1145 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1102 /* pass on event */ 1146 /* pass on event */
1103 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; 1147 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1104/* { */ 1148 edata = ee->engine.data;
1105/* time_t t; */ 1149/*
1106/* char *ct; */ 1150 {
1107 1151 time_t t;
1108/* const char *modes[] = { */ 1152 char *ct;
1109/* "MODE_NORMAL", */ 1153
1110/* "MODE_WHILE_GRABBED", */ 1154 const char *modes[] = {
1111/* "MODE_GRAB", */ 1155 "MODE_NORMAL",
1112/* "MODE_UNGRAB" */ 1156 "MODE_WHILE_GRABBED",
1113/* }; */ 1157 "MODE_GRAB",
1114/* const char *details[] = { */ 1158 "MODE_UNGRAB"
1115/* "DETAIL_ANCESTOR", */ 1159 };
1116/* "DETAIL_VIRTUAL", */ 1160 const char *details[] = {
1117/* "DETAIL_INFERIOR", */ 1161 "DETAIL_ANCESTOR",
1118/* "DETAIL_NON_LINEAR", */ 1162 "DETAIL_VIRTUAL",
1119/* "DETAIL_NON_LINEAR_VIRTUAL", */ 1163 "DETAIL_INFERIOR",
1120/* "DETAIL_POINTER", */ 1164 "DETAIL_NON_LINEAR",
1121/* "DETAIL_POINTER_ROOT", */ 1165 "DETAIL_NON_LINEAR_VIRTUAL",
1122/* "DETAIL_DETAIL_NONE" */ 1166 "DETAIL_POINTER",
1123/* }; */ 1167 "DETAIL_POINTER_ROOT",
1124/* t = time(NULL); */ 1168 "DETAIL_DETAIL_NONE"
1125/* ct = ctime(&t); */ 1169 };
1126/* ct[strlen(ct) - 1] = 0; */ 1170 t = time(NULL);
1127/* printf("@@ ->OUT 0x%x 0x%x %s md=%s dt=%s\n", */ 1171 ct = ctime(&t);
1128/* e->win, e->event_win, */ 1172 ct[strlen(ct) - 1] = 0;
1129/* ct, */ 1173 printf("@@ ->OUT 0x%x 0x%x %s md=%s dt=%s\n",
1130/* modes[e->mode], */ 1174 e->win, e->event_win,
1131/* details[e->detail]); */ 1175 ct,
1132/* } */ 1176 modes[e->mode],
1177 details[e->detail]);
1178 }
1179 */
1133 // disable. causes more problems than it fixes 1180 // disable. causes more problems than it fixes
1134 // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) || 1181 // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) ||
1135 // (e->mode == ECORE_X_EVENT_MODE_UNGRAB)) 1182 // (e->mode == ECORE_X_EVENT_MODE_UNGRAB))
1136 // return 0; 1183 // return 0;
1137 /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */ 1184
1185 // click to focus mouse out+in work-around
1186 if ((e->mode == ECORE_X_EVENT_MODE_GRAB) &&
1187 (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR))
1188 {
1189 // defer out handling in case its a "fake" out thanks to click
1190 // to focus (which gets us another out soon after
1191 if (edata->outdelay) ecore_timer_del(edata->outdelay);
1192 edata->out_ev = *e;
1193 edata->outdelay = ecore_timer_add(0.05, _fake_out, ee);
1194 return 0;
1195 }
1196 if (edata->outdelay)
1197 {
1198 ecore_timer_del(edata->outdelay);
1199 edata->outdelay = NULL;
1200 }
1201
1202// if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0;
1138// printf("OUT: ee->in=%i, e->mode=%i, e->detail=%i, dount_count=%i\n", 1203// printf("OUT: ee->in=%i, e->mode=%i, e->detail=%i, dount_count=%i\n",
1139// ee->in, e->mode, e->detail, evas_event_down_count_get(ee->evas)); 1204// ee->in, e->mode, e->detail, evas_event_down_count_get(ee->evas));
1140 if (ee->in) 1205 if (ee->in)
@@ -1675,6 +1740,11 @@ _ecore_evas_x_free(Ecore_Evas *ee)
1675 ecore_event_window_unregister(*winp); 1740 ecore_event_window_unregister(*winp);
1676 free(winp); 1741 free(winp);
1677 } 1742 }
1743 if (edata->outdelay)
1744 {
1745 ecore_timer_del(edata->outdelay);
1746 edata->outdelay = NULL;
1747 }
1678 free(edata); 1748 free(edata);
1679 _ecore_evas_x_shutdown(); 1749 _ecore_evas_x_shutdown();
1680 ecore_x_shutdown(); 1750 ecore_x_shutdown();