]> code.delx.au - gnu-emacs/blob - README.xwidget
4cb0f704195b241bf913fc899ae7685d56b37528
[gnu-emacs] / README.xwidget
1 * Xwidgets
2
3 This is an experimental branch to enable embedding of GTK widgets
4 inside an Emacs window. The Emacs abstraction is called an Xwidget,
5 for eXternal widget, and also in reference to the Xembed protocoll.
6
7 There is a demo file called xwidget-test.el which shows some of the
8 possibilities. There are some screnshots at the emacswiki.
9
10 Currently its possible to insert buttons, sliders, and xembed widgets
11 in the buffer. It works similar to the support for images in Emacs.
12 Adding more types of widgets should be fairly straightforward, but
13 will require adapter code for each type.
14
15 A difference from images is that xwidgets live their own life. You
16 create them with an api, get a reference, and tie them to a particular
17 buffer with a display spec.
18
19 Each xwidget can have several views. In MVC terms, an xwidget is the
20 model, and an xwidget-view is a view of the xwidget in a particular
21 Emacs window.
22
23 The xwidget code attempts to keep the visual appearance of the views
24 in sync with through an Observer pattern implementation.
25
26 ** building
27 bzr co bzr+ssh://bzr.savannah.gnu.org/emacs/xwidget/
28 export CFLAGS=" -g -DGLYPH_DEBUG=1"
29 #export CFLAGS="-g"
30 ./configure --with-x-toolkit=gtk3 --with-xwidgets
31 make -j4
32
33 ** MVC and Xembedd
34 The MVC approach appears to be at least in principle robust for plain gtk
35 widgets. For the interesting case of gtk sockets which implements an
36 xembed host widget that allows for embedding other applications inside
37 an Emacs window, the story gets more complex.
38
39 The problem is that xembed is designed to plug an application window
40 inside a a secket and thats it. You can't move a plug between
41 sockets. I tried numerous hacks to get around this but there is
42 nothing that works realy well.
43
44 Therefore the Emacs part of the code will only expose well-defined
45 interfaces. cooperating applications will be able to use the interface
46 in a well defined manner. The problem is that there is no known xembeddable
47 application that implement the needed type of functionality, which is
48 allowing for creating new windows on the fly that plug into new
49 sockets.
50
51 Therefore I will attempt to provide an external application that wraps
52 another application and through hacks attempts to provide the needed
53 multi view xembed function. That way Emacs is sane and the insanity
54 contained.
55
56 This app will work by providing a socket that an app plugs into. The
57 socket window is copied efficientlp by means of composition to a
58 number of other windows, that then are plugged into the different
59 Emacs sockets.
60
61 * Brief overview of how xwidgets work
62 Xwidgets work in one way like images in Emacs. You bind a display spec very
63 similar to an image display spec to buffer contents. The display engine will
64 notice the display spec and try to display the xwidget there. The display engine
65 prepares space at the right place for the xwidget and so on for free, as long as
66 we provide proper sizes and so on back to the redisplay engine.
67
68 ** Issues
69 The problem is that Emacs cant actually draw the widgets, as it can with
70 images. Emacs must notify GTK about where the widgets should be, and how they
71 should be clipped and so on, and this information must be given to GTK
72 synchonous with Emacs display changes. Ok, so why is that difficult then?
73
74 - How do we know when a widget is NOT to be drawn? The only way I found so far
75 is having a flag for each xwdiget, that is reset before a redisplay. When an
76 xwidget is encountered during display, the flag is set. After redisplay,
77 iterate all xwidgets and hide those which hasnt been displayed.
78
79 - The gtk socket type for embedding external applications is desirable
80 but presents a lot of difficulties of its own. One difficulty is
81 deciding which input events to forward, and when and how to do it.
82
83 ** placement and clipping
84 the entire emacs frame is a gtk window. we use the fixed layout
85 manager to place xwidgets on the frame. coordinates are supplied by
86 the emacs display engine. widgets are placed inside an intermediate
87 window, called the widgetwindow. the widgetwindows are placed on the
88 emacs frame.
89
90 this way was chosen to simplify clipping of the widgets against emacs
91 window borders.
92
93
94 ** different strategies
95 Integrating toolkit widgets(gtk in this case) and the emacs display
96 engine is more difficult than your plain average gui application, and
97 different strategies has been tested and will continue to be tested.
98
99 There was a distinction between live xwidgets and
100 phantom xwidgets, previous to the change to MVC.
101
102 - the first aproach was to have the live xwidget on-screen, and move
103 them about. the phantoms were generated by snapshoting the live
104 xwidget.
105
106 the drawback of that aproach was that the gtk toolkit is admirably
107 lazy and doesnt draw the widget if its not actualy shown, meaning that
108 the snapshots for the phantoms will show garbage.
109
110 - the second aproach was to use composition support. that tells gtk
111 that the widget should be drawn in an off-screen buffer and drawn on
112 screen by the application.
113
114 this has the primary advantage that the snapshot is always
115 available, and enables the possibility of more eye-candy like drawing
116 live and phantom widgets in different colors.
117
118 the drawback is that its our own responsibility to handle drawing,
119 which puts more of the display optimization burden on us.
120
121 this is aproach worked so-so.
122
123 - another aproach is to have both live and phantom widgets drawn
124 on-screen by proxy gtk objects. the live xwidget will be entirely
125 handled in an off-screen window, and the proxy objects will redirect
126 events there.
127
128 - combine on-screen and off-screen aproaches. maybe composition is the
129 way to go for most cases, but on-screen xembeding is the way to go
130 for particular special cases, like showing video in a
131 window. off-screen rendering and whatnot, is not efficient in that
132 particular case, and the user will simply have to accept that the
133 phantom of a video widget isnt particularily beautiful.
134
135 - The current and seemingly sanest aproach implements a MVC pattern.
136
137 ** Testing
138 ;;test like:
139 ;; cd /path/to/xwidgets-emacs-dir
140 ;; make all&& src/emacs -q --eval "(progn (load \"`pwd`/lisp/xwidget-test.el\") (xwidget-demo-basic))"
141
142 * ToDo:s
143 ** DONE webkit flashkiller by default
144 CLOSED: [2011-07-19 Tue 14:27]
145 while its possible to support plugins in the webkit xwidget, flash has
146 issues on 64 bit, and slows down emacs to a halt with off screen
147 rendering, and of course is not free software. its in the way for real
148 world usage even if its interesting to watch flash animations inside
149 emacs. which should be achieved with Gnash or other free software
150 instead.
151
152 http://stackoverflow.com/questions/4885513/prevent-flash-in-cocoa-webview
153
154 simply use this api:
155 http://webkitgtk.org/reference/WebKitWebPluginDatabase.html
156
157 ** DONE allow xwidgets to report thoir size
158 CLOSED: [2011-07-19 Tue 14:26]
159 now we just hard code sizes. but webkit widgets for instance can
160 report sizes that suit the content. support that.
161 ** TODO BUG xwidget view ghosts
162 - xwidget-webkit-browse-url somewhere
163 - split window.
164 now theres 2 webkit views
165 - c-x 1
166 now theres 2 views but one is a ghost!
167 one should have been deleted when its window died but that didnt work
168 for some reason here.
169
170 - m-x xwidget-cleanup
171
172 the ghost goes away because we killed explicitly but this is just a workaround.
173
174 xwidget_view_delete_all_in_window(w); in delete-window-internal is not sufficient.
175 delete-other-windows-internal
176 delete_all_subwindows
177 unshow_buffer
178
179 ** DONE BUG annoying backtrace
180 CLOSED: [2011-07-19 Tue 14:28]
181 (this no longer seems to happen even under heavy usage. seems merging
182 from trunk helped. lots were happening in redisplay at this time in trunk.)
183
184 sadly happens a lot.
185 - happens even with no initialized xwidgets
186 - + row->glyphs[area][i].face_id
187 or similar code, so row is invalid for some reason.
188 xwidgets currently disable some redisplay opimizations so it might be
189 an actual emacs bug manifesting without optimizations.
190
191 *** bt 1
192 /* Compute the width of this line. */
193 row->pixel_width = row->x;
194 for (i = 0; i < row->used[TEXT_AREA]; ++i)
195 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
196
197 (gdb) bt
198 #0 0x000000000045c340 in compute_line_metrics (it=0x7fffffff8a20)
199 at xdisp.c:17549
200 #1 0x00000000004603da in display_line (it=0x7fffffff8a20) at xdisp.c:18792
201 #2 0x0000000000457646 in try_window (window=23403045, pos=..., flags=1)
202 at xdisp.c:15399
203 #3 0x00000000004559c9 in redisplay_window (window=23403045, just_this_one_p=0)
204 at xdisp.c:14944
205 #4 0x0000000000450247 in redisplay_window_0 (window=23403045) at xdisp.c:13152
206 #5 0x00000000005fdcd9 in internal_condition_case_1 (bfun=
207 0x450208 <redisplay_window_0>, arg=23403045, handlers=12691046, hfun=
208 0x4501d9 <redisplay_window_error>) at eval.c:1538
209 #6 0x00000000004501ba in redisplay_windows (window=23403045) at xdisp.c:13132
210 #7 0x000000000044f19c in redisplay_internal () at xdisp.c:12706
211 #8 0x000000000044f9f2 in redisplay_preserve_echo_area (from_where=7)
212 at xdisp.c:12964
213 #9 0x0000000000568525 in swallow_events (do_display=1) at keyboard.c:4197
214 #10 0x0000000000422554 in sit_for (timeout=40, reading=1, do_display=1)
215 at dispnew.c:5963
216 #11 0x000000000056512c in read_char (commandflag=1, nmaps=8, maps=
217 0x7fffffffd3f0, prev_event=12720514, used_mouse_menu=0x7fffffffd604,
218 end_time=0x0) at keyboard.c:2689
219 #12 0x0000000000572c59 in read_key_sequence (keybuf=0x7fffffffd850, bufsize=
220 30, prompt=12720514, dont_downcase_last=0, can_return_switch_frame=1,
221 ---Type <return> to continue, or q <return> to quit---
222 fix_current_buffer=1) at keyboard.c:9291
223 #13 0x0000000000562897 in command_loop_1 () at keyboard.c:1446
224 #14 0x00000000005fdb52 in internal_condition_case (bfun=
225 0x5624b4 <command_loop_1>, handlers=12772898, hfun=0x561dab <cmd_error>)
226 at eval.c:1493
227 #15 0x00000000005621ab in command_loop_2 (ignore=12720514) at keyboard.c:1157
228 #16 0x00000000005fd4ce in internal_catch (tag=12768770, func=
229 0x562185 <command_loop_2>, arg=12720514) at eval.c:1247
230 #17 0x000000000056215e in command_loop () at keyboard.c:1136
231 #18 0x00000000005618f9 in recursive_edit_1 () at keyboard.c:757
232 #19 0x0000000000561a95 in Frecursive_edit () at keyboard.c:821
233 #20 0x000000000055fba2 in main (argc=1, argv=0x7fffffffe188) at emacs.c:1704
234
235
236 *** bt 2
237
238 ** DONE Examine using XComposite rather than GTK off-screen
239 rendering. This would make xembed widgets work much better. This
240 would probably be rathter difficult, but could open up other
241 interesting possibilities for Emacs. There is an early attempt in
242 xwidget.c, but the X call to redirect to offscreen rendering fails
243 for unknown reasons.
244
245 the attempt was further worked on, and the xlib calls replaced with
246 gdk calls, this works better.
247
248 ** TODO make the keyboard event code propagation code work.
249 There is an attempt to provide an api to send keyboard events to an
250 xwidget, but it doesnt currently work very well.
251
252 try gtk event creation instead since that works fine in the webkit osr code.
253
254 ** DONE remove the special-case for when the minibuffer is
255 active. I added some code to reduce the annoying problem display artefacts
256 when making the minibuffer the selected window. This made xwidgets in the
257 buffer go grey or black whenever one did m-x to activate the minibuffer. The
258 coded tried to handle the minibuffer as a special case. That simply wasnt a
259 good idea. Special-casing will never work properly. It is much better to spend
260 time finding solutions that work acceptably in the general case.
261
262 ** DONE disable emacs cursor drawing on top of an active xwidget.
263 This ought to be rather simple and should improve the visuals a lot.
264
265 ** TODO improve the xwidgets programming interface
266 so its less of hand-waving affair. This shouldnt be too hard, but I
267 have deliberatley not spent any time on it, since getting the
268 visuals right is much harder. Anyway, I sort of think the interface
269 should be somewhat like it is, except symbols is used instead of
270 integers.
271 *** DONE use symbols for xwidget types rather than ints
272 CLOSED: [2011-06-27 Mon 12:52]
273
274
275 *** TODO better lisp based structure for xwidgets
276 the lisp interface woud be like this:
277 - make-xwidget returns an xwidget object, similar to a process
278 object. this object is used when creating the display spec(instead of
279 the user defined id now used)
280
281 the data structure would be something like this:
282 - a "process" like aproach to create the xwidgets. xwidgets are
283 coupled to buffers, somewhat like processes, except a buffer can
284 hold several xwidgets
285 - an xwidget has a plist to hold the model, like a process
286 - an xwidget has an assoc list of xwidget views
287
288 there are some things that arent clear:
289 - an xwidget doesnt necessarily need to be coupled to a buffer but it
290 seems to be the clearest model. xwidgets would be buffer local
291 - xwidget-views are by necessity coupled to a emacs window so it might
292 be better to store them window locally rather than in an assoc
293 coupled to the xwidget model
294 - for some gtk widgets that resist an mvc approach, like the webkit
295 widgets, special operations are needed, similar to the old phantom
296 widgets aproach. so we need to differentiate live and phantom
297 instances for these troublesome widgets and let lisp manage all the trickery.
298
299 stuff that needs to work:
300 - do something for all views of a xwidget(resize, value change)
301 - do something for all xw-views in an emacs window(deletion etc)
302 - lookup xw-view for xwidget in emacs window(during redisplay)
303 (- do something for all siblings of a xw-view. not atm)
304
305 *** DONE xwidget creation interface
306 CLOSED: [2011-07-18 Mon 01:59]
307 xwidgets are a little bit like emacs processes but also a little bit
308 like emacs images. Therefore its not perfectly obvious how to handle
309 creation. Currently I just use hardcoded identifiers. the real scheme
310 needs to be something else.
311
312 Heres a tentative approach:
313 - xwidget-create returns a xwidget object, like process creation
314 functions. the xwidget will be largely uninitialized until
315 discovered by redisplay. an xw belongs to a buffer
316 - xwidget-insert inserts the xwidget in a buffer. when discovered by
317 redisplay it will be initialized and a xwidget-view allocated
318 - an event will be emitted when initialization is finished when
319 relevant like for sockets
320
321 the problem with this aproach is that its not really legal to reuse
322 xwidget objects by writing several display specs who reference the
323 same xwidget. It could presumably be done but it would just become
324 weird for no real benefit. the big preblem is that the display spec
325 decides the on-screen size, and its not sane to have xwidget views
326 with different sizes. therefore such display specs would need to be
327 catched and dissallowed. Except it is hard because AFAIK the specs
328 don't have an identity as such. A flag in the structure could be set
329 by lookup so the first display attempt would win. but then you can't
330 rewrite the spec to change the size. hmmm. A third approach would be
331 to just allow the 1st spec refering an xw during a redisplay to take
332 effect, the rest are signaled as errors. this wouldnt be too bad.
333
334 the other aproach would be to work more like images:
335
336 - write the display spec with all information needed to create the
337 xwidget.
338 - retrieve the xwidget objet from the spec with an xwidget-at-point function. It
339 can be uninitalized which client code must handle. Unlike
340 assynchronous process creation we dont get back a handle, because
341 there is none yet.
342 - emitted event on initialization, when needed. Many widgets don't
343 need this. for instance, a button sends an event when pressed. but
344 you can't press it unless its on screen, and then its initialized
345 properly.
346
347 This approach seemed good, but how do I know which instance
348 generates an event if I cant set the id beforehand?
349
350 so, therefore, the first two aproach is used.
351
352
353 *** DONE xwidget creation interface actually
354 CLOSED: [2011-07-18 Mon 01:59]
355 conclusion of above ramblings:
356 - should be similar to make-text-button
357 - don't init from display spec, instead during make-xwidget call
358 *** TODO callbacks would be nice
359 but they need to be handled initially with events for technical
360 reasons. C code can't call Lisp easily. The event handler can call the
361 callback though.
362
363 ** TODO more documentation
364 There should be user docs, and xwidget contributor docs. The current README
365 is all contributor docs there is now, apart from the code.
366
367
368
369 ** CANCELLED look into more ways of displaying xwidgets, like binding them to a
370 CLOSED: [2011-07-05 Tue 11:34]
371 window rather than a point in a buffer. This was suggested by Chidong.
372 This would be a useful addition to Emacs in itself, and would avoid nearly all
373 display issues. I still think the general case is more interesting, but this
374 special case should also be added. The xwidget would then be bound to
375 replace the view of a particular window, and it would only show in
376 that window.
377
378 I got the webkit xwidget to work well enough so I dont see the need
379 for this now, except for sockets and I think it can better be dealt
380 with at the lisp level.
381
382 ** DONE MVC mode for xwidgets
383 CLOSED: [2011-06-27 Mon 12:53]
384 It appears unfruitful to chase using the same display mode for all
385 types of xwidgets. Composition is fun but not robust the way I'm
386 tried to do it.
387
388 Instead there should be a set of MVC xwidgets. Each on-screen instance
389 of an MVC widget would be a real GTK widget. The instances would
390 communciate state using signals.
391
392 There are drawbacks. There is no inbuilt support for MVC in GTK, so we
393 have to roll our own, which is tedious if not much work for the few
394 cases.
395
396 MVC for xembedded application will need support from the applications
397 themselves. Inkscape supports multiple views to the same document,
398 other programs don't. In practice it might not be a big drawback.
399
400
401 *** DONE figure out what to do with the multiple frames case.
402 CLOSED: [2011-06-27 Mon 12:52]
403 This should be easier to solve with MVC.
404 Surprisingly, this just worked!
405 *** DONE how to propagate changes in views to other views?
406 CLOSED: [2011-06-27 Mon 12:53]
407 I used gtk signals, the implementation for sliders works well!
408
409 ** TODO canvas support
410 heresy an interesting comparision of gtk canvases
411 http://live.gnome.org/ProjectRidley/CanvasOverview
412 *** goocanvas
413 goocanvas is a gtk canvas implemented using cairo. investigate.
414
415 pros:
416 - it has a MVC model aproach out of the box which is nice.
417
418 http://developer.gnome.org/goocanvas/unstable/goocanvas-model-view-canvas.html
419
420 export CFLAGS="`pkg-config --cflags goocanvas` -DHAVE_GOOCANVAS"
421 export LDFLAGS=`pkg-config --libs goocanvas`
422 ./configure
423 make
424
425 I made a hello goo world xwidget so seems doable.
426 I wanted to load a SVG which wasnt immediately straightforward, so I
427 tried clutter. but it turns out the exact same strategy could be used
428 with goocanvas.
429
430 *** clutter
431 maybe clutter can be used as a canvas?
432 pros:
433 - seems to have a lot of traction atm. many examples
434 - potentialy fast and cool vector graphics
435 cons:
436 - no out of the box MVC support, but seems doable. no worse than the
437 other home brew mvc support I have in xwidgets
438 (media-explorer in an application that employes the MVC pattern)
439
440 http://www.openismus.com/documents/clutter_tutorial/0.9/docs/tutorial/html/sec-stage-widget.html
441
442 there is also cool stuff like this:
443 http://gitorious.org/webkit-clutter/webkit-clutter which is an webkit actor for
444 clutter! hmmmmm.
445
446 I want to render svg. aparently:
447 librsvg rsvg_handle_render_cairo(h, cr);
448 ClutterCairoTexture
449 Clutter
450
451 export CFLAGS="`pkg-config --cflags clutter-gtk-1.0` -DHAVE_CLUTTER"
452 export LDFLAGS=`pkg-config --libs clutter-gtk-1.0`
453 ./configure
454 make
455
456 compiles but I get:
457 Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in
458 the same process is not supported
459
460 export CFLAGS="`pkg-config --cflags clutter-gtk-0.10` -DHAVE_CLUTTER"
461 export LDFLAGS=`pkg-config --libs clutter-gtk-0.10`
462 ./configure
463 make
464
465
466 ** DONE mvc code crashes after a while
467 CLOSED: [2011-07-12 Tue 18:52]
468 seemingly only when compiling with optimizations.
469 I have no idea why.
470
471 Doesn't seem to happen after some code cleanups.
472 ** DONE xwidget-resize-at
473 CLOSED: [2011-07-19 Tue 14:28]
474 reimplement so display spec is not involved
475 ** DONE display spec validation
476 CLOSED: [2011-07-19 Tue 14:44]
477 it is an error to reuse xwidgets in several buffers or in the same
478 buffer. how do we catch these errors?
479 - showing the same xwidget twice in a buffer is no more wrong than
480 showing in several emacs windows, just conceptually wrong, so ignore
481 this case for now
482 - xwidgets now store a reference to the buffer they were created in,
483 so use that to invalidate xwidget references in oher buffers. but
484 thats not really an error either
485 - xwidgets should now be proper lisp objects so you dont delete them
486 you await their garbage collection. so therefore there can never be
487 invalid disploy specs
488
489 so turned out this got solved by using proper lisp objects for
490 xwidgets. yay!
491
492
493 ** TODO browser xwidget
494 although embedding a browser is not my primary concern many are
495 interested in this. some suitable browser component needs to be found
496 supporting gtk.
497
498 *** DONE webkit
499 CLOSED: [2011-07-03 Sun 22:13]
500 there is a webkit gtk port. there is no obvious mvc support.
501 http://live.gnome.org/WebKitGtk
502 http://webkitgtk.org/
503
504 it might be possible to keep a set of webxits in artificial
505 synchronisation by recursive deep copy of the DOM from one webkit to
506 another. This will be error prone at best though. Another way might be
507 to just use bitmap copy of the "live"instance to the "phantom"
508 instances. the problem of transfering the live view remains though.
509
510 export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT -g"
511 export LDFLAGS=`pkg-config --libs webkit-1.0`
512 ./configure
513 make
514
515 **** off screen rendering
516 export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT_OSR -g"
517 export LDFLAGS=`pkg-config --libs webkit-1.0`
518 ./configure
519 make
520
521 works a little bit but i get errors like:
522
523 (emacs:8362): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11'
524
525 set a breakpoint in g_log, backtrace seems to indicate
526 webkitViewportAttributesRecompute is the offender.
527
528 maybe try gtk3 variants?
529
530 export CFLAGS="`pkg-config --cflags webkitgtk-3.0 ` -DHAVE_WEBKIT_OSR "
531 export LDFLAGS=`pkg-config --libs webkitgtk-3.0 `
532 ./configure --with-x-toolkit=gtk3
533 make
534
535 crash in gtk_window_get_size instead. great.
536
537 http://gtkplus-p3.0.sourcearchive.com/documentation/2.91.5-0ubuntu1/testoffscreenwindow_8c-source.html
538
539 after many atempts, the basic issue remains. for some reason the
540 offscreen widget isnt ok when I want to snapshot it, so i simply get
541 emptiness. the surface is only ok someimes.
542
543 here is a useful debugging snippets:
544 // debugging redraw:
545 // - the bg colors always change, so theres no error in signal handling
546 // - i get this error now and then:
547 //(emacs:7109): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11'
548 // seems to happen in webkit actually. see README
549
550 if(0){ //redraw debug hack. helped a lot in fact. use the with alpha painter below also
551 cairo_set_source_rgb(cr, osr_dbg_color, 1.0, 0.2);
552 cairo_rectangle(cr, 0,0, xw->width, xw->height);
553 cairo_fill(cr);
554 osr_dbg_color+=0.1;
555 if(osr_dbg_color>1.0)
556 osr_dbg_color=0.0;
557
558 }
559
560 you need to terminate drawing like this:
561
562 //cairo_set_source_surface (cr, src_pixmap, 0,0);
563 //cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
564
565 //cairo_paint_with_alpha (cr, 1.0);
566 //cairo_paint(cr);
567
568 the snippets change background color on oach redraw.
569
570 **** on-screen rendering to separate window
571 an alternative might be to open a separate window and snapshot it. the
572 idea is that whatever oddness webkit does so that offscreen rendering
573 doesnt work, doesnt happen on-screen. the window could be opened
574 somewhere not in the way.
575
576 *** CANCELLED firefox
577 CLOSED: [2011-07-03 Sun 22:13]
578 http://www-archive.mozilla.org/unix/gtk-embedding.html
579 seems to be severly bitrotted
580
581 heres a newer aproach
582 http://hg.mozilla.org/incubator/embedding/file/29ac0fe51754/gtk/tests/test.cpp
583
584 while webkit clearly has the best traction as an embeddee, the
585 offscreen rendering issues makes it interesting to see what ff brings
586 to the table. turns out webkit has as good offscreen support as anyone.
587
588
589 *** TODO text field support
590 Emacs captures all keyboard events so text field support isn't super
591 straightforward.
592
593 **** propagate keyboard events
594 I have some old hacks for this and they are not good.
595 **** use the DOM model
596 expose document.activeElement to lisp. This is potentially more
597 interesting than just forwarding keyboard events.
598
599 webkit_web_view_get_dom_document ()
600
601 this is hard it seems. an idea might be to hack elisp support for swig
602 to machine generate the bindings.
603 **** DONE inject javascript
604 CLOSED: [2011-07-03 Sun 22:50]
605 webkit_web_view_execute_script ()
606
607 this works now:
608 (xwidget-webkit-execute-script 5 "document.activeElement.value='test'")
609
610 so it should be possible to do some interesting stuff.
611 execute-script does however not return anything at the interface level
612 so satisfaction is not total:
613
614 http://markmail.org/message/4yowmdgras73z3x5
615
616 maybe
617 https://launchpad.net/gnome-seed
618
619 or this funny hack:
620 <jave> im trying to understanh how to interact via javascript to an embedded
621 webkit gtk instance [23:38]
622 <jave> i use webkit_web_view_execute_script() which is nice but doesnt return
623 a value, by design aparently [23:39]
624 <jave> any hints?
625 <lucian> jave: afaik, webkit still doesn't have full gobject bindings [23:48]
626 <lucian> jave: you can hack it up by making the JS modify the title, and read
627 the title from gtk-side
628 <jave> lucian: that was a pretty cool idea!
629
630
631 *** webkit_web_view_load_string ()
632 I would like preview of html in a buffer rather than from uri.
633
634
635
636 *** TODO simple xwidget-webkit wrapper
637 so that it could be used for actual browsing :)
638 I dont want to reinvent too many wheels so i'd like to use existing
639 emacs facilities here possible. use bindings similar to w3m(or info)
640
641 - m-x xwidget-webkit starts a session
642 - 'g' goes to a url
643 - use bookmark-jump i suppose. I mostly use org for bookmarks myself
644 - browse-url support so webkit can be the default browser
645 - some way of getting around the quirky keyboard interaction since
646 xwidgets dont receive keyboard events because I hawe no idea how to
647 do that in a sane way
648
649 ... and one can of course go on bikeshedding forever. lets keep it
650 simple and extensible, and compatible with other Emacs packages.
651
652 the really cool ideas would need Emacs DOM integration, which is not
653 easy.
654
655 ** DONE clipping of controllers
656 CLOSED: [2011-07-05 Tue 11:33]
657
658 Emacs uses a big GTK window and does its own clipping against Emacs
659 windows inside this area. So, in order to layout gtk widgets in emacs
660 windows we must clip thim ourselves.
661
662 The following method worked well for a long time:
663 - make a gtk widget, say a button, xw
664 - make a clipping area, of type gtkfixed(many types have been tested)
665 - put the clip area in the main emacs gtk window
666 - figure out clip area changes during emacs redisplay
667
668 the only weirdness was that one has to tell gtk the clip area has a
669 window in order to get clipping. This is weird because all gtkwidgets
670 are windows in a sense and a window is almost by definition also a
671 clipping area.
672
673 Anyway, in GTK3 the gtk_widget_set_has_window(GTK_WIDGET (
674 xv->widgetwindow), TRUE); call is ignored.
675
676 The gtkeventbox which is documented to have its own window doesnt work
677 either.
678
679 http://www.lanedo.com/~carlos/gtk3-doc/chap-drawing-model.html
680
681 anyway clipping is rather complicated but seems to finally work okay.
682
683 *** DONE subclass my own clipping widget
684 CLOSED: [2011-07-04 Mon 16:55]
685 http://www.lanedo.com/~carlos/gtk3-doc/GtkWidget.html#gtk-widget-set-has-window
686 mentions that it has_window can only be called inside a widget
687 impementation.
688
689 this wasnt really the issue. allocation was the problem
690 *** DONE try scrolled window
691 CLOSED: [2011-07-01 Fri 10:56]
692 clipping does in fact work with
693 gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget);
694 !!
695
696 I get unwanted scrollbars in the widget though.
697
698 gtk_scrolled_window_set_policy ( xv->widgetwindow,
699 GTK_POLICY_NEVER, GTK_POLICY_NEVER);
700
701 stops clipping from working!
702
703
704 *** DONE try viewport
705 CLOSED: [2011-07-01 Fri 10:56]
706 gtkviewport is used in scrolled window so in order to remove
707 scrollbars it should be possible to use viewport directly. however,
708 viewport ignores size requests. or rather the container does.
709
710
711 *** DONE debug allocation
712 CLOSED: [2011-07-04 Mon 16:56]
713 the container determines how much size to allocate to child widgets.
714
715 GtkAllocation galloc;
716 gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc);
717 printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height);
718
719 after my clipping attemp shows that my size request is ignored! this
720 might be logical, since the container provided by emacs is a
721 gtkfixed. gtkfixed might choose to heed the widgets size desires and
722 allocate the entire widget size. but we want clipping!
723
724 since i cant reasonably expect to change the emacs main container, i
725 can maybe overide the setallocation method in gwfixed, and adjust
726 allocation to clipping if its an xwidget asking for allocation.
727
728 **** DONE subclass gtkfixed
729 CLOSED: [2011-07-04 Mon 16:56]
730 possibly i need to subclass gtkfixed and override
731
732 void gtk_widget_size_allocate (GtkWidget *widget,
733 GtkAllocation *allocation);
734
735 http://developer.gnome.org/gobject/stable/howto-gobject.html
736
737 turns out emacs already does this for gtk3 according to jan D:
738 >>For GTK3, Emacs already subclasses GtkFixed, see emacsgtkfixed.[ch].
739
740 - widgets may not be underallocated, aparently
741 http://mail.gnome.org/archives/commits-list/2011-April/msg10950.html
742
743 - how to call base class method/chain up
744 http://developer.gnome.org/gobject/stable/howto-gobject-chainup.html
745
746 - the allocation modification could happen in the container or the
747 child. it feels more apropiate in the container
748
749 it is however unexpectedy inconvenient to modify allocation because
750 the needed data is private to the base class. to overcome this:
751
752 - run base class method 1st.
753 - then, iterate all children, and modify allocation for xwidget
754 children only. x y will then be set.
755
756 JanD pointed out the GTK3 port already has its own subclass, so I
757 modified that one.
758
759 *** DONE clip top
760 CLOSED: [2011-07-05 Tue 11:30]
761 there are four controller edges that potentialy need clipping. I begun
762 with right and bottom edges. clipping them is just a matter of setting
763 the right size of the widgetwindow and also ensure it gets the right
764 allocation from the container.
765
766 clipping top (and left) is not equally straightforward. I'm using a
767 viewport now and scroll it the amount that needs to be clipped.
768 however, the viewport is sensitive to changes in allocation, which
769 makes it harder to use the allocation workarounds.
770
771 see:
772 - gtk_widget_set_size_request
773 - gtkscrolledwindow
774
775 I returned to using a simple gtkfixed for the widgetwindow. with
776 allocation hack and set_has_window it works. Idea prefer not to have
777 the allocatien hack and it wasnt needed it gtk3 only gtk2. needs
778 furthi investigation,
779
780 ** TODO various code cleanups
781 There are many cleanups necessary before any hope of inclusion in
782 Emacs trunk. To begin with, the part of the patch that touches other
783 parts of emacs must be very clean.
784 *** TODO use FRAME_GTK_WIDGET (f)
785 rather than gwfixed.
786
787 *** DONE support configure
788 CLOSED: [2011-07-12 Tue 18:48]
789 ** DONE translate clicks
790 CLOSED: [2011-07-03 Sun 22:12]
791 on onscreen webkit peer to offscreen
792
793 maybe
794 http://developer.gnome.org/gdk/stable/gdk-Windows.html#GdkWindow-from-embedder
795
796 turned out to be not so hard, captured events, copied them and
797 forwarded them offscreen!
798
799 ** TODO investigate gdk_window_redirect_to_drawable
800 http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-offscreen-window-set-embedder
801 maybe control be used in place of my own copy hacks? to work it must
802 support a chain of redirects, which seems unlikely. the benefit would
803 be that I dont have to spend time optimizing redrawing.
804
805
806
807 ** DONE remove xwidget_views when emacs window is deleted
808 CLOSED: [2011-07-05 Tue 11:29]
809 removing xwidget views when an Emacs window closes is not reliable.
810
811 - switching buffers in a window seems to hide the corresponding
812 xwidget-views properly, but they might as well be deleted.
813
814 - patching delete-window-internal could be used to delete the xwidget-views
815 this seems to work
816
817
818 ** TODO support webkit signals
819 particularily document-load-finished
820 http://webkitgtk.org/reference/webkitgtk-webkitwebview.html#WebKitWebView-document-load-finished
821 ** notes from x_draw_xwidget_glyph_string
822
823 BUG it seems this method for some reason is called with bad s->x and s->y sometimes.
824 When this happens the xwidget doesnt move on screen as it should.
825 This mightbe because of x_scroll_run. Emacs decides to scroll the screen by blitting sometimes.
826 then emacs doesnt try to actualy call the paint routines, which means this here code will never
827 run so the xwidget wont know it has been moved.
828
829 Solved temporarily by never optimizing in try_window_reusing_current_matrix().
830
831 BUG the phantoming code doesnt work very well when the live xwidget is off screen.
832 you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is
833 always available in an off-screen buffer. My current attempt at composition doesnt work properly however.
834
835 //allocation debugging. the correct values cant be expected to show upp immediately, but eventually they should get to be ok
836 // this is because we dont know when the container gets around to doing layout
837 //GtkAllocation galloc;
838 //gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc);
839 //printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height);
840
841
842 *** old notes about the old live/phantom scheme
843
844 //TODO:
845 // 1) always draw live xwidget in slected window
846 // (2) if there were no live instances of the xwidget in selected window, also draw it live)
847 // 3) if there was a live xwidget previously, now phantom it.
848
849 else
850 {
851 //ok, we are painting the xwidgets in non-selected window, so draw a phantom
852 //printf("draw phantom xwidget at:%d %d\n",x,y);
853 //xwidget_composite_draw_phantom (xw, x, y, clipx, clipy); //TODO MVC there will be very few cases of phantoming
854 }
855
856
857 atm this works as follows: only check if xwidgets are displayed in the
858 "selected window". if not, hide them or phantom them.
859
860 this means valid cases like xwidgets being displayed only once in
861 non-selected windows, does not work well. they should also be visible
862 in that case not phantomed.