diff options
| author | Joakim Verona | 2011-07-01 22:32:29 +0200 |
|---|---|---|
| committer | Joakim Verona | 2011-07-01 22:32:29 +0200 |
| commit | b075649f92f1543f61efed28adb25df666a1a03c (patch) | |
| tree | 234f3708f2e51d42aedb956f55241a9868916d53 | |
| parent | 9f13671c09bfdc18336132c40a0cf5b715c8da86 (diff) | |
| download | emacs-b075649f92f1543f61efed28adb25df666a1a03c.tar.gz emacs-b075649f92f1543f61efed28adb25df666a1a03c.zip | |
first working clipping for gtk3.
| -rw-r--r-- | README.xwidget | 79 | ||||
| -rw-r--r-- | src/emacsgtkfixed.c | 48 | ||||
| -rw-r--r-- | src/xwidget.c | 31 | ||||
| -rw-r--r-- | src/xwidget.h | 2 |
4 files changed, 148 insertions, 12 deletions
diff --git a/README.xwidget b/README.xwidget index fd6c769866a..1e584869592 100644 --- a/README.xwidget +++ b/README.xwidget | |||
| @@ -357,11 +357,31 @@ crash in gtk_window_get_size instead. great. | |||
| 357 | 357 | ||
| 358 | http://gtkplus-p3.0.sourcearchive.com/documentation/2.91.5-0ubuntu1/testoffscreenwindow_8c-source.html | 358 | http://gtkplus-p3.0.sourcearchive.com/documentation/2.91.5-0ubuntu1/testoffscreenwindow_8c-source.html |
| 359 | 359 | ||
| 360 | after many atempts, the basic issue remains. for some reason the | ||
| 361 | offscreen widget isnt ok when I want to snapshot it, so i simply get | ||
| 362 | emptiness. the surface is only ok someimes. | ||
| 363 | |||
| 364 | |||
| 365 | |||
| 366 | |||
| 367 | **** on-screen rendering to separate window | ||
| 368 | an alternative might be to open a separate window and snapshot it. the | ||
| 369 | idea is that whatever oddness webkit does so that offscreen rendering | ||
| 370 | doesnt work, doesnt happen on-screen. the window could be opened | ||
| 371 | somewhere not in the way. | ||
| 360 | 372 | ||
| 361 | *** firefox | 373 | *** firefox |
| 362 | http://www-archive.mozilla.org/unix/gtk-embedding.html | 374 | http://www-archive.mozilla.org/unix/gtk-embedding.html |
| 363 | seems to be severly bitrotted | 375 | seems to be severly bitrotted |
| 364 | 376 | ||
| 377 | heres a newer aproach | ||
| 378 | http://hg.mozilla.org/incubator/embedding/file/29ac0fe51754/gtk/tests/test.cpp | ||
| 379 | |||
| 380 | while webkit clearly has the best traction as an embeddee, the | ||
| 381 | offscreen rendering issues makes it interesting to see what ff brings | ||
| 382 | to the table. | ||
| 383 | |||
| 384 | |||
| 365 | ** TODO clipping of controllers | 385 | ** TODO clipping of controllers |
| 366 | 386 | ||
| 367 | Emacs uses a big GTK window and does its own clipping against Emacs | 387 | Emacs uses a big GTK window and does its own clipping against Emacs |
| @@ -392,9 +412,66 @@ http://www.lanedo.com/~carlos/gtk3-doc/GtkWidget.html#gtk-widget-set-has-window | |||
| 392 | mentions that it has_window can only be called inside a widget | 412 | mentions that it has_window can only be called inside a widget |
| 393 | impementation. | 413 | impementation. |
| 394 | 414 | ||
| 395 | *** TODO try scrolled window | 415 | *** DONE try scrolled window |
| 416 | CLOSED: [2011-07-01 Fri 10:56] | ||
| 396 | clipping does in fact work with | 417 | clipping does in fact work with |
| 397 | gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget); | 418 | gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget); |
| 398 | !! | 419 | !! |
| 399 | 420 | ||
| 400 | I get unwanted scrollbars in the widget though. | 421 | I get unwanted scrollbars in the widget though. |
| 422 | |||
| 423 | gtk_scrolled_window_set_policy ( xv->widgetwindow, | ||
| 424 | GTK_POLICY_NEVER, GTK_POLICY_NEVER); | ||
| 425 | |||
| 426 | stops clipping from working! | ||
| 427 | |||
| 428 | |||
| 429 | *** DONE try viewport | ||
| 430 | CLOSED: [2011-07-01 Fri 10:56] | ||
| 431 | gtkviewport is used in scrolled window so in order to remove | ||
| 432 | scrollbars it should be possible to use viewport directly. however, | ||
| 433 | viewport ignores size requests. | ||
| 434 | |||
| 435 | |||
| 436 | *** TODO debug allocation | ||
| 437 | the container determines how much size to allocate to child widgets. | ||
| 438 | |||
| 439 | GtkAllocation galloc; | ||
| 440 | gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc); | ||
| 441 | printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height); | ||
| 442 | |||
| 443 | after my clipping attemp shows that my size request is ignored! this | ||
| 444 | might be logical, since the container provided by emacs is a | ||
| 445 | gtkfixed. gtkfixed might choose to heed the widgets size desires and | ||
| 446 | allocate the entire widget size. but we want clipping! | ||
| 447 | |||
| 448 | since i cant reasonably expect to change the emacs main container, i | ||
| 449 | can maybe overide the setallocation method in gwfixed, and adjust | ||
| 450 | allocation to clipping if its an xwidget asking for allocation. | ||
| 451 | |||
| 452 | **** subclass gtkfixed | ||
| 453 | possibly i need to subclass gtkfixed and override | ||
| 454 | |||
| 455 | void gtk_widget_size_allocate (GtkWidget *widget, | ||
| 456 | GtkAllocation *allocation); | ||
| 457 | |||
| 458 | http://developer.gnome.org/gobject/stable/howto-gobject.html | ||
| 459 | |||
| 460 | turns out emacs already does this for gtk3 according to jan D: | ||
| 461 | >>For GTK3, Emacs already subclasses GtkFixed, see emacsgtkfixed.[ch]. | ||
| 462 | |||
| 463 | - widgets may not be underallocated, aparently | ||
| 464 | http://mail.gnome.org/archives/commits-list/2011-April/msg10950.html | ||
| 465 | |||
| 466 | - how to call base class method/chain up | ||
| 467 | http://developer.gnome.org/gobject/stable/howto-gobject-chainup.html | ||
| 468 | |||
| 469 | - the allocation modification could happen in the container or the | ||
| 470 | child. it feels more apropiate in the container | ||
| 471 | |||
| 472 | it is however unexpectedy inconvenient to modify allocation because | ||
| 473 | the needed data is private to the base class. to overcome this: | ||
| 474 | |||
| 475 | - run base class method 1st. | ||
| 476 | - then, iterate all children, and modify allocation for xwidget | ||
| 477 | children only. x y will then be set. | ||
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c index 0b57e2cdf36..d07788f3193 100644 --- a/src/emacsgtkfixed.c +++ b/src/emacsgtkfixed.c | |||
| @@ -27,7 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 27 | #include "lisp.h" | 27 | #include "lisp.h" |
| 28 | #include "frame.h" | 28 | #include "frame.h" |
| 29 | #include "xterm.h" | 29 | #include "xterm.h" |
| 30 | 30 | #include "xwidget.h" | |
| 31 | struct _EmacsFixedPrivate | 31 | struct _EmacsFixedPrivate |
| 32 | { | 32 | { |
| 33 | struct frame *f; | 33 | struct frame *f; |
| @@ -42,6 +42,49 @@ static void emacs_fixed_get_preferred_height (GtkWidget *widget, | |||
| 42 | gint *natural); | 42 | gint *natural); |
| 43 | G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED) | 43 | G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED) |
| 44 | 44 | ||
| 45 | |||
| 46 | |||
| 47 | void aloc_callback(GtkWidget* child, GtkWidget* fixed){ | ||
| 48 | GtkAllocation child_allocation; | ||
| 49 | GtkRequisition child_requisition; | ||
| 50 | |||
| 51 | //TODO | ||
| 52 | // if child is an xwidget, find its clipping area and modify allocation | ||
| 53 | |||
| 54 | struct xwidget_view* xv = (struct xwidget_viev*) g_object_get_data (G_OBJECT (child), XG_XWIDGET_VIEW); | ||
| 55 | printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child)); | ||
| 56 | if(xv){ | ||
| 57 | printf(" allocation modification for xw\n"); | ||
| 58 | gtk_widget_get_allocation(child, &child_allocation); | ||
| 59 | child_allocation.width = xv->clipx; | ||
| 60 | child_allocation.height = xv->clipy; | ||
| 61 | gtk_widget_size_allocate (child, &child_allocation); | ||
| 62 | } | ||
| 63 | |||
| 64 | } | ||
| 65 | |||
| 66 | static void emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget, | ||
| 67 | GtkAllocation *allocation){ | ||
| 68 | //for xwidgets | ||
| 69 | printf(" emacs_fixed_gtk_widget_size_allocate\n"); | ||
| 70 | |||
| 71 | //TODO 1st call base class method | ||
| 72 | EmacsFixedClass *klass; | ||
| 73 | GtkWidgetClass *parent_class; | ||
| 74 | klass = EMACS_FIXED_GET_CLASS (widget); | ||
| 75 | parent_class = g_type_class_peek_parent (klass); | ||
| 76 | parent_class->size_allocate (widget, allocation); | ||
| 77 | |||
| 78 | |||
| 79 | //then modify allocations | ||
| 80 | gtk_container_foreach (widget, | ||
| 81 | aloc_callback, | ||
| 82 | widget); | ||
| 83 | |||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | |||
| 45 | static void | 88 | static void |
| 46 | emacs_fixed_class_init (EmacsFixedClass *klass) | 89 | emacs_fixed_class_init (EmacsFixedClass *klass) |
| 47 | { | 90 | { |
| @@ -53,6 +96,9 @@ emacs_fixed_class_init (EmacsFixedClass *klass) | |||
| 53 | 96 | ||
| 54 | widget_class->get_preferred_width = emacs_fixed_get_preferred_width; | 97 | widget_class->get_preferred_width = emacs_fixed_get_preferred_width; |
| 55 | widget_class->get_preferred_height = emacs_fixed_get_preferred_height; | 98 | widget_class->get_preferred_height = emacs_fixed_get_preferred_height; |
| 99 | |||
| 100 | widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate; | ||
| 101 | |||
| 56 | g_type_class_add_private (klass, sizeof (EmacsFixedPrivate)); | 102 | g_type_class_add_private (klass, sizeof (EmacsFixedPrivate)); |
| 57 | } | 103 | } |
| 58 | 104 | ||
diff --git a/src/xwidget.c b/src/xwidget.c index b612bc3b283..841e3ee2144 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -75,6 +75,7 @@ | |||
| 75 | #ifdef HAVE_GTK3 | 75 | #ifdef HAVE_GTK3 |
| 76 | //for gtk3; sockets and plugs | 76 | //for gtk3; sockets and plugs |
| 77 | #include <gtk/gtkx.h> | 77 | #include <gtk/gtkx.h> |
| 78 | #include "emacsgtkfixed.h" | ||
| 78 | #endif | 79 | #endif |
| 79 | 80 | ||
| 80 | #include <librsvg/rsvg.h> | 81 | #include <librsvg/rsvg.h> |
| @@ -129,8 +130,6 @@ Lisp_Object Qbutton, Qtoggle, Qslider, Qsocket, Qcairo, Qwebkit, | |||
| 129 | extern Lisp_Object QCtype; | 130 | extern Lisp_Object QCtype; |
| 130 | extern Lisp_Object QCwidth, QCheight; | 131 | extern Lisp_Object QCwidth, QCheight; |
| 131 | 132 | ||
| 132 | #define XG_XWIDGET "emacs_xwidget" | ||
| 133 | #define XG_XWIDGET_VIEW "emacs_xwidget_view" | ||
| 134 | struct xwidget_view* xwidget_view_lookup(struct xwidget* xw, struct window *w); | 133 | struct xwidget_view* xwidget_view_lookup(struct xwidget* xw, struct window *w); |
| 135 | 134 | ||
| 136 | int | 135 | int |
| @@ -555,7 +554,9 @@ xwidget_init_view ( | |||
| 555 | 554 | ||
| 556 | //xv->widgetwindow = GTK_CONTAINER (gtk_fixed_new ()); //works well for clipping on gtk2 not gtk3 | 555 | //xv->widgetwindow = GTK_CONTAINER (gtk_fixed_new ()); //works well for clipping on gtk2 not gtk3 |
| 557 | //xv->widgetwindow = GTK_CONTAINER (gtk_event_box_new ()); //doesnt help clipping gtk3 | 556 | //xv->widgetwindow = GTK_CONTAINER (gtk_event_box_new ()); //doesnt help clipping gtk3 |
| 558 | xv->widgetwindow = GTK_CONTAINER (gtk_scrolled_window_new (NULL, NULL)); //doesnt help clipping gtk3 | 557 | //xv->widgetwindow = GTK_CONTAINER (gtk_scrolled_window_new (NULL, NULL)); //clips in gtk3 |
| 558 | xv->widgetwindow = GTK_CONTAINER (gtk_viewport_new (NULL, NULL)); //clips in gtk3 | ||
| 559 | |||
| 559 | 560 | ||
| 560 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), xww->width, xww->height); | 561 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), xww->width, xww->height); |
| 561 | /* GtkAllocation a; */ | 562 | /* GtkAllocation a; */ |
| @@ -573,21 +574,24 @@ xwidget_init_view ( | |||
| 573 | 574 | ||
| 574 | 575 | ||
| 575 | //gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); | 576 | //gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); |
| 576 | //gtk_container_add (xv->widgetwindow, xv->widget); | 577 | gtk_container_add (xv->widgetwindow, xv->widget); |
| 577 | 578 | ||
| 578 | gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget); | 579 | //gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget); // when using scrollw |
| 579 | |||
| 580 | gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width, xww->height); | ||
| 581 | gtk_fixed_put (GTK_FIXED (s->f->gwfixed), GTK_WIDGET (xv->widgetwindow), x, y); | ||
| 582 | xv->x = x; xv->y = y; | ||
| 583 | gtk_widget_show_all (GTK_WIDGET (xv->widgetwindow)); | ||
| 584 | 580 | ||
| 585 | //store some xwidget data in the gtk widgets | 581 | //store some xwidget data in the gtk widgets |
| 586 | g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, (gpointer) (s->f)); //the emacs frame | 582 | g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, (gpointer) (s->f)); //the emacs frame |
| 587 | g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, (gpointer) (xww)); //the xwidget | 583 | g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, (gpointer) (xww)); //the xwidget |
| 588 | g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, (gpointer) (xv)); //the xwidget | 584 | g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, (gpointer) (xv)); //the xwidget |
| 589 | g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, (gpointer) (xww)); //the xwidget | 585 | g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, (gpointer) (xww)); //the xwidget |
| 586 | g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET_VIEW, (gpointer) (xv)); //the xwidget | ||
| 590 | 587 | ||
| 588 | |||
| 589 | gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width, xww->height); | ||
| 590 | gtk_fixed_put (EMACS_FIXED (s->f->gwfixed), GTK_WIDGET (xv->widgetwindow), x, y); | ||
| 591 | xv->x = x; xv->y = y; | ||
| 592 | gtk_widget_show_all (GTK_WIDGET (xv->widgetwindow)); | ||
| 593 | |||
| 594 | |||
| 591 | //this seems to enable xcomposition. later we need to paint ourselves somehow, | 595 | //this seems to enable xcomposition. later we need to paint ourselves somehow, |
| 592 | //since the widget is no longer responsible for painting itself | 596 | //since the widget is no longer responsible for painting itself |
| 593 | //if(xw->type!=3) //im having trouble with compositing and sockets. hmmm. | 597 | //if(xw->type!=3) //im having trouble with compositing and sockets. hmmm. |
| @@ -701,6 +705,13 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 701 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), | 705 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), |
| 702 | clipx, clipy); | 706 | clipx, clipy); |
| 703 | printf("reclip %d %d -> %d %d\n",xv->clipx, xv->clipy, clipx, clipy ); | 707 | printf("reclip %d %d -> %d %d\n",xv->clipx, xv->clipy, clipx, clipy ); |
| 708 | |||
| 709 | //allocation debugging. the correct values cant be expected to show upp immediately, but eventually they should get to be ok | ||
| 710 | // this is because we dont know when the container gets around to doing layout | ||
| 711 | GtkAllocation galloc; | ||
| 712 | gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc); | ||
| 713 | printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height); | ||
| 714 | |||
| 704 | xv->clipx = clipx; xv->clipy = clipy; | 715 | xv->clipx = clipx; xv->clipy = clipy; |
| 705 | } | 716 | } |
| 706 | //a live xwidget paints itself. when using composition, that | 717 | //a live xwidget paints itself. when using composition, that |
diff --git a/src/xwidget.h b/src/xwidget.h index d54d4e649d8..36e33c5dfbf 100644 --- a/src/xwidget.h +++ b/src/xwidget.h | |||
| @@ -83,3 +83,5 @@ void xwidget_touch (struct xwidget_view *xw); | |||
| 83 | void assert_valid_xwidget_id(int id,char *str); | 83 | void assert_valid_xwidget_id(int id,char *str); |
| 84 | 84 | ||
| 85 | int lookup_xwidget (Lisp_Object spec); | 85 | int lookup_xwidget (Lisp_Object spec); |
| 86 | #define XG_XWIDGET "emacs_xwidget" | ||
| 87 | #define XG_XWIDGET_VIEW "emacs_xwidget_view" | ||