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