diff options
| -rw-r--r-- | README.xwidget | 18 | ||||
| -rw-r--r-- | src/xwidget.c | 221 |
2 files changed, 215 insertions, 24 deletions
diff --git a/README.xwidget b/README.xwidget index 4477f53051c..24b11286ca2 100644 --- a/README.xwidget +++ b/README.xwidget | |||
| @@ -333,11 +333,29 @@ export LDFLAGS=`pkg-config --libs webkit-1.0` | |||
| 333 | ./configure | 333 | ./configure |
| 334 | make | 334 | make |
| 335 | 335 | ||
| 336 | **** off screen rendering | ||
| 336 | export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT_OSR -g" | 337 | export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT_OSR -g" |
| 337 | export LDFLAGS=`pkg-config --libs webkit-1.0` | 338 | export LDFLAGS=`pkg-config --libs webkit-1.0` |
| 338 | ./configure | 339 | ./configure |
| 339 | make | 340 | make |
| 340 | 341 | ||
| 342 | works a little bit but i get errors like: | ||
| 343 | |||
| 344 | (emacs:8362): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11' | ||
| 345 | |||
| 346 | set a breakpoint in g_log, backtrace seems to indicate | ||
| 347 | webkitViewportAttributesRecompute is the offender. | ||
| 348 | |||
| 349 | maybe try gtk3 variants? | ||
| 350 | |||
| 351 | export CFLAGS="`pkg-config --cflags webkitgtk-3.0 ` -DHAVE_WEBKIT_OSR -g" | ||
| 352 | export LDFLAGS=`pkg-config --libs webkitgtk-3.0 ` | ||
| 353 | ./configure --with-x-toolkit=gtk3 | ||
| 354 | make | ||
| 355 | |||
| 356 | crash in gtk_window_get_size instead. great. | ||
| 357 | |||
| 358 | http://gtkplus-p3.0.sourcearchive.com/documentation/2.91.5-0ubuntu1/testoffscreenwindow_8c-source.html | ||
| 341 | 359 | ||
| 342 | 360 | ||
| 343 | *** firefox | 361 | *** firefox |
diff --git a/src/xwidget.c b/src/xwidget.c index ad10567f91b..ea880458dc1 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -72,6 +72,11 @@ | |||
| 72 | #include <gtk/gtk.h> | 72 | #include <gtk/gtk.h> |
| 73 | #include <gdk/gdk.h> | 73 | #include <gdk/gdk.h> |
| 74 | 74 | ||
| 75 | #ifdef HAVE_GTK3 | ||
| 76 | //for gtk3; sockets and plugs | ||
| 77 | #include <gtk/gtkx.h> | ||
| 78 | #endif | ||
| 79 | |||
| 75 | #include <librsvg/rsvg.h> | 80 | #include <librsvg/rsvg.h> |
| 76 | 81 | ||
| 77 | #ifdef HAVE_GOOCANVAS | 82 | #ifdef HAVE_GOOCANVAS |
| @@ -83,6 +88,18 @@ | |||
| 83 | #include <clutter-gtk/clutter-gtk.h> | 88 | #include <clutter-gtk/clutter-gtk.h> |
| 84 | #endif | 89 | #endif |
| 85 | 90 | ||
| 91 | |||
| 92 | #ifdef HAVE_WEBKIT | ||
| 93 | #include <webkitgtk.h> | ||
| 94 | #endif | ||
| 95 | |||
| 96 | |||
| 97 | #ifdef HAVE_WEBKIT_OSR | ||
| 98 | #include <webkit/webkitwebview.h> | ||
| 99 | #endif | ||
| 100 | |||
| 101 | |||
| 102 | |||
| 86 | #include "xwidget.h" | 103 | #include "xwidget.h" |
| 87 | 104 | ||
| 88 | //TODO should of course not be a hardcoded array but I can't be bothered atm | 105 | //TODO should of course not be a hardcoded array but I can't be bothered atm |
| @@ -252,13 +269,21 @@ void xwidget_slider_changed (GtkRange *range, | |||
| 252 | 269 | ||
| 253 | } | 270 | } |
| 254 | 271 | ||
| 272 | double osr_dbg_color=0; | ||
| 255 | void webkit_osr_redraw_child ( struct xwidget* xw, GtkWidget *widget) | 273 | void webkit_osr_redraw_child ( struct xwidget* xw, GtkWidget *widget) |
| 256 | { | 274 | { |
| 257 | 275 | ||
| 258 | 276 | //this stuff is different in gtk3 | |
| 277 | #ifndef HAVE_GTK3 | ||
| 259 | cairo_t *cr; | 278 | cairo_t *cr; |
| 279 | |||
| 280 | |||
| 260 | GdkPixmap *src_pixmap; | 281 | GdkPixmap *src_pixmap; |
| 261 | src_pixmap = xw->widget_osr->window; | 282 | src_pixmap = gtk_offscreen_window_get_pixmap(xw->widgetwindow_osr); |
| 283 | |||
| 284 | //g_object_ref(src_pixmap);//TODO needs to be unrefed eventually, if we are to use his method | ||
| 285 | |||
| 286 | |||
| 262 | printf("webkit_osr_redraw_child xw.id:%d xw.type:%d window:%d\n", xw->id,xw->type, gtk_widget_get_window (widget)); | 287 | printf("webkit_osr_redraw_child xw.id:%d xw.type:%d window:%d\n", xw->id,xw->type, gtk_widget_get_window (widget)); |
| 263 | 288 | ||
| 264 | cr = gdk_cairo_create (gtk_widget_get_window (widget)); | 289 | cr = gdk_cairo_create (gtk_widget_get_window (widget)); |
| @@ -266,19 +291,70 @@ void webkit_osr_redraw_child ( struct xwidget* xw, GtkWidget *widget) | |||
| 266 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | 291 | cairo_rectangle(cr, 0,0, xw->width, xw->height); |
| 267 | cairo_clip(cr); | 292 | cairo_clip(cr); |
| 268 | 293 | ||
| 269 | /* | 294 | // debugging redraw: |
| 270 | cairo_set_source_rgb(cr, 0.1, 1.0, 0.2); | 295 | // - the bg colors always change, so theres no error in signal handling |
| 296 | // - i get this error now and then: | ||
| 297 | //(emacs:7109): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11' | ||
| 298 | // seems to happen in webkit actually. see README | ||
| 299 | |||
| 300 | if(1){ //redraw debug hack | ||
| 301 | cairo_set_source_rgb(cr, osr_dbg_color, 1.0, 0.2); | ||
| 302 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | ||
| 303 | cairo_fill(cr); | ||
| 304 | osr_dbg_color+=0.1; | ||
| 305 | if(osr_dbg_color>1.0) | ||
| 306 | osr_dbg_color=0.0; | ||
| 307 | |||
| 308 | } | ||
| 309 | |||
| 310 | gdk_cairo_set_source_pixmap (cr, src_pixmap, 0,0); //deprecated. use gdk_cairo_set_source_window | ||
| 311 | //gdk_cairo_set_source_window(cr, src_pixmap, 0,0); | ||
| 312 | |||
| 313 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | ||
| 314 | cairo_paint_with_alpha (cr, 0.7); | ||
| 315 | //cairo_paint(cr); | ||
| 316 | |||
| 317 | |||
| 318 | cairo_destroy (cr); | ||
| 319 | #elseif | ||
| 320 | cairo_t *cr; | ||
| 321 | cairo_surface_t * *src_pixmap; | ||
| 322 | src_pixmap = gtk_offscreen_window_get_surface (xw->widgetwindow_osr); | ||
| 323 | |||
| 324 | //g_object_ref(src_pixmap);//TODO needs to be unrefed eventually, if we are to use his method | ||
| 325 | |||
| 326 | |||
| 327 | printf("webkit_osr_redraw_child gtk3 xw.id:%d xw.type:%d window:%d\n", xw->id,xw->type, gtk_widget_get_window (widget)); | ||
| 328 | |||
| 329 | cr = gdk_cairo_create (gtk_widget_get_window (widget)); | ||
| 330 | |||
| 271 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | 331 | cairo_rectangle(cr, 0,0, xw->width, xw->height); |
| 272 | cairo_fill(cr); | 332 | cairo_clip(cr); |
| 273 | */ | 333 | |
| 334 | // debugging redraw: | ||
| 335 | // - the bg colors always change, so theres no error in signal handling | ||
| 336 | // - i get this error now and then: | ||
| 337 | //(emacs:7109): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11' | ||
| 338 | // seems to happen in webkit actually. see README | ||
| 339 | |||
| 340 | if(1){ //redraw debug hack | ||
| 341 | cairo_set_source_rgb(cr, osr_dbg_color, 1.0, 0.2); | ||
| 342 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | ||
| 343 | cairo_fill(cr); | ||
| 344 | osr_dbg_color+=0.1; | ||
| 345 | if(osr_dbg_color>1.0) | ||
| 346 | osr_dbg_color=0.0; | ||
| 347 | |||
| 348 | } | ||
| 274 | 349 | ||
| 275 | gdk_cairo_set_source_pixmap (cr, src_pixmap, | 350 | cairo_set_source_surface (cr, src_pixmap, 0,0); |
| 276 | 0,0); | 351 | |
| 277 | 352 | ||
| 278 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | 353 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); |
| 279 | //cairo_paint_with_alpha (cr, 0.9); | 354 | cairo_paint_with_alpha (cr, 0.7); |
| 280 | cairo_paint(cr); | 355 | //cairo_paint(cr); |
| 281 | cairo_destroy (cr); | 356 | cairo_destroy (cr); |
| 357 | #endif | ||
| 282 | } | 358 | } |
| 283 | 359 | ||
| 284 | /* when the on-screen webkit peer view gets exposed this signal is called. | 360 | /* when the on-screen webkit peer view gets exposed this signal is called. |
| @@ -293,12 +369,72 @@ gboolean webkit_osr_expose_event_callback (GtkWidget *widget, GdkEventExpose *ev | |||
| 293 | /* when the off-screen webkit master view changes this signal is called. | 369 | /* when the off-screen webkit master view changes this signal is called. |
| 294 | it copies the bitmap from the off-screen webkit instance */ | 370 | it copies the bitmap from the off-screen webkit instance */ |
| 295 | gboolean webkit_osr_damage_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data) | 371 | gboolean webkit_osr_damage_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data) |
| 296 | { | 372 | { |
| 297 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); | 373 | //TODO this is wrong! should just oueu a redraw of onscreen widget |
| 298 | webkit_osr_redraw_child(xw, widget); | 374 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); |
| 299 | return FALSE; | 375 | struct xwidget_view* xv; |
| 376 | //webkit_osr_redraw_child(xw, widget); | ||
| 377 | for (int i = 0; i < MAX_XWIDGETS; i++)//todo mvc refactor | ||
| 378 | { | ||
| 379 | xv = &xwidget_views[i]; | ||
| 380 | if(xv->model == xw){ | ||
| 381 | gtk_widget_queue_draw (xv->widget); //redraw all views, the master has changed | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 385 | return TRUE; | ||
| 300 | } | 386 | } |
| 301 | 387 | ||
| 388 | |||
| 389 | //for gtk3 | ||
| 390 | gboolean | ||
| 391 | xwidget_osr_draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) | ||
| 392 | { | ||
| 393 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); | ||
| 394 | struct xwidget_view* xv = (struct xwidget_viev*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET_VIEW); | ||
| 395 | cairo_surface_t* src_pixmap; | ||
| 396 | //src_pixmap = gtk_offscreen_window_get_surface (xw->widgetwindow_osr); | ||
| 397 | |||
| 398 | |||
| 399 | printf("xwidget_osr_draw_callback gtk3 xw.id:%d xw.type:%d window:%d srcpix:%d vis:%d\n", | ||
| 400 | xw->id,xw->type, gtk_widget_get_window (widget), src_pixmap, gtk_widget_get_visible (xw->widget_osr)); | ||
| 401 | |||
| 402 | // cr = gdk_cairo_create (gtk_widget_get_window (widget)); | ||
| 403 | |||
| 404 | cairo_rectangle(cr, 0,0, xv->clipx, xv->clipy);//xw->width, xw->height); | ||
| 405 | cairo_clip(cr); | ||
| 406 | |||
| 407 | // debugging redraw: | ||
| 408 | // - the bg colors always change, so theres no error in signal handling | ||
| 409 | // - i get this error now and then: | ||
| 410 | //(emacs:7109): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11' | ||
| 411 | // seems to happen in webkit actually. see README | ||
| 412 | |||
| 413 | if(1){ //redraw debug hack. | ||
| 414 | cairo_set_source_rgb(cr, osr_dbg_color, 1.0, 0.2); | ||
| 415 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | ||
| 416 | cairo_fill(cr); | ||
| 417 | osr_dbg_color+=0.1; | ||
| 418 | if(osr_dbg_color>1.0) | ||
| 419 | osr_dbg_color=0.0; | ||
| 420 | |||
| 421 | } | ||
| 422 | |||
| 423 | //maybe use below instead? | ||
| 424 | gtk_widget_draw (xw->widget_osr, cr); | ||
| 425 | |||
| 426 | //cairo_set_source_surface (cr, src_pixmap, 0,0); | ||
| 427 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | ||
| 428 | |||
| 429 | cairo_paint_with_alpha (cr, 0.7); | ||
| 430 | //cairo_paint(cr); | ||
| 431 | |||
| 432 | |||
| 433 | return FALSE; | ||
| 434 | } | ||
| 435 | |||
| 436 | |||
| 437 | |||
| 302 | int xwidget_view_index=0; | 438 | int xwidget_view_index=0; |
| 303 | 439 | ||
| 304 | /* initializes and does initial placement of an xwidget view on screen */ | 440 | /* initializes and does initial placement of an xwidget view on screen */ |
| @@ -395,10 +531,16 @@ xwidget_init_view ( | |||
| 395 | } else if (EQ(xww->type, Qwebkit_osr)) { | 531 | } else if (EQ(xww->type, Qwebkit_osr)) { |
| 396 | #ifdef HAVE_WEBKIT_OSR | 532 | #ifdef HAVE_WEBKIT_OSR |
| 397 | xv->widget = gtk_drawing_area_new(); | 533 | xv->widget = gtk_drawing_area_new(); |
| 534 | gtk_widget_set_app_paintable ( xv->widget, TRUE); //because expose event handling | ||
| 535 | #endif | ||
| 536 | #ifdef HAVE_GTK3 //and webkit_osr | ||
| 537 | g_signal_connect (G_OBJECT ( xv->widget), "draw", | ||
| 538 | G_CALLBACK (xwidget_osr_draw_callback), NULL); | ||
| 539 | |||
| 540 | #else | ||
| 398 | g_signal_connect (G_OBJECT ( xv->widget), "expose_event", | 541 | g_signal_connect (G_OBJECT ( xv->widget), "expose_event", |
| 399 | G_CALLBACK (webkit_osr_expose_event_callback), NULL); | 542 | G_CALLBACK (webkit_osr_expose_event_callback), NULL); |
| 400 | 543 | #endif | |
| 401 | #endif | ||
| 402 | 544 | ||
| 403 | 545 | ||
| 404 | } else return NULL; | 546 | } else return NULL; |
| @@ -411,11 +553,23 @@ xwidget_init_view ( | |||
| 411 | //xw->widgetwindow = GTK_CONTAINER (gtk_layout_new (NULL, NULL)); | 553 | //xw->widgetwindow = GTK_CONTAINER (gtk_layout_new (NULL, NULL)); |
| 412 | //xw->widgetwindow = GTK_CONTAINER (gtk_offscreen_window_new ()); | 554 | //xw->widgetwindow = GTK_CONTAINER (gtk_offscreen_window_new ()); |
| 413 | 555 | ||
| 414 | xv->widgetwindow = GTK_CONTAINER (gtk_fixed_new ()); | 556 | xv->widgetwindow = GTK_CONTAINER (gtk_fixed_new ()); //works well for clipping on gtk2 not gtk3 |
| 415 | gtk_widget_set_has_window(GTK_WIDGET ( xv->widgetwindow), TRUE); //if gtk_fixed doesnt have a window it will surprisingly not honor setsize so that children gets clipped later. the documentation is not consistent regarding if its legal to call this method | 557 | //xv->widgetwindow = GTK_CONTAINER (gtk_event_box_new ()); //doesnt help clipping gtk3 |
| 416 | //xv->widgetwindow = GTK_CONTAINER (gtk_event_box_new ()); | 558 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), xww->width, xww->height); |
| 559 | /* GtkAllocation a; */ | ||
| 560 | /* a.x=0; a.y=0; a.width=xww->width; a.height=xww->height; */ | ||
| 561 | /* gtk_widget_set_allocation (GTK_WIDGET (xv->widget), &a); */ | ||
| 562 | |||
| 563 | gtk_widget_set_has_window(GTK_WIDGET ( xv->widgetwindow), TRUE); | ||
| 564 | //if gtk_fixed doesnt have a window it will surprisingly not honor | ||
| 565 | //setsize so that children gets clipped later. the documentation is | ||
| 566 | //not consistent regarding if its legal to call this method. | ||
| 567 | |||
| 568 | //doesnt help on gtk3, and the docs seem clearer there that this is | ||
| 569 | //an internal function | ||
| 570 | |||
| 571 | |||
| 417 | 572 | ||
| 418 | //gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, xw->height); | ||
| 419 | //gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); | 573 | //gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); |
| 420 | gtk_container_add (xv->widgetwindow, xv->widget); | 574 | gtk_container_add (xv->widgetwindow, xv->widget); |
| 421 | gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width, xww->height); | 575 | gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width, xww->height); |
| @@ -901,6 +1055,17 @@ struct xwidget_view* xwidget_view_lookup(struct xwidget* xw, struct window * | |||
| 901 | return xv; | 1055 | return xv; |
| 902 | } | 1056 | } |
| 903 | 1057 | ||
| 1058 | //attempting a workaround for a webkit offscreen bug | ||
| 1059 | void gtk_window_get_position (GtkWindow *window, | ||
| 1060 | gint *root_x, | ||
| 1061 | gint *root_y){ | ||
| 1062 | printf("my getsize\n"); | ||
| 1063 | *root_x = 0; | ||
| 1064 | *root_y = 0; | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | |||
| 1068 | |||
| 904 | int | 1069 | int |
| 905 | lookup_xwidget (Lisp_Object spec) | 1070 | lookup_xwidget (Lisp_Object spec) |
| 906 | { | 1071 | { |
| @@ -939,14 +1104,22 @@ lookup_xwidget (Lisp_Object spec) | |||
| 939 | //diy mvc. widget is rendered offscreen, later blitted onscreen | 1104 | //diy mvc. widget is rendered offscreen, later blitted onscreen |
| 940 | if (EQ(xw->type, Qwebkit_osr)){ | 1105 | if (EQ(xw->type, Qwebkit_osr)){ |
| 941 | xw->widgetwindow_osr = GTK_CONTAINER (gtk_offscreen_window_new ()); | 1106 | xw->widgetwindow_osr = GTK_CONTAINER (gtk_offscreen_window_new ()); |
| 1107 | gtk_window_resize( GTK_WINDOW(xw->widgetwindow_osr), xw->width, xw->height); | ||
| 942 | xw->widget_osr = webkit_web_view_new(); | 1108 | xw->widget_osr = webkit_web_view_new(); |
| 1109 | |||
| 1110 | //random debug hack | ||
| 1111 | gtk_widget_set_double_buffered (xw->widget_osr,FALSE); | ||
| 1112 | gtk_widget_set_double_buffered (xw->widgetwindow_osr,FALSE); | ||
| 1113 | |||
| 1114 | |||
| 1115 | //xw->widget_osr ///XXX | ||
| 1116 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height); | ||
| 943 | gtk_container_add (xw->widgetwindow_osr, xw->widget_osr); | 1117 | gtk_container_add (xw->widgetwindow_osr, xw->widget_osr); |
| 944 | gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow_osr)); | 1118 | gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow_osr)); |
| 945 | 1119 | ||
| 946 | //store some xwidget data in the gtk widgets | 1120 | //store some xwidget data in the gtk widgets |
| 947 | g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET, (gpointer) (xw)); //the xwidget | 1121 | g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET, (gpointer) (xw)); //the xwidget |
| 948 | g_object_set_data (G_OBJECT (xw->widgetwindow_osr), XG_XWIDGET, (gpointer) (xw)); //the xwidget | 1122 | g_object_set_data (G_OBJECT (xw->widgetwindow_osr), XG_XWIDGET, (gpointer) (xw)); //the xwidget |
| 949 | |||
| 950 | 1123 | ||
| 951 | g_signal_connect (G_OBJECT ( xw->widgetwindow_osr), "damage_event", | 1124 | g_signal_connect (G_OBJECT ( xw->widgetwindow_osr), "damage_event", |
| 952 | G_CALLBACK (webkit_osr_damage_event_callback), NULL); | 1125 | G_CALLBACK (webkit_osr_damage_event_callback), NULL); |