diff options
| author | Joakim Verona | 2013-04-04 19:01:31 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-04-04 19:01:31 +0200 |
| commit | 73423aa260a3fcecacd452fad876fcbc018bd578 (patch) | |
| tree | 387460519532c764769690816cff9e1f44b29049 | |
| parent | 39667649e3bcf9b9de7b70ee7dd2df7bfb9ac972 (diff) | |
| download | emacs-73423aa260a3fcecacd452fad876fcbc018bd578.tar.gz emacs-73423aa260a3fcecacd452fad876fcbc018bd578.zip | |
lots of work on a new event propagation strategy that seems to work for simple widgets but not webkit
| -rw-r--r-- | lisp/xwidget-test.el | 3 | ||||
| -rw-r--r-- | src/xwidget.c | 198 |
2 files changed, 157 insertions, 44 deletions
diff --git a/lisp/xwidget-test.el b/lisp/xwidget-test.el index a8c280352ad..ba434f3d79a 100644 --- a/lisp/xwidget-test.el +++ b/lisp/xwidget-test.el | |||
| @@ -70,7 +70,8 @@ | |||
| 70 | 70 | ||
| 71 | (xwidget-demo "a-webkit-osr" | 71 | (xwidget-demo "a-webkit-osr" |
| 72 | (xwidget-insert (point-min) 'webkit-osr "webkit-osr" 1000 1000) | 72 | (xwidget-insert (point-min) 'webkit-osr "webkit-osr" 1000 1000) |
| 73 | (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic)) | 73 | (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic) |
| 74 | (xwidget-webkit-goto-uri (xwidget-at 1) "http://www.fsf.org")) | ||
| 74 | 75 | ||
| 75 | (xwidget-demo "a-xwgir" | 76 | (xwidget-demo "a-xwgir" |
| 76 | (xwidget-insert (point-min) 'xwgir "xwgir" 1000 1000) | 77 | (xwidget-insert (point-min) 'xwgir "xwgir" 1000 1000) |
diff --git a/src/xwidget.c b/src/xwidget.c index f3394cd7f11..e0747e7da7a 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -186,7 +186,8 @@ xwgir_event_callback (GtkWidget *widget, | |||
| 186 | gpointer user_data); | 186 | gpointer user_data); |
| 187 | 187 | ||
| 188 | GtkWidget* xwgir_create(char* class, char* namespace); | 188 | GtkWidget* xwgir_create(char* class, char* namespace); |
| 189 | 189 | static void | |
| 190 | send_xembed_ready_event (struct xwidget* xw, int xembedid); | ||
| 190 | DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 7, 0, | 191 | DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 7, 0, |
| 191 | doc: /* xw */ | 192 | doc: /* xw */ |
| 192 | ) | 193 | ) |
| @@ -237,7 +238,11 @@ DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 7, 0, | |||
| 237 | xw->widget_osr = xwgir_create( SDATA(Fcar(Fcdr(Fget(xw->type, Qcxwgir_class)))), | 238 | xw->widget_osr = xwgir_create( SDATA(Fcar(Fcdr(Fget(xw->type, Qcxwgir_class)))), |
| 238 | SDATA(Fcar(Fget(xw->type, Qcxwgir_class)))); | 239 | SDATA(Fcar(Fget(xw->type, Qcxwgir_class)))); |
| 239 | 240 | ||
| 240 | 241 | ///debug xwgir | |
| 242 | /* gdk_offscreen_window_set_embedder ( gtk_widget_get_window (xw->widget_osr), */ | ||
| 243 | /* gtk_widget_get_window (GTK_WIDGET (xw->widgetwindow_osr)) */ | ||
| 244 | /* ); */ | ||
| 245 | /// | ||
| 241 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height); | 246 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height); |
| 242 | gtk_container_add (xw->widgetwindow_osr, xw->widget_osr); | 247 | gtk_container_add (xw->widgetwindow_osr, xw->widget_osr); |
| 243 | 248 | ||
| @@ -282,6 +287,16 @@ DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 7, 0, | |||
| 282 | 287 | ||
| 283 | } | 288 | } |
| 284 | 289 | ||
| 290 | if (EQ(xw->type, Qsocket_osr)) { | ||
| 291 | printf ("xwid:%d socket id:%x %d\n", | ||
| 292 | xw, | ||
| 293 | gtk_socket_get_id (GTK_SOCKET (xw->widget_osr)), | ||
| 294 | gtk_socket_get_id (GTK_SOCKET (xw->widget_osr))); | ||
| 295 | send_xembed_ready_event (xw, | ||
| 296 | gtk_socket_get_id (GTK_SOCKET (xw->widget_osr))); | ||
| 297 | //gtk_widget_realize(xw->widget); | ||
| 298 | } | ||
| 299 | |||
| 285 | 300 | ||
| 286 | unblock_input(); | 301 | unblock_input(); |
| 287 | 302 | ||
| @@ -316,36 +331,6 @@ DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 7, 0, | |||
| 316 | 331 | ||
| 317 | /* } */ | 332 | /* } */ |
| 318 | 333 | ||
| 319 | |||
| 320 | /* //////////////////////////////////////////////////////// */ | ||
| 321 | /* if(Fget(xw->type, Qcxwgir_class) != Qnil){ */ | ||
| 322 | /* //here we have run out of hard coded symbols, we will now attempt to create */ | ||
| 323 | /* //a widget dynamically */ | ||
| 324 | /* //TODO */ | ||
| 325 | /* // - support OSR */ | ||
| 326 | /* // - support constructor args */ | ||
| 327 | /* // - support signals */ | ||
| 328 | /* // - check that the argument widget type actually exists */ | ||
| 329 | |||
| 330 | /* //mostly the same as for webkit, so TODO refactor */ | ||
| 331 | /* printf("init xwgir osr\n"); */ | ||
| 332 | /* block_input(); */ | ||
| 333 | /* xw->widgetwindow_osr = GTK_CONTAINER (gtk_offscreen_window_new ()); */ | ||
| 334 | /* gtk_window_resize( GTK_WINDOW(xw->widgetwindow_osr), xw->width, xw->height); */ | ||
| 335 | /* ////////////////////////////// */ | ||
| 336 | /* //create the xwgir widget */ | ||
| 337 | /* printf("xwgir symbol %s %s %s:\n", */ | ||
| 338 | /* SDATA(SYMBOL_NAME(xw->type)), */ | ||
| 339 | /* SDATA(Fcar(Fcdr(Fget(xw->type, Qcxwgir_class)))), */ | ||
| 340 | /* SDATA(Fcar(Fget(xw->type, Qcxwgir_class)))); */ | ||
| 341 | /* //xv->widget = xwgir_create ("Button"); */ | ||
| 342 | /* Fcar(Fget(xw->type, Qcxwgir_class)); */ | ||
| 343 | /* xw->widget_osr = xwgir_create( SDATA(Fcar(Fcdr(Fget(xw->type, Qcxwgir_class)))), */ | ||
| 344 | /* SDATA(Fcar(Fget(xw->type, Qcxwgir_class)))); */ | ||
| 345 | /* gtk_widget_add_events(xw->widget_osr, */ | ||
| 346 | /* GDK_BUTTON_PRESS_MASK */ | ||
| 347 | /* | GDK_BUTTON_RELEASE_MASK */ | ||
| 348 | /* | GDK_POINTER_MOTION_MASK); */ | ||
| 349 | 334 | ||
| 350 | /* ////////////////////////////// */ | 335 | /* ////////////////////////////// */ |
| 351 | /* gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height); */ | 336 | /* gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height); */ |
| @@ -663,6 +648,8 @@ xwidget_osr_draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) | |||
| 663 | 648 | ||
| 664 | GtkWidget* xwgir_create_debug; | 649 | GtkWidget* xwgir_create_debug; |
| 665 | 650 | ||
| 651 | |||
| 652 | |||
| 666 | gboolean | 653 | gboolean |
| 667 | xwidget_osr_event_forward (GtkWidget *widget, | 654 | xwidget_osr_event_forward (GtkWidget *widget, |
| 668 | GdkEvent *event, | 655 | GdkEvent *event, |
| @@ -671,17 +658,29 @@ xwidget_osr_event_forward (GtkWidget *widget, | |||
| 671 | /* copy events that arrive at the outer widget to the offscreen widget */ | 658 | /* copy events that arrive at the outer widget to the offscreen widget */ |
| 672 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); | 659 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); |
| 673 | GdkEvent* eventcopy = gdk_event_copy(event); | 660 | GdkEvent* eventcopy = gdk_event_copy(event); |
| 661 | //GdkEvent* eventcopy = gdk_event_new(GDK_BUTTON_PRESS); | ||
| 662 | |||
| 674 | 663 | ||
| 675 | //((GdkEventAny*)eventcopy)->window = gtk_widget_get_window(xw->widget_osr); | 664 | //((GdkEventAny*)eventcopy)->window = gtk_widget_get_window(xw->widget_osr); |
| 676 | //((GdkEventAny*)eventcopy)->window = xw->widgetwindow_osr; | 665 | //eventcopy->any.window = gtk_widget_get_window(GTK_WIDGET (xw->widgetwindow_osr)); |
| 677 | //((GdkEventAny*)eventcopy)->window = gtk_widget_get_window(xwgir_create_debug); | 666 | //((GdkEventAny*)eventcopy)->window = gtk_widget_get_window(xwgir_create_debug); |
| 678 | eventcopy->any.window = gtk_widget_get_window(xw->widget_osr);//gtk_widget_get_window(xwgir_create_debug); | 667 | eventcopy->any.window = gtk_widget_get_window(xw->widget_osr);//gtk_widget_get_window(xwgir_create_debug); |
| 679 | //eventcopy->send_event = TRUE; | 668 | //eventcopy->any.window = gtk_button_get_event_window(GTK_BUTTON(xw->widget_osr));//gtk_widget_get_window(xwgir_create_debug); |
| 669 | //eventcopy->button.x=200; eventcopy->button.y=200; | ||
| 670 | //event->button.button = GDK_BUTTON_PRIMARY; //debug | ||
| 671 | |||
| 672 | //eventcopy->any.window = xw->widgetwindow_osr;//gtk_widget_get_window(xwgir_create_debug); | ||
| 673 | /* eventcopy->any.send_event = TRUE; */ | ||
| 674 | /* eventcopy->button.time = GDK_CURRENT_TIME; */ | ||
| 675 | /* eventcopy->button.device = event->button.device; */ | ||
| 676 | |||
| 677 | |||
| 680 | printf("xwidget_osr_event_forward redirect event to window:%d\n", ((GdkEventAny*)eventcopy)->window); | 678 | printf("xwidget_osr_event_forward redirect event to window:%d\n", ((GdkEventAny*)eventcopy)->window); |
| 681 | printf("A type:%d x:%d y:%d \n", event->type, event->button.x, event->button.y); | 679 | printf("A type:%d x:%f y:%f \n", event->type, event->button.x, event->button.y); |
| 682 | printf("B type:%d x:%d y:%d \n", eventcopy->type, eventcopy->button.x, eventcopy->button.y); | 680 | printf("B type:%d x:%f y:%f \n", eventcopy->type, eventcopy->button.x, eventcopy->button.y); |
| 683 | //gtk_button_get_event_window(xwgir_create_debug); | 681 | //gtk_button_get_event_window(xwgir_create_debug); |
| 684 | gtk_main_do_event(eventcopy); //TODO this will leak events. they should be deallocated later, perhaps in xwgir_event_callback | 682 | gtk_main_do_event(eventcopy); //TODO this will leak events. they should be deallocated later, perhaps in xwgir_event_callback |
| 683 | //printf("gtk_widget_event:%d\n",gtk_widget_event(xw->widget_osr, eventcopy)); | ||
| 685 | //gdk_event_put(eventcopy); | 684 | //gdk_event_put(eventcopy); |
| 686 | //gdk_event_queue_append(eventcopy); | 685 | //gdk_event_queue_append(eventcopy); |
| 687 | //gdk_event_free(eventcopy); | 686 | //gdk_event_free(eventcopy); |
| @@ -689,7 +688,6 @@ xwidget_osr_event_forward (GtkWidget *widget, | |||
| 689 | //return FALSE; //dont propagate this event furter | 688 | //return FALSE; //dont propagate this event furter |
| 690 | } | 689 | } |
| 691 | 690 | ||
| 692 | |||
| 693 | gboolean | 691 | gboolean |
| 694 | xwgir_event_callback (GtkWidget *widget, | 692 | xwgir_event_callback (GtkWidget *widget, |
| 695 | GdkEvent *event, | 693 | GdkEvent *event, |
| @@ -878,8 +876,81 @@ DEFUN ("xwgir-call-method", Fxwgir_call_method, Sxwgir_call_method, 3, 3, | |||
| 878 | return Qt; | 876 | return Qt; |
| 879 | } | 877 | } |
| 880 | 878 | ||
| 879 | void | ||
| 880 | to_child (GtkWidget *bin, | ||
| 881 | double widget_x, | ||
| 882 | double widget_y, | ||
| 883 | double *x_out, | ||
| 884 | double *y_out) | ||
| 885 | { | ||
| 886 | *x_out = widget_x; | ||
| 887 | *y_out = widget_y; | ||
| 888 | } | ||
| 889 | |||
| 890 | |||
| 891 | void | ||
| 892 | offscreen_window_from_parent (GdkWindow *window, | ||
| 893 | double parent_x, | ||
| 894 | double parent_y, | ||
| 895 | double *offscreen_x, | ||
| 896 | double *offscreen_y, | ||
| 897 | GtkWidget *bin) | ||
| 898 | { | ||
| 899 | /* printf("offscreen_window_from_parent %d %f,%f %f,%f\n", */ | ||
| 900 | /* window, */ | ||
| 901 | /* parent_x, */ | ||
| 902 | /* parent_y, */ | ||
| 903 | /* offscreen_x, */ | ||
| 904 | /* offscreen_y ); */ | ||
| 905 | to_child (bin, parent_x, parent_y, offscreen_x, offscreen_y); | ||
| 906 | } | ||
| 907 | |||
| 908 | GdkWindow * | ||
| 909 | pick_offscreen_child (GdkWindow *offscreen_window, | ||
| 910 | double widget_x, | ||
| 911 | double widget_y, | ||
| 912 | GdkWindow *bin) | ||
| 913 | { | ||
| 914 | //in this simple case we assume the window contains a single widget. easy. | ||
| 915 | //but then we get the problem that the widget cant be embedded in several windows | ||
| 916 | printf("pick_offscreen_child %d %f %f %d\n", | ||
| 917 | offscreen_window, | ||
| 918 | widget_x, | ||
| 919 | widget_y, | ||
| 920 | bin ); | ||
| 921 | return bin; | ||
| 922 | } | ||
| 881 | 923 | ||
| 882 | 924 | ||
| 925 | void | ||
| 926 | xwidget_set_embedder_view(struct xwidget* xww, | ||
| 927 | struct xwidget_view* xv){ | ||
| 928 | printf("gdk_offscreen_window_set_embedder %d %d\n", | ||
| 929 | GDK_IS_WINDOW(gtk_widget_get_window (xww->widget_osr)), | ||
| 930 | GDK_IS_WINDOW(gtk_widget_get_window (GTK_WIDGET (xv->widget)))); | ||
| 931 | //set_embedder needs to be called after xv->widget realization | ||
| 932 | gdk_offscreen_window_set_embedder ( gtk_widget_get_window (xww->widget_osr), | ||
| 933 | gtk_widget_get_window (GTK_WIDGET (xv->widget)) | ||
| 934 | |||
| 935 | |||
| 936 | ); | ||
| 937 | //this signal doesnt seem completely necessary | ||
| 938 | /* g_signal_connect (gtk_widget_get_window (xww->widget_osr), "from-embedder", */ | ||
| 939 | /* G_CALLBACK (offscreen_window_from_parent), gtk_widget_get_window (GTK_WIDGET (xv->widget))); */ | ||
| 940 | //but this one is | ||
| 941 | g_signal_connect (gtk_widget_get_window (xv->widget), "pick-embedded-child", | ||
| 942 | G_CALLBACK (pick_offscreen_child), gtk_widget_get_window (xww->widget_osr)); | ||
| 943 | } | ||
| 944 | |||
| 945 | gboolean | ||
| 946 | xwidget_osr_event_set_embedder (GtkWidget *widget, | ||
| 947 | GdkEvent *event, | ||
| 948 | gpointer xv) | ||
| 949 | { | ||
| 950 | xwidget_set_embedder_view(((struct xwidget_view*) xv)->model, | ||
| 951 | (struct xwidget_view*) xv); | ||
| 952 | } | ||
| 953 | |||
| 883 | 954 | ||
| 884 | int xwidget_view_index=0; | 955 | int xwidget_view_index=0; |
| 885 | 956 | ||
| @@ -989,14 +1060,30 @@ xwidget_init_view (struct xwidget *xww, | |||
| 989 | GDK_BUTTON_PRESS_MASK | 1060 | GDK_BUTTON_PRESS_MASK |
| 990 | | GDK_BUTTON_RELEASE_MASK | 1061 | | GDK_BUTTON_RELEASE_MASK |
| 991 | | GDK_POINTER_MOTION_MASK); | 1062 | | GDK_POINTER_MOTION_MASK); |
| 1063 | |||
| 1064 | |||
| 1065 | if (EQ(xww->type, Qwebkit_osr)){ | ||
| 1066 | /* ///xwgir debug */ | ||
| 1067 | /* //forward events. this isnt compatible with the set_embedded strategy */ | ||
| 1068 | g_signal_connect (G_OBJECT ( xv->widget), "button-press-event", | ||
| 1069 | G_CALLBACK (xwidget_osr_event_forward), NULL); | ||
| 1070 | g_signal_connect (G_OBJECT ( xv->widget), "button-release-event", | ||
| 1071 | G_CALLBACK (xwidget_osr_event_forward), NULL); | ||
| 1072 | g_signal_connect (G_OBJECT ( xv->widget), "motion-notify-event", | ||
| 1073 | G_CALLBACK (xwidget_osr_event_forward), NULL); | ||
| 1074 | }else{ | ||
| 1075 | //xwgir debug , orthogonal to forwarding | ||
| 1076 | g_signal_connect (G_OBJECT ( xv->widget), "motion-notify-event", | ||
| 1077 | G_CALLBACK (xwidget_osr_event_set_embedder), xv); | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | //draw | ||
| 992 | g_signal_connect (G_OBJECT ( xv->widget), "draw", | 1081 | g_signal_connect (G_OBJECT ( xv->widget), "draw", |
| 993 | G_CALLBACK (xwidget_osr_draw_callback), NULL); | 1082 | G_CALLBACK (xwidget_osr_draw_callback), NULL); |
| 994 | g_signal_connect (G_OBJECT ( xv->widget), "button-press-event", | 1083 | |
| 995 | G_CALLBACK (xwidget_osr_event_forward), NULL); | 1084 | |
| 996 | g_signal_connect (G_OBJECT ( xv->widget), "button-release-event", | 1085 | |
| 997 | G_CALLBACK (xwidget_osr_event_forward), NULL); | 1086 | |
| 998 | g_signal_connect (G_OBJECT ( xv->widget), "motion-notify-event", | ||
| 999 | G_CALLBACK (xwidget_osr_event_forward), NULL); | ||
| 1000 | /* g_signal_connect (G_OBJECT ( xv->widget), "key-press-event", */ | 1087 | /* g_signal_connect (G_OBJECT ( xv->widget), "key-press-event", */ |
| 1001 | /* G_CALLBACK (xwidget_osr_event_forward), NULL); */ | 1088 | /* G_CALLBACK (xwidget_osr_event_forward), NULL); */ |
| 1002 | /* g_signal_connect (G_OBJECT ( xv->widget), "key-release-event", */ | 1089 | /* g_signal_connect (G_OBJECT ( xv->widget), "key-release-event", */ |
| @@ -1032,6 +1119,8 @@ xwidget_init_view (struct xwidget *xww, | |||
| 1032 | xv->x = x; xv->y = y; | 1119 | xv->x = x; xv->y = y; |
| 1033 | gtk_widget_show_all (GTK_WIDGET (xv->widgetwindow)); | 1120 | gtk_widget_show_all (GTK_WIDGET (xv->widgetwindow)); |
| 1034 | 1121 | ||
| 1122 | |||
| 1123 | |||
| 1035 | //widgettype specific initialization only possible after realization | 1124 | //widgettype specific initialization only possible after realization |
| 1036 | if (EQ(xww->type, Qsocket)) { | 1125 | if (EQ(xww->type, Qsocket)) { |
| 1037 | printf ("xwid:%d socket id:%x %d\n", | 1126 | printf ("xwid:%d socket id:%x %d\n", |
| @@ -1042,6 +1131,29 @@ xwidget_init_view (struct xwidget *xww, | |||
| 1042 | gtk_socket_get_id (GTK_SOCKET (xv->widget))); | 1131 | gtk_socket_get_id (GTK_SOCKET (xv->widget))); |
| 1043 | //gtk_widget_realize(xw->widget); | 1132 | //gtk_widget_realize(xw->widget); |
| 1044 | } | 1133 | } |
| 1134 | |||
| 1135 | ////////////////////////////////////////////////////////////// | ||
| 1136 | //xwgir debug | ||
| 1137 | if (//EQ(xww->type, Qwebkit_osr)|| | ||
| 1138 | EQ(xww->type, Qsocket_osr)|| | ||
| 1139 | (Fget(xww->type, Qcxwgir_class) != Qnil))//xwgir widgets are OSR | ||
| 1140 | { | ||
| 1141 | //xwidget_set_embedder_view(xww,xv); | ||
| 1142 | printf("gdk_offscreen_window_set_embedder %d %d\n", | ||
| 1143 | GDK_IS_WINDOW(gtk_widget_get_window (xww->widget_osr)), | ||
| 1144 | GDK_IS_WINDOW(gtk_widget_get_window (GTK_WIDGET (xv->widget)))); | ||
| 1145 | //set_embedder needs to be called after xv->widget realization | ||
| 1146 | gdk_offscreen_window_set_embedder ( gtk_widget_get_window (xww->widget_osr), | ||
| 1147 | gtk_widget_get_window (GTK_WIDGET (xv->widget)) | ||
| 1148 | |||
| 1149 | ); | ||
| 1150 | /* g_signal_connect (gtk_widget_get_window (xww->widget_osr), "from-embedder", */ | ||
| 1151 | /* G_CALLBACK (offscreen_window_from_parent), gtk_widget_get_window (GTK_WIDGET (xv->widget))); */ | ||
| 1152 | g_signal_connect (gtk_widget_get_window (xv->widget), "pick-embedded-child", | ||
| 1153 | G_CALLBACK (pick_offscreen_child), gtk_widget_get_window (xww->widget_osr)); | ||
| 1154 | } | ||
| 1155 | //////////////////////////////////////// | ||
| 1156 | |||
| 1045 | return xv; | 1157 | return xv; |
| 1046 | } | 1158 | } |
| 1047 | 1159 | ||