diff options
| author | Joakim Verona | 2010-09-15 11:34:12 +0200 |
|---|---|---|
| committer | Joakim Verona | 2010-09-15 11:34:12 +0200 |
| commit | ffce6496f1e23dbe524b8c3c0e3530cf610e1b08 (patch) | |
| tree | 9dc9d35237fc616280b31bf469848527777fe122 | |
| parent | 263063570533390c3859ad1e64c7fdcc06c8617d (diff) | |
| download | emacs-ffce6496f1e23dbe524b8c3c0e3530cf610e1b08.tar.gz emacs-ffce6496f1e23dbe524b8c3c0e3530cf610e1b08.zip | |
this doesnt actually work at all, but it does do some interesting things with composition, and contains lots of random experimental code. so i commit now, remove junk, and continue
| -rw-r--r-- | README.xwidget | 50 | ||||
| -rw-r--r-- | src/xwidget.c | 232 |
2 files changed, 169 insertions, 113 deletions
diff --git a/README.xwidget b/README.xwidget index 506e34a7866..e8617392ef5 100644 --- a/README.xwidget +++ b/README.xwidget | |||
| @@ -18,19 +18,21 @@ buffer with a display spec. Also, xwidgets exists in only one copy, | |||
| 18 | where a plain image can be shown in several windows. The xwidget code | 18 | where a plain image can be shown in several windows. The xwidget code |
| 19 | tries to handle this by essentialy making a screen capture of the | 19 | tries to handle this by essentialy making a screen capture of the |
| 20 | widget and displaying those in the non-active windows, and the live | 20 | widget and displaying those in the non-active windows, and the live |
| 21 | widget in the active window. This doesnt currently work for xembed | 21 | widget in the active window. The current snapshot code doesnt work if |
| 22 | gtk_socket widgets. | 22 | the live xwidget is off-screen. This seems to be solveable by using |
| 23 | the XComposite interface, but that doesnt currently work. | ||
| 23 | 24 | ||
| 24 | The current state is that one window, one frame, showing many xwidgets | 25 | The current state is that one window, one frame, showing many xwidgets |
| 25 | is a nice demo. One frame, many windows, will have lots of display | 26 | is a nice demo. One frame, many windows, will have lots of display |
| 26 | glitches. Many frames, many windows, will probably work even worse. | 27 | glitches. Many frames, many windows, will work even worse. |
| 28 | |||
| 27 | 29 | ||
| 28 | * Brief overview of how xwidgets work | 30 | * Brief overview of how xwidgets work |
| 29 | Xwidgets work in one way like images in Emacs. You bind a display spec very | 31 | Xwidgets work in one way like images in Emacs. You bind a display spec very |
| 30 | similar to an image display spec to buffer contents. The display engine will | 32 | similar to an image display spec to buffer contents. The display engine will |
| 31 | notice the display spec and try to display the xwidget there. The display engine | 33 | notice the display spec and try to display the xwidget there. The display engine |
| 32 | prepares space at the right place for the xwidget and so on for free, as long as | 34 | prepares space at the right place for the xwidget and so on for free, as long as |
| 33 | we provide proper sizes and so on. | 35 | we provide proper sizes and so on back to the redisplay engine. |
| 34 | 36 | ||
| 35 | The problem is that Emacs cant actually draw the widgets, as it can with | 37 | The problem is that Emacs cant actually draw the widgets, as it can with |
| 36 | images. Emacs must notify GTK about where the widgets should be, and how they | 38 | images. Emacs must notify GTK about where the widgets should be, and how they |
| @@ -50,33 +52,34 @@ synchonous with Emacs display changes. Ok, so why is that difficult then? | |||
| 50 | display is clever and optimized. It is often difficult to know that a xwdiget | 52 | display is clever and optimized. It is often difficult to know that a xwdiget |
| 51 | hasnt actually been displayed after a redisplay. | 53 | hasnt actually been displayed after a redisplay. |
| 52 | 54 | ||
| 53 | - phantom views of xwidgets are thankfully not so hard because gtk supports | 55 | - phantom views of xwidgets are thankfully not so hard because gtk |
| 54 | offscreen rendering of many widget types. Except it doesnt for the gtk socket | 56 | supports snapshoting of many widget types. Snapshoting doesnt seem |
| 55 | type, which happens to be very desirable. This might be solvable with | 57 | to work if the live widget is offscreen. This might be solvable with |
| 56 | xcomposite, but is difficult. | 58 | xcomposite, but attempts have so far failed. |
| 57 | 59 | ||
| 58 | - The gtk socket type for embedding external applications is desirable but | 60 | - The gtk socket type for embedding external applications is desirable |
| 59 | presents a lot of difficulties of its own. Offscreen rendering has been | 61 | but presents a lot of difficulties of its own. One difficulty is |
| 60 | mentioned already. Another difficulty is deciding which input events to | 62 | deciding which input events to forward, and when and how to do it. |
| 61 | forward, and when and how to do it. | ||
| 62 | 63 | ||
| 63 | - The case of showing an xwidget in several frames is not solved at all | 64 | - The case of showing an xwidget in several frames is not solved at all |
| 64 | currently. This would mean moving the live xwidget between frames when the | 65 | currently. This would mean moving the live xwidget between frames when the |
| 65 | selected window moves. The gtk widget will need to be reparented between | 66 | selected window moves. The gtk widget will need to be reparented between |
| 66 | windows, which seem fragile. | 67 | windows, which seems fragile. |
| 67 | 68 | ||
| 68 | * ToDo:s | 69 | * ToDo:s |
| 69 | 70 | ||
| 70 | ** TODO Examine using XComposite rather than GTK off-screen rendering. This | 71 | ** TODO Examine using XComposite rather than GTK off-screen |
| 71 | would make xembed widgets work much better. This would probably be | 72 | rendering. This would make xembed widgets work much better. This |
| 72 | rathter difficult, but could open up other interesting possibilities | 73 | would probably be rathter difficult, but could open up other |
| 73 | for Emacs. | 74 | interesting possibilities for Emacs. There is an early attempt in |
| 75 | xwidget.c, but the X call to redirect to offscreen rendering fails | ||
| 76 | for unknown reasons. | ||
| 74 | 77 | ||
| 75 | ** TODO make the keyboard event code propagation code work. There is an attempt | 78 | ** TODO make the keyboard event code propagation code work. There is an attempt |
| 76 | to provide an api to send keyboard events to an xwidget, but it doesnt currently | 79 | to provide an api to send keyboard events to an xwidget, but it doesnt currently |
| 77 | work very well. | 80 | work very well. |
| 78 | 81 | ||
| 79 | ** TODO remove the special-case for when the minibuffer is | 82 | ** DONE remove the special-case for when the minibuffer is |
| 80 | active. I added some code to reduce the annoying problem display artefacts | 83 | active. I added some code to reduce the annoying problem display artefacts |
| 81 | when making the minibuffer the selected window. This made xwidgets in the | 84 | when making the minibuffer the selected window. This made xwidgets in the |
| 82 | buffer go grey or black whenever one did m-x to activate the minibuffer. The | 85 | buffer go grey or black whenever one did m-x to activate the minibuffer. The |
| @@ -84,15 +87,18 @@ work very well. | |||
| 84 | good idea. Special-casing will never work properly. It is much better to spend | 87 | good idea. Special-casing will never work properly. It is much better to spend |
| 85 | time finding solutions that work acceptably in the general case. | 88 | time finding solutions that work acceptably in the general case. |
| 86 | 89 | ||
| 87 | ** TODO disable emacs cursor drawing on top of an active xwidget. | 90 | ** DONE disable emacs cursor drawing on top of an active xwidget. |
| 88 | This ought to be rather simple and should improve the visuals a lot. | 91 | This ought to be rather simple and should improve the visuals a lot. |
| 92 | |||
| 89 | 93 | ||
| 90 | ** TODO figure out what to do with the multiple frames case. | 94 | ** TODO figure out what to do with the multiple frames case. |
| 91 | I havent spent any time at all on this. | 95 | I havent spent any time at all on this. |
| 92 | 96 | ||
| 93 | ** TODO improve the xwidgets programming interface so its less of | 97 | ** TODO improve the xwidgets programming interface so its less of |
| 94 | hand-waving affair. This shouldnt be too hard, but I have deliberatley not | 98 | hand-waving affair. This shouldnt be too hard, but I have deliberatley not |
| 95 | spent any time on it, since getting the visuals right is much harder. | 99 | spent any time on it, since getting the visuals right is much |
| 100 | harder. Anyway, I sort of think the interface should be somewhat like | ||
| 101 | it is, except symbols is used instead of integers. | ||
| 96 | 102 | ||
| 97 | ** TODO more documentation | 103 | ** TODO more documentation |
| 98 | There should be user docs, and xwidget contributor docs. The current README | 104 | There should be user docs, and xwidget contributor docs. The current README |
| @@ -102,5 +108,7 @@ is all contributor docs there is now, apart from the code. | |||
| 102 | window rather than a point in a buffer. This was suggested by Chidong. | 108 | window rather than a point in a buffer. This was suggested by Chidong. |
| 103 | This would be a useful addition to Emacs in itself, and would avoid nearly all | 109 | This would be a useful addition to Emacs in itself, and would avoid nearly all |
| 104 | display issues. I still think the general case is more interesting, but this | 110 | display issues. I still think the general case is more interesting, but this |
| 105 | special case should also be added. | 111 | special case should also be added. The xwidget would then be bound to |
| 112 | replace the view of a particular window, and it would only show in | ||
| 113 | that window. | ||
| 106 | 114 | ||
diff --git a/src/xwidget.c b/src/xwidget.c index 142dda0e76f..ea32ea841ab 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -189,7 +189,7 @@ xwidget_setup_socket_composition(struct xwidget* xw) | |||
| 189 | XCompositeRedirectSubwindows( dpy, xid, | 189 | XCompositeRedirectSubwindows( dpy, xid, |
| 190 | CompositeRedirectAutomatic ); | 190 | CompositeRedirectAutomatic ); |
| 191 | 191 | ||
| 192 | 192 | ||
| 193 | /* | 193 | /* |
| 194 | XWindowAttributes attr; | 194 | XWindowAttributes attr; |
| 195 | XGetWindowAttributes( dpy, xid, &attr ); | 195 | XGetWindowAttributes( dpy, xid, &attr ); |
| @@ -226,7 +226,40 @@ xwidget_show (struct xwidget *xw) | |||
| 226 | xw->hidden = 0; | 226 | xw->hidden = 0; |
| 227 | //gtk_widget_show(GTK_WIDGET(xw->widgetwindow)); | 227 | //gtk_widget_show(GTK_WIDGET(xw->widgetwindow)); |
| 228 | gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), | 228 | gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), |
| 229 | xw->x, xw->y); | 229 | xw->x, xw->y); |
| 230 | } | ||
| 231 | |||
| 232 | |||
| 233 | xwidget_composite_draw(GtkWidget *widget, | ||
| 234 | GdkEventExpose *event, | ||
| 235 | gpointer data) | ||
| 236 | //struct xwidget *xw) | ||
| 237 | { | ||
| 238 | FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (widget), XG_FRAME_DATA); | ||
| 239 | //////////////////////////////////////////////////////////////// | ||
| 240 | //Example 7. Composited windows | ||
| 241 | GdkRegion *region; | ||
| 242 | GtkWidget *child; | ||
| 243 | cairo_t *cr; | ||
| 244 | /* get our child (in this case, the event box) */ | ||
| 245 | child = widget; //gtk_bin_get_child (GTK_BIN (widget)); | ||
| 246 | /* create a cairo context to draw to the window */ | ||
| 247 | cr = gdk_cairo_create (gtk_widget_get_window(f->gwfixed));//xw->widgetwindow));//widget->window); | ||
| 248 | /* the source data is the (composited) event box */ | ||
| 249 | gdk_cairo_set_source_pixmap (cr, child->window, | ||
| 250 | child->allocation.x, | ||
| 251 | child->allocation.y); | ||
| 252 | /* draw no more than our expose event intersects our child */ | ||
| 253 | /* region = gdk_region_rectangle (&child->allocation); | ||
| 254 | gdk_region_intersect (region, event->region); | ||
| 255 | gdk_cairo_region (cr, region); | ||
| 256 | cairo_clip (cr); */ | ||
| 257 | /* composite, with a 50% opacity */ | ||
| 258 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | ||
| 259 | cairo_paint_with_alpha (cr, 0.5);//transparency); | ||
| 260 | /* we're done */ | ||
| 261 | cairo_destroy (cr); | ||
| 262 | // return FALSE; | ||
| 230 | } | 263 | } |
| 231 | 264 | ||
| 232 | void | 265 | void |
| @@ -242,7 +275,7 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y) | |||
| 242 | case 1: | 275 | case 1: |
| 243 | xw->widget = gtk_button_new_with_label (xw->title); | 276 | xw->widget = gtk_button_new_with_label (xw->title); |
| 244 | g_signal_connect (G_OBJECT (xw->widget), "clicked", | 277 | g_signal_connect (G_OBJECT (xw->widget), "clicked", |
| 245 | G_CALLBACK (buttonclick_handler), xw); | 278 | G_CALLBACK (buttonclick_handler), xw); |
| 246 | break; | 279 | break; |
| 247 | case 2: | 280 | case 2: |
| 248 | xw->widget = gtk_toggle_button_new_with_label (xw->title); | 281 | xw->widget = gtk_toggle_button_new_with_label (xw->title); |
| @@ -252,8 +285,8 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y) | |||
| 252 | break; | 285 | break; |
| 253 | case 4: | 286 | case 4: |
| 254 | xw->widget = | 287 | xw->widget = |
| 255 | gtk_hscale_new (GTK_ADJUSTMENT | 288 | gtk_hscale_new (GTK_ADJUSTMENT |
| 256 | (gtk_adjustment_new (0, 0, 100, 1, 1, 0))); | 289 | (gtk_adjustment_new (0, 0, 100, 1, 1, 0))); |
| 257 | gtk_scale_set_draw_value (GTK_SCALE (xw->widget), FALSE); //i think its emacs role to show text and stuff, so disable the widgets own text | 290 | gtk_scale_set_draw_value (GTK_SCALE (xw->widget), FALSE); //i think its emacs role to show text and stuff, so disable the widgets own text |
| 258 | } | 291 | } |
| 259 | //widget realization | 292 | //widget realization |
| @@ -265,24 +298,30 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y) | |||
| 265 | gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); | 298 | gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); |
| 266 | gtk_container_add (xw->widgetwindow, xw->widget); | 299 | gtk_container_add (xw->widgetwindow, xw->widget); |
| 267 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, | 300 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, |
| 268 | xw->height); | 301 | xw->height); |
| 269 | gtk_fixed_put (GTK_FIXED (s->f->gwfixed), GTK_WIDGET (xw->widgetwindow), x, | 302 | gtk_fixed_put (GTK_FIXED (s->f->gwfixed), GTK_WIDGET (xw->widgetwindow), x, |
| 270 | y); | 303 | y); |
| 271 | gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow)); | 304 | gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow)); |
| 272 | 305 | ||
| 273 | //a bit inconsistent, but the rest of emacs stores stuff in the widgets, | 306 | //a bit inconsistent, but the rest of emacs stores stuff in the widgets, |
| 274 | //like frame data. in my case it might as well reside in the xwidget struct i think | 307 | //like frame data. in my case it might as well reside in the xwidget struct i think |
| 275 | g_object_set_data (G_OBJECT (xw->widget), XG_FRAME_DATA, (gpointer) (s->f)); | 308 | g_object_set_data (G_OBJECT (xw->widget), XG_FRAME_DATA, (gpointer) (s->f)); |
| 276 | 309 | ||
| 310 | //this seems to enable xcomposition. later we need to paint ourselves somehow, | ||
| 311 | //since the widget is no longer responsible for painting itself | ||
| 312 | gdk_window_set_composited (xw->widget->window, TRUE); | ||
| 313 | |||
| 314 | g_signal_connect(xw->widget, "expose-event", G_CALLBACK(xwidget_composite_draw), NULL); | ||
| 315 | |||
| 277 | //widgettype specific initialization only possible after realization | 316 | //widgettype specific initialization only possible after realization |
| 278 | switch (xw->type) | 317 | switch (xw->type) |
| 279 | { | 318 | { |
| 280 | case 3: | 319 | case 3: |
| 281 | printf ("socket id:%x %d\n", | 320 | printf ("socket id:%x %d\n", |
| 282 | gtk_socket_get_id (GTK_SOCKET (xw->widget)), | 321 | gtk_socket_get_id (GTK_SOCKET (xw->widget)), |
| 283 | gtk_socket_get_id (GTK_SOCKET (xw->widget))); | 322 | gtk_socket_get_id (GTK_SOCKET (xw->widget))); |
| 284 | send_xembed_ready_event (xw->id, | 323 | send_xembed_ready_event (xw->id, |
| 285 | gtk_socket_get_id (GTK_SOCKET (xw->widget))); | 324 | gtk_socket_get_id (GTK_SOCKET (xw->widget))); |
| 286 | break; | 325 | break; |
| 287 | } | 326 | } |
| 288 | } | 327 | } |
| @@ -293,7 +332,8 @@ void | |||
| 293 | xwidget_draw_phantom (struct xwidget *xw, | 332 | xwidget_draw_phantom (struct xwidget *xw, |
| 294 | int x, int y, | 333 | int x, int y, |
| 295 | int clipx, int clipy, | 334 | int clipx, int clipy, |
| 296 | struct glyph_string *s) | 335 | struct glyph_string *s, |
| 336 | float transparency) | ||
| 297 | { | 337 | { |
| 298 | //we cant always get real widgets, so here we try to fetch a snapshot of | 338 | //we cant always get real widgets, so here we try to fetch a snapshot of |
| 299 | //the real xwidget and paint that as a phantom image. if that fails, we | 339 | //the real xwidget and paint that as a phantom image. if that fails, we |
| @@ -309,7 +349,7 @@ xwidget_draw_phantom (struct xwidget *xw, | |||
| 309 | GdkNativeWindow p_xid; | 349 | GdkNativeWindow p_xid; |
| 310 | GdkWindow* xid; | 350 | GdkWindow* xid; |
| 311 | 351 | ||
| 312 | if (xw->type == 3 && xwidget_has_composition()){ | 352 | /* if (xw->type == 3 && xwidget_has_composition()){ |
| 313 | //its a gtk_socket, get_snapshot() doesnt work so try using composition methods | 353 | //its a gtk_socket, get_snapshot() doesnt work so try using composition methods |
| 314 | //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid); | 354 | //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid); |
| 315 | xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget)); | 355 | xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget)); |
| @@ -326,25 +366,29 @@ xwidget_draw_phantom (struct xwidget *xw, | |||
| 326 | printf("phantom other\n"); | 366 | printf("phantom other\n"); |
| 327 | xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL); | 367 | xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL); |
| 328 | } | 368 | } |
| 329 | 369 | */ | |
| 330 | if(xw_snapshot==NULL){ | 370 | #if 0 |
| 331 | printf(" xw_snapshot null for some reason ... \n"); | 371 | xw_snapshot=gdk_offscreen_window_get_pixmap(xw->widget->window); |
| 332 | return; | 372 | if(xw_snapshot==NULL){ |
| 333 | } | 373 | printf(" xw_snapshot null for some reason ... \n"); |
| 334 | 374 | /* //return; */ | |
| 335 | printf("3\n"); | 375 | } |
| 336 | gdkgc = gdk_gc_new (xw_snapshot); | 376 | gdkgc = gdk_gc_new (xw_snapshot); |
| 337 | 377 | ||
| 338 | //currently a phantom gets a line drawn across it to denote phantomness | 378 | //currently a phantom gets a line drawn across it to denote phantomness |
| 339 | //dimming or such would be more elegant | 379 | //dimming or such would be more elegant, but we cant be bothered atm |
| 340 | printf("4\n"); | 380 | gdk_draw_line (xw_snapshot, gdkgc, 0, 0, xw->width, xw->height); |
| 341 | gdk_draw_line (xw_snapshot, gdkgc, 0, 0, xw->width, xw->height); | 381 | gdk_draw_drawable (gtk_widget_get_window (s->f->gwfixed), //convert to GdkWindow from gtkWindow |
| 342 | printf("5\n"); | 382 | gdkgc, xw_snapshot, 0, 0, x, y, clipx, clipy); |
| 343 | gdk_draw_drawable (gtk_widget_get_window (s->f->gwfixed), //convert to GdkWindow from gtkWindow | 383 | #else |
| 344 | gdkgc, xw_snapshot, 0, 0, x, y, clipx, clipy); | ||
| 345 | } | ||
| 346 | 384 | ||
| 385 | xwidget_composite_draw(xw->widget, NULL, NULL); | ||
| 386 | #endif | ||
| 387 | //////////////////////////////////////////////////////////////// | ||
| 388 | |||
| 347 | 389 | ||
| 390 | //clean up here... | ||
| 391 | } | ||
| 348 | /* gtk widget reparent snippet to be used: | 392 | /* gtk widget reparent snippet to be used: |
| 349 | g_object_ref((gpointer)xw->widgetwindow); | 393 | g_object_ref((gpointer)xw->widgetwindow); |
| 350 | gtk_container_remove(GTK_CONTAINER(old_parent), xw->widgetwindow); | 394 | gtk_container_remove(GTK_CONTAINER(old_parent), xw->widgetwindow); |
| @@ -369,12 +413,12 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 369 | run so the xwidget wont know it has been moved. | 413 | run so the xwidget wont know it has been moved. |
| 370 | 414 | ||
| 371 | Solved temporarily by never optimizing in try_window_reusing_current_matrix(). | 415 | Solved temporarily by never optimizing in try_window_reusing_current_matrix(). |
| 372 | 416 | ||
| 373 | BUG the phantoming code doesnt work very well when the live xwidget is off screen. | 417 | BUG the phantoming code doesnt work very well when the live xwidget is off screen. |
| 374 | you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is | 418 | you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is |
| 375 | always available in an off-screen buffer. My current attempt at composition doesnt work properly however. | 419 | always available in an off-screen buffer. My current attempt at composition doesnt work properly however. |
| 376 | 420 | ||
| 377 | 421 | ||
| 378 | */ | 422 | */ |
| 379 | int box_line_hwidth = eabs (s->face->box_line_width); | 423 | int box_line_hwidth = eabs (s->face->box_line_width); |
| 380 | int box_line_vwidth = max (s->face->box_line_width, 0); | 424 | int box_line_vwidth = max (s->face->box_line_width, 0); |
| @@ -384,7 +428,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 384 | //TODO drawing_in_selected_window can be true for several windows if we have several frames. | 428 | //TODO drawing_in_selected_window can be true for several windows if we have several frames. |
| 385 | //we also need to check that the xwidget is to be drawn inside a window on a frame where it originaly lives. | 429 | //we also need to check that the xwidget is to be drawn inside a window on a frame where it originaly lives. |
| 386 | //otherwise draw a phantom, or maybe reparent the xwidget. | 430 | //otherwise draw a phantom, or maybe reparent the xwidget. |
| 387 | 431 | ||
| 388 | struct xwidget *xw = &xwidgets[s->xwidget_id]; | 432 | struct xwidget *xw = &xwidgets[s->xwidget_id]; |
| 389 | int clipx; int clipy; | 433 | int clipx; int clipy; |
| 390 | 434 | ||
| @@ -412,27 +456,31 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 412 | if (drawing_in_selected_window) | 456 | if (drawing_in_selected_window) |
| 413 | { | 457 | { |
| 414 | if ((xw->x != x) || (xw->y != y)) //has it moved? | 458 | if ((xw->x != x) || (xw->y != y)) //has it moved? |
| 415 | { | 459 | { |
| 416 | printf ("xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y); | 460 | printf ("xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y); |
| 417 | } | 461 | } |
| 418 | else | 462 | else |
| 419 | { | 463 | { |
| 420 | } | 464 | } |
| 421 | //TODO maybe theres a bug that the hidden flag sometimes dont get reset properly | 465 | //TODO maybe theres a bug that the hidden flag sometimes dont get reset properly |
| 422 | if (!xwidget_hidden(xw)) //hidden equals not being seen in the live window | 466 | if (!xwidget_hidden(xw)) //hidden equals not being seen in the live window |
| 423 | { | 467 | { |
| 424 | gtk_fixed_move (GTK_FIXED (s->f->gwfixed), | 468 | gtk_fixed_move (GTK_FIXED (s->f->gwfixed), |
| 425 | GTK_WIDGET (xw->widgetwindow), x, y); | 469 | GTK_WIDGET (xw->widgetwindow), x, y); |
| 426 | //clip the widget window if some parts happen to be outside drawable area | 470 | //clip the widget window if some parts happen to be outside drawable area |
| 427 | //an emacs window is not a gtk window, a gtk window covers the entire frame | 471 | //an emacs window is not a gtk window, a gtk window covers the entire frame |
| 428 | gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow), clipx, | 472 | gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow), clipx, |
| 429 | clipy); | 473 | clipy); |
| 430 | } | 474 | |
| 475 | //if we are using compositing, we are always responsible for drawing the widget on the screen | ||
| 476 | //just reuse the phantom routine for now | ||
| 477 | xwidget_draw_phantom (xw, x, y, clipx, clipy, s, 1.0); | ||
| 478 | } | ||
| 431 | else | 479 | else |
| 432 | { | 480 | { |
| 433 | //xwidget is hidden, hide it offscreen somewhere, still realized, so we may snapshot it | 481 | //xwidget is hidden, hide it offscreen somewhere, still realized, so we may snapshot it |
| 434 | //gtk_fixed_move(GTK_FIXED(s->f->gwfixed),GTK_WIDGET(xw->widgetwindow) ,10000,10000); | 482 | //gtk_fixed_move(GTK_FIXED(s->f->gwfixed),GTK_WIDGET(xw->widgetwindow) ,10000,10000); |
| 435 | } | 483 | } |
| 436 | //xw refers to the *live* instance of the xwidget | 484 | //xw refers to the *live* instance of the xwidget |
| 437 | xw->x = x; | 485 | xw->x = x; |
| 438 | xw->y = y; | 486 | xw->y = y; |
| @@ -442,7 +490,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 442 | else | 490 | else |
| 443 | { | 491 | { |
| 444 | //ok, we are painting the xwidgets in non-selected window, so draw a phantom | 492 | //ok, we are painting the xwidgets in non-selected window, so draw a phantom |
| 445 | xwidget_draw_phantom (xw, x, y, clipx, clipy, s); | 493 | xwidget_draw_phantom (xw, x, y, clipx, clipy, s, 0.1); |
| 446 | 494 | ||
| 447 | } | 495 | } |
| 448 | 496 | ||
| @@ -494,7 +542,7 @@ DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_inte | |||
| 494 | xw->height=h; | 542 | xw->height=h; |
| 495 | gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); | 543 | gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); |
| 496 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, | 544 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, |
| 497 | xw->height); | 545 | xw->height); |
| 498 | return Qnil; | 546 | return Qnil; |
| 499 | } | 547 | } |
| 500 | 548 | ||
| @@ -598,7 +646,7 @@ xwidget_key_send_message (struct frame *f, | |||
| 598 | event.state = modifiers; | 646 | event.state = modifiers; |
| 599 | 647 | ||
| 600 | XSendEvent (event.display, event.window, TRUE, KeyPressMask, | 648 | XSendEvent (event.display, event.window, TRUE, KeyPressMask, |
| 601 | (XEvent *) & event); | 649 | (XEvent *) & event); |
| 602 | } | 650 | } |
| 603 | 651 | ||
| 604 | //using "accessible" interfaces seems expensive | 652 | //using "accessible" interfaces seems expensive |
| @@ -662,7 +710,7 @@ syms_of_xwidget (void) | |||
| 662 | Qxwidget_info = intern ("xwidget-info"); | 710 | Qxwidget_info = intern ("xwidget-info"); |
| 663 | staticpro (&Qxwidget_info); | 711 | staticpro (&Qxwidget_info); |
| 664 | defsubr (&Sxwidget_info); | 712 | defsubr (&Sxwidget_info); |
| 665 | 713 | ||
| 666 | Qxwidget_resize_internal = intern ("xwidget-resize-internal"); | 714 | Qxwidget_resize_internal = intern ("xwidget-resize-internal"); |
| 667 | staticpro (&Qxwidget_resize_internal); | 715 | staticpro (&Qxwidget_resize_internal); |
| 668 | defsubr (&Sxwidget_resize_internal); | 716 | defsubr (&Sxwidget_resize_internal); |
| @@ -757,7 +805,7 @@ xwidget_hide (struct xwidget *xw) | |||
| 757 | xw->hidden = 1; | 805 | xw->hidden = 1; |
| 758 | //gtk_widget_hide(GTK_WIDGET(xw->widgetwindow)); | 806 | //gtk_widget_hide(GTK_WIDGET(xw->widgetwindow)); |
| 759 | gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), | 807 | gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), |
| 760 | 10000, 10000); | 808 | 10000, 10000); |
| 761 | } | 809 | } |
| 762 | 810 | ||
| 763 | 811 | ||
| @@ -781,11 +829,11 @@ xwidget_spec_value ( | |||
| 781 | CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail))) | 829 | CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail))) |
| 782 | { | 830 | { |
| 783 | if (EQ (XCAR (tail), key)) | 831 | if (EQ (XCAR (tail), key)) |
| 784 | { | 832 | { |
| 785 | if (found) | 833 | if (found) |
| 786 | *found = 1; | 834 | *found = 1; |
| 787 | return XCAR (XCDR (tail)); | 835 | return XCAR (XCDR (tail)); |
| 788 | } | 836 | } |
| 789 | } | 837 | } |
| 790 | 838 | ||
| 791 | if (found) | 839 | if (found) |
| @@ -835,7 +883,7 @@ lookup_xwidget (Lisp_Object spec) | |||
| 835 | 883 | ||
| 836 | 884 | ||
| 837 | printf ("xwidget_id:%d type:%d found:%d %d %d title:%s (%d,%d)\n", id, | 885 | printf ("xwidget_id:%d type:%d found:%d %d %d title:%s (%d,%d)\n", id, |
| 838 | xw->type, found, found1, found2, xw->title, xw->height, xw->width); | 886 | xw->type, found, found1, found2, xw->title, xw->height, xw->width); |
| 839 | 887 | ||
| 840 | 888 | ||
| 841 | assert_valid_xwidget_id (id, "lookup_xwidget"); | 889 | assert_valid_xwidget_id (id, "lookup_xwidget"); |
| @@ -908,35 +956,35 @@ xwidget_end_redisplay (struct glyph_matrix *matrix) | |||
| 908 | struct glyph_row *row; | 956 | struct glyph_row *row; |
| 909 | row = MATRIX_ROW (matrix, i); | 957 | row = MATRIX_ROW (matrix, i); |
| 910 | if (row->enabled_p != 0) | 958 | if (row->enabled_p != 0) |
| 911 | { | 959 | { |
| 912 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | 960 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) |
| 913 | { | 961 | { |
| 914 | struct glyph *glyph = row->glyphs[area]; | 962 | struct glyph *glyph = row->glyphs[area]; |
| 915 | struct glyph *glyph_end = glyph + row->used[area]; | 963 | struct glyph *glyph_end = glyph + row->used[area]; |
| 916 | for (; glyph < glyph_end; ++glyph) | 964 | for (; glyph < glyph_end; ++glyph) |
| 917 | { | 965 | { |
| 918 | if (glyph->type == XWIDGET_GLYPH) | 966 | if (glyph->type == XWIDGET_GLYPH) |
| 919 | { | 967 | { |
| 920 | //printf("(%d)",glyph->u.xwidget_id); | 968 | //printf("(%d)",glyph->u.xwidget_id); |
| 921 | //here the id sometimes sucks, so maybe the desired glyph matrix isnt ready here? | 969 | //here the id sometimes sucks, so maybe the desired glyph matrix isnt ready here? |
| 922 | //also, it appears the desired matrix is not the entire window, but only the changed part. wtf? | 970 | //also, it appears the desired matrix is not the entire window, but only the changed part. wtf? |
| 923 | int id = glyph->u.xwidget_id; | 971 | int id = glyph->u.xwidget_id; |
| 924 | if (id < 0 || id > MAX_XWIDGETS) | 972 | if (id < 0 || id > MAX_XWIDGETS) |
| 925 | { | 973 | { |
| 926 | printf | 974 | printf |
| 927 | ("glyph matrix contains crap, abort xwidget handling and wait for better times\n "); | 975 | ("glyph matrix contains crap, abort xwidget handling and wait for better times\n "); |
| 928 | //dump_glyph_matrix(matrix, 2); | 976 | //dump_glyph_matrix(matrix, 2); |
| 929 | return; | 977 | return; |
| 930 | } | 978 | } |
| 931 | else | 979 | else |
| 932 | { | 980 | { |
| 933 | // printf("row %d not enabled\n", i); | 981 | // printf("row %d not enabled\n", i); |
| 934 | } | 982 | } |
| 935 | xwidget_touch (&xwidgets[glyph->u.xwidget_id]); | 983 | xwidget_touch (&xwidgets[glyph->u.xwidget_id]); |
| 936 | } | 984 | } |
| 937 | } | 985 | } |
| 938 | } | 986 | } |
| 939 | } | 987 | } |
| 940 | } | 988 | } |
| 941 | 989 | ||
| 942 | for (i = 0; i < MAX_XWIDGETS; i++) | 990 | for (i = 0; i < MAX_XWIDGETS; i++) |
| @@ -985,11 +1033,11 @@ xwidget_invalidate (void) | |||
| 985 | { | 1033 | { |
| 986 | xw = &xwidgets[i]; | 1034 | xw = &xwidgets[i]; |
| 987 | if (xw->initialized) | 1035 | if (xw->initialized) |
| 988 | { | 1036 | { |
| 989 | printf ("%d,", i); | 1037 | printf ("%d,", i); |
| 990 | gtk_widget_queue_draw_area (xw->widget, 0, 0, xw->width, | 1038 | gtk_widget_queue_draw_area (xw->widget, 0, 0, xw->width, |
| 991 | xw->height); | 1039 | xw->height); |
| 992 | } | 1040 | } |
| 993 | } | 1041 | } |
| 994 | printf ("\n"); | 1042 | printf ("\n"); |
| 995 | } | 1043 | } |