]> code.delx.au - gnu-emacs/blob - README.xwidget
conflict resolve
[gnu-emacs] / README.xwidget
1 -*-org-*-
2 * Xwidgets
3
4 This is an experimental branch to enable embedding of GTK widgets
5 inside an Emacs window. The Emacs abstraction is called an Xwidget,
6 for eXternal widget, and also in reference to the Xembed protocoll.
7
8 There is a demo file called xwidget-test.el which shows some of the
9 possibilities. There are some screnshots at the emacswiki.
10
11 Currently its possible to insert buttons, sliders, xembed widgets, and
12 webkit in the buffer. It works similar to the support for images in
13 Emacs. Adding more types of widgets should be fairly straightforward,
14 but will require adapter code for each type.
15
16 A difference from images is that xwidgets live their own life. You
17 create them with an api, get a reference, and tie them to a particular
18 buffer with a display spec.
19
20 Each xwidget can have several views. In MVC terms, an xwidget is the
21 model, and an xwidget-view is a view of the xwidget in a particular
22 Emacs window.
23
24 The xwidget code attempts to keep the visual appearance of the views
25 in sync with through an Observer pattern implementation. This is
26 necessary to support the Emacs window paradigm.
27
28 ** building
29 bzr co bzr+ssh://bzr.savannah.gnu.org/emacs/xwidget/
30 #the below compiler flags shouldn't be strictly necessary
31 export CFLAGS=" -g"
32 ./configure --with-xwidgets --enable-asserts --with-x-toolkit=gtk3
33 make -j4
34 gdb -ex run src/emacs
35
36 ** try it out
37 If you have GTK3 and gtk-webkit installed, you should be able to
38 start the embedded webkit browser now:
39
40 M-X xwidget-webkit-browse-url
41
42 If that didnt work out try the minimal demonstration instead:
43
44 (load-library "xwidget-test")
45 (xwidget-demo-a-button)
46
47 It looks unimpressive, but it's a gtk button inside an Emacs buffer!
48 *** webkit hints
49 If you got webkit working, great! Please note, though, that the
50 current support is far from a full fledged browser. My focus is on
51 delivering a component that can be used to build a full emacs based
52 browser on. Since I implement a browse-url function you can get quite
53 far just by:
54
55 (setq browse-url-browser-function 'xwidget-webkit-browse-url)
56
57 then all Emacs browser interface systems work to a degree.
58 heres stuff I use currenly
59
60 - m-x anything-surfraw interfaces to search engines
61 - C-o in org mode opens links inside org
62 - m-x ffap opens links anywhere in a buffer
63 - m-x gtk-lookup-symbol searches gtk docs
64 - m-x bookmark-jump
65 etc..
66
67 I'll add more examples as I go along.
68
69 However theres lots of support missing, see TODO list for
70 information. Briefly:
71 - download handling
72 - keyboard field navigation
73 - isearch
74 - history
75 - sites that use flash. I dont really care about this issue so its
76 unlikely to be fixed. Just a heads up.
77
78 ** Stability
79 Beginning with Summer 2011 I am now able to use Xwidget Emacs as my
80 primary Emacs. That is good for the project and the stability of the
81 code.
82
83 At the time of writing I have 24 hour Emacs uptime with several
84 embedded webkit browsers, Gnus, org-mode, tramp, etc. etc.
85
86 That said, there are still many improvements that needs to be done,
87 particularily in memory management. Expect xwidget emacs to leak
88 heavily for now.
89
90 ** timeline for inclusion in trunk
91 The Emacs 24 feature freeze is passed, so xwidgets won't probably be merged
92 until Emacs 25. OTOH since I now use xwidget emacs as my primary
93 emacs, I will merge from trunk much more often than in the past.
94
95 ** reporting bugs
96 emacs xwidgets uses the same tracker as mainline emacs, but a
97 different package.
98
99 m-x report-emacs-bug
100
101 Change the address to:
102 submit@debbugs.gnu.org
103
104 Include this line first in the body:
105 Package: emacs-xwidgets
106
107 browse bugs:
108 http://debbugs.gnu.org/cgi/pkgreport.cgi?package=emacs-xwidgets
109 ** Thanks
110 emacs-devel@gnu.org. There are very helpful people there. When I
111 started the xwidget project I had no clue about the Emacs internals.
112
113 * Brief overview of how xwidgets work
114 Xwidgets work in one way like images in Emacs. You bind a display spec very
115 similar to an image display spec to buffer contents. The display engine will
116 notice the display spec and try to display the xwidget there. The display engine
117 prepares space at the right place for the xwidget and so on for free, as long as
118 we provide proper sizes and so on back to the redisplay engine.
119
120 ** Issues
121 The problem is that Emacs cant actually draw the widgets, as it can with
122 images. Emacs must notify GTK about where the widgets should be, and how they
123 should be clipped and so on, and this information must be given to GTK
124 synchonous with Emacs display changes. Ok, so why is that difficult then?
125
126 - How do we know when a widget is NOT to be drawn? The only way I found so far
127 is having a flag for each xwdiget, that is reset before a redisplay. When an
128 xwidget is encountered during display, the flag is set. After redisplay,
129 iterate all xwidgets and hide those which hasnt been displayed.
130
131 - The gtk socket type for embedding external applications is desirable
132 but presents a lot of difficulties of its own. One difficulty is
133 deciding which input events to forward, and when and how to do it.
134
135 ** placement and clipping
136 the entire emacs frame is a gtk window. we use the fixed layout
137 manager to place xwidgets on the frame. coordinates are supplied by
138 the emacs display engine. widgets are placed inside an intermediate
139 window, called the widgetwindow. the widgetwindows are placed on the
140 emacs frame.
141
142 this way was chosen to simplify clipping of the widgets against emacs
143 window borders.
144
145
146 ** different strategies
147 Integrating toolkit widgets(gtk in this case) and the emacs display
148 engine is more difficult than your plain average gui application, and
149 different strategies has been tested and will continue to be tested.
150
151 There was a distinction between live xwidgets and
152 phantom xwidgets, previous to the change to MVC.
153
154 - the first aproach was to have the live xwidget on-screen, and move
155 them about. the phantoms were generated by snapshoting the live
156 xwidget.
157
158 the drawback of that aproach was that the gtk toolkit is admirably
159 lazy and doesnt draw the widget if its not actualy shown, meaning that
160 the snapshots for the phantoms will show garbage.
161
162 - the second aproach was to use composition support. that tells gtk
163 that the widget should be drawn in an off-screen buffer and drawn on
164 screen by the application.
165
166 this has the primary advantage that the snapshot is always
167 available, and enables the possibility of more eye-candy like drawing
168 live and phantom widgets in different colors.
169
170 the drawback is that its our own responsibility to handle drawing,
171 which puts more of the display optimization burden on us.
172
173 this is aproach worked so-so.
174
175 - another aproach is to have both live and phantom widgets drawn
176 on-screen by proxy gtk objects. the live xwidget will be entirely
177 handled in an off-screen window, and the proxy objects will redirect
178 events there.
179
180 - combine on-screen and off-screen aproaches. maybe composition is the
181 way to go for most cases, but on-screen xembeding is the way to go
182 for particular special cases, like showing video in a
183 window. off-screen rendering and whatnot, is not efficient in that
184 particular case, and the user will simply have to accept that the
185 phantom of a video widget isnt particularily beautiful.
186
187 - The current and seemingly sanest aproach implements a MVC pattern.
188
189 ** Testing
190 ;;test like:
191 ;; cd /path/to/xwidgets-emacs-dir
192 ;; make all&& src/emacs -q --eval "(progn (load \"`pwd`/lisp/xwidget-test.el\") (xwidget-demo-basic))"
193
194 ** MVC and Xembedd
195 The MVC approach appears to be at least in principle robust for plain gtk
196 widgets. For the interesting case of gtk sockets which implements an
197 xembed host widget that allows for embedding other applications inside
198 an Emacs window, the story gets more complex.
199
200 The problem is that xembed is designed to plug an application window
201 inside a a secket and thats it. You can't move a plug between
202 sockets. I tried numerous hacks to get around this but there is
203 nothing that works realy well.
204
205 Therefore the Emacs part of the code will only expose well-defined
206 interfaces. cooperating applications will be able to use the interface
207 in a well defined manner. The problem is that there is no known xembeddable
208 application that implement the needed type of functionality, which is
209 allowing for creating new windows on the fly that plug into new
210 sockets.
211
212 Therefore I will attempt to provide an external application that wraps
213 another application and through hacks attempts to provide the needed
214 multi view xembed function. That way Emacs is sane and the insanity
215 contained.
216
217 This app will work by providing a socket that an app plugs into. The
218 socket window is copied efficientlp by means of composition to a
219 number of other windows, that then are plugged into the different
220 Emacs sockets.
221 ** old notes from x_draw_xwidget_glyph_string
222
223 BUG it seems this method for some reason is called with bad s->x and s->y sometimes.
224 When this happens the xwidget doesnt move on screen as it should.
225 This mightbe because of x_scroll_run. Emacs decides to scroll the screen by blitting sometimes.
226 then emacs doesnt try to actualy call the paint routines, which means this here code will never
227 run so the xwidget wont know it has been moved.
228
229 Solved temporarily by never optimizing in try_window_reusing_current_matrix().
230
231 BUG the phantoming code doesnt work very well when the live xwidget is off screen.
232 you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is
233 always available in an off-screen buffer. My current attempt at composition doesnt work properly however.
234
235 //allocation debugging. the correct values cant be expected to show upp immediately, but eventually they should get to be ok
236 // this is because we dont know when the container gets around to doing layout
237 //GtkAllocation galloc;
238 //gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc);
239 //printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height);
240
241
242 *** old notes about the old live/phantom scheme
243
244 //TODO:
245 // 1) always draw live xwidget in slected window
246 // (2) if there were no live instances of the xwidget in selected window, also draw it live)
247 // 3) if there was a live xwidget previously, now phantom it.
248
249 else
250 {
251 //ok, we are painting the xwidgets in non-selected window, so draw a phantom
252 //printf("draw phantom xwidget at:%d %d\n",x,y);
253 //xwidget_composite_draw_phantom (xw, x, y, clipx, clipy); //TODO MVC there will be very few cases of phantoming
254 }
255
256
257 atm this works as follows: only check if xwidgets are displayed in the
258 "selected window". if not, hide them or phantom them.
259
260 this means valid cases like xwidgets being displayed only once in
261 non-selected windows, does not work well. they should also be visible
262 in that case not phantomed.
263
264 * ToDo:s
265 ** TODO optimize drawing off large offscreen widgets
266 Currently I just allocate as large an area as the offscreen widget
267 desires. This works well most of the time. But a HTML page might in
268 principle be of infinite height so there will probably be cases where
269 this doesn't work too well.
270 ** DONE again a trace
271 CLOSED: [2011-10-28 Fri 13:48]
272 [2011-08-23 Tue]
273 the hunch is that since I still hand-wave the view storage the array
274 can get out of synchronous. so maybe switching to a lisp structure
275 will help as it did for the model. Anyway, doesnt happen at all often.
276 *** the trace
277 (gdb) bt
278 #0 0x0000000000685304 in xwidget_touch (xv=0x0) at xwidget.c:1225
279 #1 0x00000000006853e7 in xwidget_end_redisplay (w=0x11b42ca0, matrix=
280 0xff9bf40) at xwidget.c:1272
281 #2 0x000000000041cc31 in update_window (w=0x11b42ca0, force_p=0)
282 at dispnew.c:3705
283 #3 0x000000000041c0e5 in update_window_tree (w=0x11b42ca0, force_p=0)
284 at dispnew.c:3331
285 #4 0x000000000041be8b in update_frame (f=0x1682a50, force_p=0,
286 inhibit_hairy_id_p=0) at dispnew.c:3258
287 #5 0x000000000045066f in redisplay_internal () at xdisp.c:12931
288 #6 0x000000000044e210 in redisplay () at xdisp.c:12110
289 #7 0x0000000000567e65 in read_char (commandflag=1, nmaps=7, maps=
290 0x7fffffffc040, prev_event=12708226, used_mouse_menu=0x7fffffffc254,
291 end_time=0x0) at keyboard.c:2447
292 #8 0x000000000057613c in read_key_sequence (keybuf=0x7fffffffc4a0, bufsize=
293 30, prompt=12708226, dont_downcase_last=0, can_return_switch_frame=1,
294 fix_current_buffer=1) at keyboard.c:9299
295 #9 0x0000000000565d45 in command_loop_1 () at keyboard.c:1448
296 #10 0x0000000000601008 in internal_condition_case (bfun=
297 0x565962 <command_loop_1>, handlers=12760466, hfun=0x565259 <cmd_error>)
298 at eval.c:1490
299 #11 0x0000000000565659 in command_loop_2 (ignore=12708226) at keyboard.c:1159
300 #12 0x0000000000600992 in internal_catch (tag=12873826, func=
301 ---Type <return> to continue, or q <return> to quit---
302 0x565633 <command_loop_2>, arg=12708226) at eval.c:1247
303 #13 0x00000000005655bd in command_loop () at keyboard.c:1124
304 #14 0x0000000000564da7 in recursive_edit_1 () at keyboard.c:759
305 #15 0x0000000000564f43 in Frecursive_edit () at keyboard.c:823
306 #16 0x000000000060444f in Ffuncall (nargs=1, args=0x7fffffffca20)
307 at eval.c:2986
308 #17 0x00000000006507f8 in exec_byte_code (bytestr=145172929, vector=145179445,
309 maxdepth=116, args_template=12708226, nargs=0, args=0x0) at bytecode.c:785
310 #18 0x0000000000604eec in funcall_lambda (fun=140575909, nargs=2, arg_vector=
311 0x7fffffffcfe8) at eval.c:3220
312 #19 0x000000000060467e in Ffuncall (nargs=3, args=0x7fffffffcfe0)
313 at eval.c:3038
314 #20 0x00000000006035fc in Fapply (nargs=2, args=0x7fffffffd0b0) at eval.c:2494
315 #21 0x0000000000603b43 in apply1 (fn=12874242, arg=301666310) at eval.c:2732
316 #22 0x00000000005feb25 in call_debugger (arg=301666310) at eval.c:220
317 #23 0x0000000000601ca9 in maybe_call_debugger (conditions=9431542, sig=
318 12761282, data=301666742) at eval.c:1893
319 #24 0x0000000000601785 in Fsignal (error_symbol=12761282, data=301666742)
320 at eval.c:1714
321 #25 0x0000000000601898 in xsignal (error_symbol=12761282, data=301666742)
322 at eval.c:1749
323 #26 0x0000000000601926 in xsignal2 (error_symbol=12761282, arg1=102756373,
324 arg2=0) at eval.c:1770
325 ---Type <return> to continue, or q <return> to quit---
326 #27 0x0000000000604d6e in funcall_lambda (fun=102756373, nargs=0, arg_vector=
327 0x7fffffffd398) at eval.c:3189
328 #28 0x000000000060467e in Ffuncall (nargs=1, args=0x7fffffffd390)
329 at eval.c:3038
330 #29 0x00000000006507f8 in exec_byte_code (bytestr=54783137, vector=109656229,
331 maxdepth=12, args_template=12708226, nargs=0, args=0x0) at bytecode.c:785
332 #30 0x0000000000604eec in funcall_lambda (fun=109656517, nargs=0, arg_vector=
333 0x7fffffffd890) at eval.c:3220
334 #31 0x000000000060467e in Ffuncall (nargs=1, args=0x7fffffffd888)
335 at eval.c:3038
336 #32 0x0000000000603b08 in apply1 (fn=109656517, arg=12708226) at eval.c:2725
337 #33 0x00000000005fc8c9 in Fcall_interactively (function=109656517, record_flag=
338 12708226, keys=12754549) at callint.c:379
339 #34 0x00000000006044c2 in Ffuncall (nargs=4, args=0x7fffffffdc60)
340 at eval.c:2996
341 #35 0x0000000000603c57 in call3 (fn=12893554, arg1=109656517, arg2=12708226,
342 arg3=12708226) at eval.c:2789
343 #36 0x00000000005784cd in Fcommand_execute (cmd=109656517, record_flag=
344 12708226, keys=12708226, special=12708226) at keyboard.c:10290
345 #37 0x00000000005661fb in command_loop_1 () at keyboard.c:1575
346 #38 0x0000000000601008 in internal_condition_case (bfun=
347 0x565962 <command_loop_1>, handlers=12760466, hfun=0x565259 <cmd_error>)
348 at eval.c:1490
349 ---Type <return> to continue, or q <return> to quit---
350 #39 0x0000000000565659 in command_loop_2 (ignore=12708226) at keyboard.c:1159
351 #40 0x0000000000600992 in internal_catch (tag=12756258, func=
352 0x565633 <command_loop_2>, arg=12708226) at eval.c:1247
353 #41 0x000000000056560c in command_loop () at keyboard.c:1138
354 #42 0x0000000000564da7 in recursive_edit_1 () at keyboard.c:759
355 #43 0x0000000000564f43 in Frecursive_edit () at keyboard.c:823
356 #44 0x0000000000563052 in main (argc=1, argv=0x7fffffffe678) at emacs.c:1711
357
358 Lisp Backtrace:
359 "recursive-edit" (0xffffca28)
360 "debug" (0xffffcfe8)
361 "image-bol" (0xffffd398)
362 0x68939c0 PVEC_COMPILED
363 "call-interactively" (0xffffdc68)
364 (gdb)
365
366
367 ** DONE new annoying trace
368 CLOSED: [2011-08-13 Sat 16:16]
369 maybe related to scroll inhibiting or cursor inhibiting code.
370 It appears actually to be related to GLYPH_DEBUG=1. this flag is no
371 longer needed.
372 *** the trace
373 Breakpoint 1, abort () at emacs.c:383
374 383 kill (getpid (), SIGABRT);
375 Missing separate debuginfos, use: debuginfo-install hunspell-1.2.15-2.fc15.x86_64 nss-mdns-0.10-9.fc15.x86_64
376 (gdb)
377 (gdb)
378 (gdb) bt
379 #0 abort () at emacs.c:383
380 #1 0x0000000000418f01 in matrix_row (matrix=0xac29400, row=-1)
381 at dispnew.c:1477
382 #2 0x000000000046e113 in draw_glyphs (w=0x18235c0, x=198, row=0xa3af100, area=
383 TEXT_AREA, start=17, end=18, hl=DRAW_CURSOR, overlaps=0) at xdisp.c:22550
384 #3 0x000000000047869f in draw_phys_cursor_glyph (w=0x18235c0, row=0xa3af100,
385 hl=DRAW_CURSOR) at xdisp.c:24882
386 #4 0x00000000005083bb in x_draw_window_cursor (w=0x18235c0, glyph_row=
387 0xa3af100, x=180, y=361, cursor_type=0, cursor_width=1, on_p=1, active_p=1)
388 at xterm.c:7440
389 #5 0x00000000004790cd in display_and_set_cursor (w=0x18235c0, on=1, hpos=17,
390 vpos=19, x=180, y=361) at xdisp.c:25098
391 #6 0x00000000004fa31f in x_update_window_end (w=0x18235c0, cursor_on_p=1,
392 mouse_face_overwritten_p=0) at xterm.c:644
393 #7 0x000000000041ccb9 in update_window (w=0x18235c0, force_p=0)
394 at dispnew.c:3694
395 #8 0x000000000041c165 in update_window_tree (w=0x18235c0, force_p=0)
396 at dispnew.c:3331
397 #9 0x000000000041beee in update_frame (f=0x1658460, force_p=0,
398 inhibit_hairy_id_p=0) at dispnew.c:3258
399 #10 0x0000000000450a2e in redisplay_internal () at xdisp.c:12983
400 #11 0x000000000044e2a6 in redisplay () at xdisp.c:12099
401 #12 0x000000000056a60d in read_char (commandflag=1, nmaps=6, maps=
402
403 ** DONE allow xwidgets to report their size
404 CLOSED: [2011-07-19 Tue 14:26]
405 now we just hard code sizes. but webkit widgets for instance can
406 report sizes that suit the content. support that.
407 ** TODO BUG xwidget view ghosts
408 - xwidget-webkit-browse-url somewhere
409 - split window.
410 now theres 2 webkit views
411 - c-x 1
412 now theres 2 views but one is a ghost!
413 one should have been deleted when its window died but that didnt work
414 for some reason here.
415
416 - m-x xwidget-cleanup
417
418 the ghost goes away because we killed explicitly but this is just a workaround.
419
420 xwidget_view_delete_all_in_window(w); in delete-window-internal is not sufficient.
421 delete-other-windows-internal
422 delete_all_subwindows
423 unshow_buffer
424
425 Added cleanup those window configuration hook which works in practice
426 but feels kludgy.
427
428 *** code looks like this
429
430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
431 (defun xwidget-cleanup ()
432 "Delete zombie xwidgets."
433 ;;its still pretty easy to trigger bugs with xwidgets.
434 ;;this function tries to implement a workaround
435 (interactive)
436 (xwidget-delete-zombies) ;;kill xviews who should have been deleted but stull linger
437 (redraw-display);;redraw display otherwise ghost of zombies will remain to haunt the screen
438 )
439
440
441
442 ;;this is a workaround because I cant find the right place to put it in C
443 ;;seems to work well in practice though
444 (add-hook 'window-configuration-change-hook 'xwidget-cleanup)
445
446 *** but it ought rather to work like this
447 xwidget-delete-zombies should be called from C after window
448 configuration has changed but before redisplay. redisplay should not
449 be called.
450
451
452 ** DONE BUG annoying backtrace
453 CLOSED: [2011-07-19 Tue 14:28]
454 (this no longer seems to happen even under heavy usage. seems merging
455 from trunk helped. lots were happening in redisplay at this time in trunk.)
456
457 sadly happens a lot.
458 - happens even with no initialized xwidgets
459 - + row->glyphs[area][i].face_id
460 or similar code, so row is invalid for some reason.
461 xwidgets currently disable some redisplay opimizations so it might be
462 an actual emacs bug manifesting without optimizations.
463
464 *** bt 1
465 /* Compute the width of this line. */
466 row->pixel_width = row->x;
467 for (i = 0; i < row->used[TEXT_AREA]; ++i)
468 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
469
470 (gdb) bt
471 #0 0x000000000045c340 in compute_line_metrics (it=0x7fffffff8a20)
472 at xdisp.c:17549
473 #1 0x00000000004603da in display_line (it=0x7fffffff8a20) at xdisp.c:18792
474 #2 0x0000000000457646 in try_window (window=23403045, pos=..., flags=1)
475 at xdisp.c:15399
476 #3 0x00000000004559c9 in redisplay_window (window=23403045, just_this_one_p=0)
477 at xdisp.c:14944
478 #4 0x0000000000450247 in redisplay_window_0 (window=23403045) at xdisp.c:13152
479 #5 0x00000000005fdcd9 in internal_condition_case_1 (bfun=
480 0x450208 <redisplay_window_0>, arg=23403045, handlers=12691046, hfun=
481 0x4501d9 <redisplay_window_error>) at eval.c:1538
482 #6 0x00000000004501ba in redisplay_windows (window=23403045) at xdisp.c:13132
483 #7 0x000000000044f19c in redisplay_internal () at xdisp.c:12706
484 #8 0x000000000044f9f2 in redisplay_preserve_echo_area (from_where=7)
485 at xdisp.c:12964
486 #9 0x0000000000568525 in swallow_events (do_display=1) at keyboard.c:4197
487 #10 0x0000000000422554 in sit_for (timeout=40, reading=1, do_display=1)
488 at dispnew.c:5963
489 #11 0x000000000056512c in read_char (commandflag=1, nmaps=8, maps=
490 0x7fffffffd3f0, prev_event=12720514, used_mouse_menu=0x7fffffffd604,
491 end_time=0x0) at keyboard.c:2689
492 #12 0x0000000000572c59 in read_key_sequence (keybuf=0x7fffffffd850, bufsize=
493 30, prompt=12720514, dont_downcase_last=0, can_return_switch_frame=1,
494 ---Type <return> to continue, or q <return> to quit---
495 fix_current_buffer=1) at keyboard.c:9291
496 #13 0x0000000000562897 in command_loop_1 () at keyboard.c:1446
497 #14 0x00000000005fdb52 in internal_condition_case (bfun=
498 0x5624b4 <command_loop_1>, handlers=12772898, hfun=0x561dab <cmd_error>)
499 at eval.c:1493
500 #15 0x00000000005621ab in command_loop_2 (ignore=12720514) at keyboard.c:1157
501 #16 0x00000000005fd4ce in internal_catch (tag=12768770, func=
502 0x562185 <command_loop_2>, arg=12720514) at eval.c:1247
503 #17 0x000000000056215e in command_loop () at keyboard.c:1136
504 #18 0x00000000005618f9 in recursive_edit_1 () at keyboard.c:757
505 #19 0x0000000000561a95 in Frecursive_edit () at keyboard.c:821
506 #20 0x000000000055fba2 in main (argc=1, argv=0x7fffffffe188) at emacs.c:1704
507
508
509 *** bt 2
510
511 ** DONE Examine using XComposite rather than GTK off-screen
512 rendering. This would make xembed widgets work much better. This
513 would probably be rathter difficult, but could open up other
514 interesting possibilities for Emacs. There is an early attempt in
515 xwidget.c, but the X call to redirect to offscreen rendering fails
516 for unknown reasons.
517
518 the attempt was further worked on, and the xlib calls replaced with
519 gdk calls, this works better.
520
521 In the end I abandoned this aproach. Xwidget-osr is the new aproach.
522
523 ** TODO make the keyboard event code propagation code work.
524 There is an attempt to provide an api to send keyboard events to an
525 xwidget, but it doesnt currently work very well.
526
527 *** TODO try gtk event creation instead
528 since that works fine in the webkit osr code.
529 but, oh no, that didn't work for some reason.
530 the widgets seems to receive the event but then the embedded widgets
531 hangs.
532
533 http://kegel.com/gtk/button.c
534
535 *** TODO examine some library to synthesise events
536 xdotool
537 xte xautomation
538 crikey
539 libxdo
540
541 *** TODO webkit raw keyboard event escape
542 c-c tab could send a raw tab to the webkit instance.
543 ** DONE remove the special-case for when the minibuffer is
544 active. I added some code to reduce the annoying problem display artefacts
545 when making the minibuffer the selected window. This made xwidgets in the
546 buffer go grey or black whenever one did m-x to activate the minibuffer. The
547 coded tried to handle the minibuffer as a special case. That simply wasnt a
548 good idea. Special-casing will never work properly. It is much better to spend
549 time finding solutions that work acceptably in the general case.
550
551 ** DONE disable emacs cursor drawing on top of an active xwidget.
552 This ought to be rather simple and should improve the visuals a lot.
553
554 ** TODO improve the xwidgets programming interface
555 so its less of hand-waving affair. This shouldnt be too hard, but I
556 have deliberatley not spent any time on it, since getting the
557 visuals right is much harder. Anyway, I sort of think the interface
558 should be somewhat like it is, except symbols is used instead of
559 integers.
560 *** DONE use symbols for xwidget types rather than ints
561 CLOSED: [2011-06-27 Mon 12:52]
562
563
564 *** TODO better lisp based structure for xwidgets
565 the lisp interface woud be like this:
566 - make-xwidget returns an xwidget object, similar to a process
567 object. this object is used when creating the display spec(instead of
568 the user defined id now used)
569
570 the data structure would be something like this:
571 - a "process" like aproach to create the xwidgets. xwidgets are
572 coupled to buffers, somewhat like processes, except a buffer can
573 hold several xwidgets
574 - an xwidget has a plist to hold the model, like a process
575 - an xwidget has an assoc list of xwidget views
576
577 there are some things that arent clear:
578 - an xwidget doesnt necessarily need to be coupled to a buffer but it
579 seems to be the clearest model. xwidgets would be buffer local
580 - xwidget-views are by necessity coupled to a emacs window so it might
581 be better to store them window locally rather than in an assoc
582 coupled to the xwidget model
583 - for some gtk widgets that resist an mvc approach, like the webkit
584 widgets, special operations are needed, similar to the old phantom
585 widgets aproach. so we need to differentiate live and phantom
586 instances for these troublesome widgets and let lisp manage all the trickery.
587
588 stuff that needs to work:
589 - do something for all views of a xwidget(resize, value change)
590 - do something for all xw-views in an emacs window(deletion etc)
591 - lookup xw-view for xwidget in emacs window(during redisplay)
592 (- do something for all siblings of a xw-view. not atm)
593
594 *** DONE xwidget creation interface
595 CLOSED: [2011-07-18 Mon 01:59]
596 xwidgets are a little bit like emacs processes but also a little bit
597 like emacs images. Therefore its not perfectly obvious how to handle
598 creation. Currently I just use hardcoded identifiers. the real scheme
599 needs to be something else.
600
601 Heres a tentative approach:
602 - xwidget-create returns a xwidget object, like process creation
603 functions. the xwidget will be largely uninitialized until
604 discovered by redisplay. an xw belongs to a buffer
605 - xwidget-insert inserts the xwidget in a buffer. when discovered by
606 redisplay it will be initialized and a xwidget-view allocated
607 - an event will be emitted when initialization is finished when
608 relevant like for sockets
609
610 the problem with this aproach is that its not really legal to reuse
611 xwidget objects by writing several display specs who reference the
612 same xwidget. It could presumably be done but it would just become
613 weird for no real benefit. the big preblem is that the display spec
614 decides the on-screen size, and its not sane to have xwidget views
615 with different sizes. therefore such display specs would need to be
616 catched and dissallowed. Except it is hard because AFAIK the specs
617 don't have an identity as such. A flag in the structure could be set
618 by lookup so the first display attempt would win. but then you can't
619 rewrite the spec to change the size. hmmm. A third approach would be
620 to just allow the 1st spec refering an xw during a redisplay to take
621 effect, the rest are signaled as errors. this wouldnt be too bad.
622
623 the other aproach would be to work more like images:
624
625 - write the display spec with all information needed to create the
626 xwidget.
627 - retrieve the xwidget objet from the spec with an xwidget-at-point function. It
628 can be uninitalized which client code must handle. Unlike
629 assynchronous process creation we dont get back a handle, because
630 there is none yet.
631 - emitted event on initialization, when needed. Many widgets don't
632 need this. for instance, a button sends an event when pressed. but
633 you can't press it unless its on screen, and then its initialized
634 properly.
635
636 This approach seemed good, but how do I know which instance
637 generates an event if I cant set the id beforehand?
638
639 so, therefore, the first two aproach is used.
640
641
642 *** DONE xwidget creation interface actually
643 CLOSED: [2011-07-18 Mon 01:59]
644 conclusion of above ramblings:
645 - should be similar to make-text-button
646 - don't init from display spec, instead during make-xwidget call
647 *** TODO callbacks would be nice
648 but they need to be handled initially with events for technical
649 reasons. C code can't call Lisp easily. The event handler can call the
650 callback though.
651
652 ** TODO more documentation
653 There should be user docs, and xwidget contributor docs. The current README
654 is all contributor docs there is now, apart from the code.
655
656
657
658 ** CANCELLED look into more ways of displaying xwidgets, like binding them to a
659 CLOSED: [2011-07-05 Tue 11:34]
660 window rather than a point in a buffer. This was suggested by Chidong.
661 This would be a useful addition to Emacs in itself, and would avoid nearly all
662 display issues. I still think the general case is more interesting, but this
663 special case should also be added. The xwidget would then be bound to
664 replace the view of a particular window, and it would only show in
665 that window.
666
667 I got the webkit xwidget to work well enough so I dont see the need
668 for this now, except for sockets and I think it can better be dealt
669 with at the lisp level.
670
671 ** DONE MVC mode for xwidgets
672 CLOSED: [2011-06-27 Mon 12:53]
673 It appears unfruitful to chase using the same display mode for all
674 types of xwidgets. Composition is fun but not robust the way I
675 tried to do it.
676
677 Instead there should be a set of MVC xwidgets. Each on-screen instance
678 of an MVC widget would be a real GTK widget. The instances would
679 communciate state using signals.
680
681 There are drawbacks. There is no inbuilt support for MVC in GTK, so we
682 have to roll our own, which is tedious if not much work for the few
683 cases.
684
685 MVC for xembedded application will need support from the applications
686 themselves. Inkscape supports multiple views to the same document,
687 other programs don't. In practice it might not be a big drawback.
688
689
690 *** DONE figure out what to do with the multiple frames case.
691 CLOSED: [2011-06-27 Mon 12:52]
692 This should be easier to solve with MVC.
693 Surprisingly, this just worked!
694 *** DONE how to propagate changes in views to other views?
695 CLOSED: [2011-06-27 Mon 12:53]
696 I used gtk signals, the implementation for sliders works well!
697
698 ** TODO canvas support
699 heres an interesting comparision of gtk canvases
700 http://live.gnome.org/ProjectRidley/CanvasOverview
701 *** goocanvas
702 goocanvas is a gtk canvas implemented using cairo. investigate.
703
704 pros:
705 - it has a MVC model aproach out of the box which is nice.
706
707 http://developer.gnome.org/goocanvas/unstable/goocanvas-model-view-canvas.html
708
709 export CFLAGS="`pkg-config --cflags goocanvas` -DHAVE_GOOCANVAS"
710 export LDFLAGS=`pkg-config --libs goocanvas`
711 ./configure
712 make
713
714 I made a hello goo world xwidget so seems doable.
715 I wanted to load a SVG which wasnt immediately straightforward, so I
716 tried clutter. but it turns out the exact same strategy could be used
717 with goocanvas.
718
719 *** clutter
720 maybe clutter can be used as a canvas?
721 pros:
722 - seems to have a lot of traction atm. many examples
723 - potentialy fast and cool vector graphics
724 cons:
725 - no out of the box MVC support, but seems doable. no worse than the
726 other home brew mvc support I have in xwidgets
727 (media-explorer in an application that employes the MVC pattern)
728
729 http://www.openismus.com/documents/clutter_tutorial/0.9/docs/tutorial/html/sec-stage-widget.html
730
731 there is also cool stuff like this:
732 http://gitorious.org/webkit-clutter/webkit-clutter which is an webkit actor for
733 clutter! hmmmmm.
734
735 I want to render svg. aparently:
736 librsvg rsvg_handle_render_cairo(h, cr);
737 ClutterCairoTexture
738 Clutter
739
740 export CFLAGS="`pkg-config --cflags clutter-gtk-1.0` -DHAVE_CLUTTER"
741 export LDFLAGS=`pkg-config --libs clutter-gtk-1.0`
742 ./configure
743 make
744
745 compiles but I get:
746 Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in
747 the same process is not supported
748
749 export CFLAGS="`pkg-config --cflags clutter-gtk-0.10` -DHAVE_CLUTTER"
750 export LDFLAGS=`pkg-config --libs clutter-gtk-0.10`
751 ./configure
752 make
753
754
755 *** webkit html 5
756 expose the DOM to lisp or something. The webkit xwidget works pretty
757 well now, so this might be the way ahead.
758 ** DONE mvc code crashes after a while
759 CLOSED: [2011-07-12 Tue 18:52]
760 seemingly only when compiling with optimizations.
761 I have no idea why.
762
763 Doesn't seem to happen after some code cleanups.
764 ** DONE xwidget-resize-at
765 CLOSED: [2011-07-19 Tue 14:28]
766 reimplement so display spec is not involved
767 ** DONE display spec validation
768 CLOSED: [2011-07-19 Tue 14:44]
769 it is an error to reuse xwidgets in several buffers or in the same
770 buffer. how do we catch these errors?
771 - showing the same xwidget twice in a buffer is no more wrong than
772 showing in several emacs windows, just conceptually wrong, so ignore
773 this case for now
774 - xwidgets now store a reference to the buffer they were created in,
775 so use that to invalidate xwidget references in oher buffers. but
776 thats not really an error either
777 - xwidgets should now be proper lisp objects so you dont delete them
778 you await their garbage collection. so therefore there can never be
779 invalid display specs
780
781 so turned out this got solved by using proper lisp objects for
782 xwidgets. yay!
783
784 ** DONE clipping of controllers
785 CLOSED: [2011-07-05 Tue 11:33]
786
787 Emacs uses a big GTK window and does its own clipping against Emacs
788 windows inside this area. So, in order to layout gtk widgets in emacs
789 windows we must clip thim ourselves.
790
791 The following method worked well for a long time:
792 - make a gtk widget, say a button, xw
793 - make a clipping area, of type gtkfixed(many types have been tested)
794 - put the clip area in the main emacs gtk window
795 - figure out clip area changes during emacs redisplay
796
797 the only weirdness was that one has to tell gtk the clip area has a
798 window in order to get clipping. This is weird because all gtkwidgets
799 are windows in a sense and a window is almost by definition also a
800 clipping area.
801
802 Anyway, in GTK3 the gtk_widget_set_has_window(GTK_WIDGET (
803 xv->widgetwindow), TRUE); call is ignored.
804
805 The gtkeventbox which is documented to have its own window doesnt work
806 either.
807
808 http://www.lanedo.com/~carlos/gtk3-doc/chap-drawing-model.html
809
810 anyway clipping is rather complicated but seems to finally work okay.
811
812 *** DONE subclass my own clipping widget
813 CLOSED: [2011-07-04 Mon 16:55]
814 http://www.lanedo.com/~carlos/gtk3-doc/GtkWidget.html#gtk-widget-set-has-window
815 mentions that it has_window can only be called inside a widget
816 impementation.
817
818 this wasnt really the issue. allocation was the problem
819 *** DONE try scrolled window
820 CLOSED: [2011-07-01 Fri 10:56]
821 clipping does in fact work with
822 gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget);
823 !!
824
825 I get unwanted scrollbars in the widget though.
826
827 gtk_scrolled_window_set_policy ( xv->widgetwindow,
828 GTK_POLICY_NEVER, GTK_POLICY_NEVER);
829
830 stops clipping from working!
831
832
833 *** DONE try viewport
834 CLOSED: [2011-07-01 Fri 10:56]
835 gtkviewport is used in scrolled window so in order to remove
836 scrollbars it should be possible to use viewport directly. however,
837 viewport ignores size requests. or rather the container does.
838
839
840 *** DONE debug allocation
841 CLOSED: [2011-07-04 Mon 16:56]
842 the container determines how much size to allocate to child widgets.
843
844 GtkAllocation galloc;
845 gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc);
846 printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height);
847
848 after my clipping attemp shows that my size request is ignored! this
849 might be logical, since the container provided by emacs is a
850 gtkfixed. gtkfixed might choose to heed the widgets size desires and
851 allocate the entire widget size. but we want clipping!
852
853 since i cant reasonably expect to change the emacs main container, i
854 can maybe overide the setallocation method in gwfixed, and adjust
855 allocation to clipping if its an xwidget asking for allocation.
856
857 **** DONE subclass gtkfixed
858 CLOSED: [2011-07-04 Mon 16:56]
859 possibly i need to subclass gtkfixed and override
860 #+begin_src C
861 void gtk_widget_size_allocate (GtkWidget *widget,
862 GtkAllocation *allocation);
863 #+end_src
864 http://developer.gnome.org/gobject/stable/howto-gobject.html
865
866 turns out emacs already does this for gtk3 according to jan D:
867 >>For GTK3, Emacs already subclasses GtkFixed, see emacsgtkfixed.[ch].
868
869 - widgets may not be underallocated, aparently
870 http://mail.gnome.org/archives/commits-list/2011-April/msg10950.html
871
872 - how to call base class method/chain up
873 http://developer.gnome.org/gobject/stable/howto-gobject-chainup.html
874
875 - the allocation modification could happen in the container or the
876 child. it feels more apropiate in the container
877
878 it is however unexpectedy inconvenient to modify allocation because
879 the needed data is private to the base class. to overcome this:
880
881 - run base class method 1st.
882 - then, iterate all children, and modify allocation for xwidget
883 children only. x y will then be set.
884
885 JanD pointed out the GTK3 port already has its own subclass, so I
886 modified that one.
887
888 *** DONE clip top
889 CLOSED: [2011-07-05 Tue 11:30]
890 there are four controller edges that potentialy need clipping. I begun
891 with right and bottom edges. clipping them is just a matter of setting
892 the right size of the widgetwindow and also ensure it gets the right
893 allocation from the container.
894
895 clipping top (and left) is not equally straightforward. I'm using a
896 viewport now and scroll it the amount that needs to be clipped.
897 however, the viewport is sensitive to changes in allocation, which
898 makes it harder to use the allocation workarounds.
899
900 see:
901 - gtk_widget_set_size_request
902 - gtkscrolledwindow
903
904 I returned to using a simple gtkfixed for the widgetwindow. with
905 allocation hack and set_has_window it works. Idea prefer not to have
906 the allocatien hack and it wasnt needed it gtk3 only gtk2. needs
907 furthi investigation,
908
909 ** various code cleanups
910 There are many cleanups necessary before any hope of inclusion in
911 Emacs trunk. To begin with, the part of the patch that touches other
912 parts of emacs must be very clean.
913 *** DONE use FRAME_GTK_WIDGET (f)
914 CLOSED: [2011-07-20 Wed 20:02]
915 rather than gwfixed.
916
917 *** DONE support configure
918 CLOSED: [2011-07-12 Tue 18:48]
919 *** DONE ifdef all xwidget code
920 CLOSED: [2011-08-13 Sat 16:19]
921 so you can reliably disable the code at compiletime
922 ** DONE translate clicks
923 CLOSED: [2011-07-03 Sun 22:12]
924 on onscreen webkit peer to offscreen
925
926 maybe
927 http://developer.gnome.org/gdk/stable/gdk-Windows.html#GdkWindow-from-embedder
928
929 turned out to be not so hard, captured events, copied them and
930 forwarded them offscreen!
931
932 ** TODO investigate gdk_window_redirect_to_drawable
933 http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-offscreen-window-set-embedder
934 maybe could be used in place of my own copy hacks? to work it must
935 support a chain of redirects, which seems unlikely. the benefit would
936 be that I dont have to spend time optimizing redrawing.
937
938
939 ** DONE remove xwidget_views when emacs window is deleted
940 CLOSED: [2011-07-05 Tue 11:29]
941 removing xwidget views when an Emacs window closes is not reliable.
942
943 - switching buffers in a window seems to hide the corresponding
944 xwidget-views properly, but they might as well be deleted.
945
946 - patching delete-window-internal could be used to delete the xwidget-views
947 this seems to work
948
949
950 ** browser xwidget
951 although embedding a browser is not my primary concern many are
952 interested in this. some suitable browser component needs to be found
953 supporting gtk.
954
955 *** DONE webkit
956 CLOSED: [2011-07-03 Sun 22:13]
957 there is a webkit gtk port. there is no obvious mvc support.
958 http://live.gnome.org/WebKitGtk
959 http://webkitgtk.org/
960
961 it might be possible to keep a set of webxits in artificial
962 synchronisation by recursive deep copy of the DOM from one webkit to
963 another. This will be error prone at best though. Another way might be
964 to just use bitmap copy of the "live"instance to the "phantom"
965 instances. the problem of transfering the live view remains though.
966
967 export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT -g"
968 export LDFLAGS=`pkg-config --libs webkit-1.0`
969 ./configure
970 make
971
972 **** off screen rendering
973 export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT_OSR -g"
974 export LDFLAGS=`pkg-config --libs webkit-1.0`
975 ./configure
976 make
977
978 works a little bit but i get errors like:
979
980 (emacs:8362): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11'
981
982 set a breakpoint in g_log, backtrace seems to indicate
983 webkitViewportAttributesRecompute is the offender.
984
985 maybe try gtk3 variants?
986 #+begin_src sh
987 export CFLAGS="`pkg-config --cflags webkitgtk-3.0 ` -DHAVE_WEBKIT_OSR "
988 export LDFLAGS=`pkg-config --libs webkitgtk-3.0 `
989 ./configure --with-x-toolkit=gtk3
990 make
991 #+end_src
992 crash in gtk_window_get_size instead. great.
993
994 http://gtkplus-p3.0.sourcearchive.com/documentation/2.91.5-0ubuntu1/testoffscreenwindow_8c-source.html
995
996 after many atempts, the basic issue remains. for some reason the
997 offscreen widget isnt ok when I want to snapshot it, so i simply get
998 emptiness. the surface is only ok someimes.
999
1000 here is a useful debugging snippets:
1001 #+begin_src C
1002 // debugging redraw:
1003 // - the bg colors always change, so theres no error in signal handling
1004 // - i get this error now and then:
1005 //(emacs:7109): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11'
1006 // seems to happen in webkit actually. see README
1007
1008 if(0){ //redraw debug hack. helped a lot in fact. use the with alpha painter below also
1009 cairo_set_source_rgb(cr, osr_dbg_color, 1.0, 0.2);
1010 cairo_rectangle(cr, 0,0, xw->width, xw->height);
1011 cairo_fill(cr);
1012 osr_dbg_color+=0.1;
1013 if(osr_dbg_color>1.0)
1014 osr_dbg_color=0.0;
1015
1016 }
1017 #+end_src
1018 you need to terminate drawing like this:
1019 #+begin_src C
1020 //cairo_set_source_surface (cr, src_pixmap, 0,0);
1021 //cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1022
1023 //cairo_paint_with_alpha (cr, 1.0);
1024 //cairo_paint(cr);
1025 #+end_src
1026
1027 the snippets change background color on oach redraw.
1028
1029 **** on-screen rendering to separate window
1030 an alternative might be to open a separate window and snapshot it. the
1031 idea is that whatever oddness webkit does so that offscreen rendering
1032 doesnt work, doesnt happen on-screen. the window could be opened
1033 somewhere not in the way.
1034
1035 *** CANCELLED firefox
1036 CLOSED: [2011-07-03 Sun 22:13]
1037 http://www-archive.mozilla.org/unix/gtk-embedding.html
1038 seems to be severly bitrotted
1039
1040 heres a newer aproach
1041 http://hg.mozilla.org/incubator/embedding/file/29ac0fe51754/gtk/tests/test.cpp
1042
1043 while webkit clearly has the best traction as an embeddee, the
1044 offscreen rendering issues makes it interesting to see what ff brings
1045 to the table.
1046
1047 turned out webkit has as good offscreen support as anyone, see I went
1048 with that in the end.
1049
1050
1051 *** DONE text field support
1052 CLOSED: [2011-07-20 Wed 20:05]
1053 Emacs captures all keyboard events so text field support isn't super
1054 straightforward.
1055
1056 **** propagate keyboard events
1057 I have some old hacks for this and they are not good.
1058 **** use the DOM model
1059 expose document.activeElement to lisp. This is potentially more
1060 interesting than just forwarding keyboard events.
1061
1062 webkit_web_view_get_dom_document ()
1063
1064 this is hard it seems. an idea might be to hack elisp support for swig
1065 to machine generate the bindings.
1066 **** DONE inject javascript
1067 CLOSED: [2011-07-03 Sun 22:50]
1068 webkit_web_view_execute_script ()
1069
1070 this works now:
1071 (xwidget-webkit-execute-script 5 "document.activeElement.value='test'")
1072
1073 so it should be possible to do some interesting stuff.
1074 execute-script does however not return anything at the interface level
1075 so satisfaction is not total:
1076
1077 http://markmail.org/message/4yowmdgras73z3x5
1078
1079 maybe
1080 https://launchpad.net/gnome-seed
1081
1082 or this funny hack:
1083 <jave> im trying to understanh how to interact via javascript to an embedded
1084 webkit gtk instance [23:38]
1085 <jave> i use webkit_web_view_execute_script() which is nice but doesnt return
1086 a value, by design aparently [23:39]
1087 <jave> any hints?
1088 <lucian> jave: afaik, webkit still doesn't have full gobject bindings [23:48]
1089 <lucian> jave: you can hack it up by making the JS modify the title, and read
1090 the title from gtk-side
1091 <jave> lucian: that was a pretty cool idea!
1092
1093
1094 *** webkit_web_view_load_string ()
1095 I would like preview of html in a buffer rather than from uri.
1096
1097
1098
1099 *** DONE simple xwidget-webkit wrapper
1100 CLOSED: [2011-07-22 Fri 11:01]
1101 so that it could be used for actual browsing :)
1102 I dont want to reinvent too many wheels so i'd like to use existing
1103 emacs facilities here possible. use bindings similar to w3m(or info)
1104
1105 - m-x xwidget-webkit starts a session
1106 - 'g' goes to a url
1107 - use bookmark-jump i suppose. I mostly use org for bookmarks myself
1108 - browse-url support so webkit can be the default browser
1109 - some way of getting around the quirky keyboard interaction since
1110 xwidgets dont receive keyboard events because I hawe no idea how to
1111 do that in a sane way
1112
1113 ... and one can of course go on bikeshedding forever. lets keep it
1114 simple and extensible, and compatible with other Emacs packages.
1115
1116 the really cool ideas would need Emacs DOM integration, which is not
1117 easy.
1118
1119 ** webkit related
1120 *** TODO webkit support webkit signals
1121
1122 **** DONE particularily document-load-finished
1123 CLOSED: [2011-08-01 Mon 22:34]
1124 http://webkitgtk.org/reference/webkitgtk-webkitwebview.html#WebKitWebView-document-load-finished
1125 because one might need tell set a title and sizes and things when it loads.
1126 **** TODO event bug
1127 Debugger entered--Lisp error: (error "Two bases given in one event")
1128
1129 hapens sometimes with xwidget events. appears to be when the
1130 originating xwidget is offscreen so that the event doesn't get caught
1131 by the correct emacs event map.
1132
1133 maybe I need to set the originating window in the event structure.
1134 event.frame_or_window = Qnil; //frame; //how to get the frame here? //TODO i store it in the xwidget now
1135
1136 since its an offscreen xwidget the buffer local keymap isnt the right
1137 place for the handler. some global map should be used.
1138
1139 onscreen widgets don't have the same issue.
1140
1141 anyway, seems it'll turn out like this:
1142 - xwidget-osr stores a callback and user data
1143 - the event is an implementation detail only and get caught in the
1144 topmost event map
1145 - the event map calls the callback in the xw with the right args.
1146
1147 we need the event handler at some level because we can't call lisp
1148 asynchronously.
1149
1150 **** TODO navigation signal
1151 **** TODO new window signal
1152 *** TODO console messages
1153 http://webkitgtk.org/reference/webkitgtk-webkitwebview.html#WebKitWebView-console-message
1154 http://getfirebug.com/wiki/index.php/Console_API#console.count.28.5Btitle.5D.29
1155 because maybe we can make a simple JS REPL that way.
1156 (xwidget-webkit-execute-script ( xwidget-webkit-last-session)
1157 "console.log('hello')")
1158 prints hello to stdout but theres no way to catch stdout from webkit I
1159 think other than receiving the signal.
1160
1161 *** TODO webkit flashkiller by default
1162 while its possible to support plugins in the webkit xwidget, flash has
1163 issues on 64 bit, and slows down emacs to a halt with off screen
1164 rendering, and of course is not free software. its in the way for real
1165 world usage even if its interesting to watch flash animations inside
1166 emacs. which should be achieved with Gnash or other free software
1167 instead.
1168
1169 http://stackoverflow.com/questions/4885513/prevent-flash-in-cocoa-webview
1170
1171 simply use this api:
1172 http://webkitgtk.org/reference/WebKitWebPluginDatabase.html
1173
1174 theres an implementation now but it's not robust enough webkit often
1175 crashes taking emacs with it.
1176
1177 *** TODO webkit downloads
1178 when clicking a download link in Webkit Emacs should take over and handle it
1179 from there. Probably need signals. There are Emacs libraries to
1180 download things, with wget etc. an url.el facility should be made.
1181 "download-requested"
1182 *** TODO webkit alt-text not handled
1183 XKCD use image-title to display a cartoon comment. These mysteriously
1184 don't work ATM. Other mouseovers work though. Maybe webkit tries to
1185 open a new window or something, which wont work.
1186
1187 *** TODO webkit isearch in webkit buffers
1188 have a look at how docview solves it
1189 webkit_web_view_search_text ()
1190 *** TODO webkit relative references doesn't work
1191 because we handle scrolling in a non-standard way. It does
1192 work sort of when theres a html frameset and webkit scrolls by itself.
1193
1194 internal links (page.html#section) do not work
1195 see xwidget-webkit-show-named-element
1196
1197 also did some webkit signal work for this.
1198
1199 now it actually works! except for I need to know the Y coordinate of
1200 the element to navigate to, and that can either be by "name" or "id"
1201 attribute, currently "id" works.
1202
1203
1204
1205 *** TODO webkit width adjustment handling issue
1206 since there are so many levels of clipping and whatnot in xwidgets
1207 sizing issues are difficult.
1208
1209 - an xwidget is told how large it can be by emacs. thats the end of
1210 it. if the xwidget thinks otherwise it will be clipped.
1211 - but emacs can ask the xwidget how large it wants to be. it can then
1212 resize the reserved area and inform the xwidget thusly.
1213
1214 That should have been enough. but webkit never reports less than what
1215 it already has. So currently a webkit view will only growth and not
1216 adjust to smaller sizes.
1217
1218 This is not a big problem in practice but is still annoying.
1219
1220 to see the problem surface to http://www.slashdot.org
1221 - xwidget-webkit-adjust-size
1222 - xwidget-webkit-adjust-size-to-content
1223
1224 and then compare by resizing in Epiphany, which is also webkit based.
1225
1226 **** TODO try putting webkit osr inside a scrolling window
1227 it seems webkit is supposed to behave differently while embedded in a
1228 scrolling window. This is a bit cumbersome because the container stack
1229 is already deep.
1230 *** TODO xwidget webkit allow loading from string from emacs
1231 *** DONE xwidget-webkit-last-session
1232 CLOSED: [2011-08-01 Mon 22:38]
1233 was rather hurried. end result is that the lisp layer only really
1234 allows for one webkit session.
1235 *** TODO extract DOM to lisp
1236 then the SHR html renderer from Gnus could render the DOM as created
1237 by Webkit.
1238
1239 made a simple oxperimental DOM tree traverser. It can be expanded to
1240 return a lisp representation, LDOM.
1241
1242 in order to bring lisp and DOM closer together the LDOM can include a
1243 mapping to the originating DOM node. so, find a node in LDOM, and the
1244 cell maps to the original DOM. but since the LDOM is a copy it can get
1245 out of sync. DOM events might help.
1246 *** DONE C-X b in other buffer from webkit
1247 CLOSED: [2011-08-12 Fri 22:20]
1248 bafflingly resets the webkit view to the top. Maybe the window
1249 reconfiguration hook code? further mystification is added because it
1250 only seems to happen with ido mode enabled.
1251
1252 in comparison with image-mode which does the right thing, I discovered
1253 that image-mode has special code to handle scrolling. the browser mode
1254 and image mode has some similarities.
1255
1256 I made some delegation code frrom webkit mode to image mode.
1257 *** TODO url-browse improvement
1258 sindikat: site.com and http://site.com should be equivalent (simple site.com
1259 throws error)
1260
1261 Yes, but its unclear at what level in Emacs to do this
1262 properly. I added a url-tidy function as a start.
1263
1264 this should be further improved:
1265 - change the call to url-tidy so its a hook
1266 - provide a couple of demonstration hooks:
1267 - url-tidy, which just prepends http://
1268 - youtube which appends &html5=1 to urls looking like http://www.youtube.com/watch?v=DZdUgjEx_dQ
1269 - history which logs all visited urls like a traditional browser
1270
1271 *** TODO sindicat notes
1272 Here are some comments from user "sindikat" and my replies
1273
1274 - http://ya.ru renders inadequatly (compare with any other browser) -
1275 the search text-input is way below
1276
1277 The problem is the size communication between Emacs and Webkit.
1278
1279 - doing PageDown is endless; so if you do 100 PageDowns, you have to
1280 do 100 PageUps to retun to the header of the page
1281
1282 True, I hadn't noticed. Thanks.
1283
1284 - http://linux.org.ru (just an example) renders incorrectly too - it
1285 should stretch horizontally
1286
1287 Size communication.
1288
1289 - obviously, pointing of mouse over some link should change it to
1290 pointing hand cursor
1291
1292 Need to verify with some other webkit browser.
1293
1294 - when you are somewhere on the middle of a long page, than go to some
1295 other page, you are still in the middle, instead of being again on
1296 the top
1297
1298 This is because I inherit from Image view mode. I kind of like it so
1299 we can add an option for it.
1300
1301
1302 - changing dropdown menus cause flickering
1303
1304
1305 - string entering is incorrect - by default it enters the title of the
1306 page, while it should be empty
1307
1308 The cause is the lack of return value in the webkit evaluation
1309 API. Ive made some fixes.
1310
1311 - internal links (page.html#section) do not work
1312
1313 ive added a rudimentary function "xwidget-webkit-show-named-element" for this
1314
1315 - maybe it's a good idea to implement Conkeror or some other
1316 keybindings, where you press 'f' then select the exact <input
1317 type="text"> where you want to enter text, without using mouse,
1318 etc.;
1319
1320 Indeed, this would require better DOM integration.
1321
1322 - pressing 'home' and 'end' puts nonsense into minibuffer
1323
1324 Probably because the Image mode derivative is mostly a hack.
1325 fixed now I think.
1326
1327
1328
1329
1330
1331
1332 - implement search (emacs internal isearch obviously doesn't work)
1333
1334 Either use the webkit search but that doesn't feel right. It would be
1335 better to expose the DOM and search that.
1336
1337 - some sites intercept with keyboard; example -
1338 http://www.artlebedev.ru/kovodstvo/business-lynch/2011/10/03/ uses
1339 Ctrl+left/right/up/down to navigate between pages - this should be
1340 implemented too
1341
1342 Keyboard integration is the unloved step-child of xwidgets, unfortunately.
1343
1344
1345
1346 ** TODO xwidget image display spec compatibility
1347 some history: the first version of the xwidget display spec was
1348 the same as an image spec. This turned out not to be fantastic because
1349 an xwidget is both like a process and like an image. it has a separate
1350 existence from display. So now the xwidget display spec is just a
1351 pointer to a xwidget. But then some useful functionality in Emacs
1352 can't be reused for xwidget, in particular image-mode.
1353
1354 Maybe a new image type could be added that was a wraper on an
1355 xwidget. Then image mode could be reused for webkit mode.
1356
1357 I tried some adaptor code in xwidget.el so webkit mode now delegates
1358 to image mode buh its a kludge.
1359
1360 ** socket related
1361 *** TODO some flickering during redisplay of sockets
1362 with gtk3 an size allocation workaround is used.
1363 this seems maybe to result in flickering sizewize y-axis with the
1364 xwidget socket type. The webkit xwidget doesn't seem similarily
1365 afflicted.
1366
1367 the size allocation workaround works by 1st running the ordinary
1368 allocation then modifying the results. its done this way to minimise
1369 the copy paste index from the base class. it might be that the
1370 original allocation has a brief time window to show itself.
1371
1372 tried to modify the allocation hack so it doesn't call allocate
1373 twice. this doesn't seem to help flicker at all aparently so the
1374 hypothesis falls. Maybe then a socket simply doesn't lke being clipped
1375 by gtkfixed.
1376
1377 *** TODO xwidget view reaping too agressive
1378 hide an emacs window for a while and return to it. the xwidget might
1379 get reaped and a new socket thus created.
1380 *** DONE try out OSR for sockets
1381 CLOSED: [2011-07-25 Mon 21:30]
1382
1383 didn't work too well in the inkscape case. it might be that some other
1384 bitmap copy method works better though.
1385
1386 basically sockets doesn't like to be offscreen because they want their
1387 own gdk window.
1388
1389 ** DONE synchronise emacs background with xwidget color
1390 CLOSED: [2011-08-11 Thu 11:04]
1391 fine-tuning to reduce flicker.
1392
1393 isn't needed if emacs bg erase disabled
1394
1395 ** DONE xwidgets doesn't work during bootstrap all of a sudden
1396 CLOSED: [2011-08-01 Mon 22:33]
1397 might be some annoying local issues with my install because it is not
1398 reliably reproducible. (went away during merges)
1399
1400 ** TODO low impact xwidget based image viewer
1401 for instance to render SVG using webkit, or some other canvas.
1402 that way it would be possible to merge to trunk in stages.
1403
1404 so, webkit could be used to display the SVG. the display spec for
1405 images would be used. multiple webkits would be used rather than
1406 offscreen rendering, so it would be GTK2 compatible.
1407 ** DONE xwidget movement doesn't work all of a sudden
1408 CLOSED: [2011-08-11 Thu 11:03]
1409 this used to work great. now it doesn't.
1410
1411 suspects:
1412 - XCopyArea
1413 - x_shift_glyphs_for_insert
1414 - x_scroll_run. this is run by the try_window* functions, and
1415 inhibiting them dösnt help. but also callid in scrolling_window.
1416
1417
1418 - try_window_reusing_current_matrix
1419 - I used to enable GLYPH_DEBUG which I currently don't. it disables
1420 many optimisations. this was fixed.
1421 - lookup_xwidget then produce_xwidget_glyph gets called always but not
1422 x_draw_xwidget_glyph_string probably because of scroll optimization.
1423 movement detection could possibly be moved to produce_xwidget_glyph(not)
1424
1425 no longer helps:
1426 (setq inhibit-try-window-id t)
1427 (setq inhibit-try-window-reusing t)
1428
1429 workaround:
1430 (run-with-timer 1 1 'redraw-display)
1431
1432 seems to work:
1433 inhibiting scrolling_window(). and this seem to be enaugh to restore
1434 old behaviour, GLYPH_DEBUG doesn't seem needed.
1435
1436
1437 ** DONE GLYPH_DEBUG doesn't work
1438 CLOSED: [2011-08-08 Mon 17:30]
1439 was stupid accidental line removal that was hard to spot
1440 ** TODO osc xwidget example
1441 a couple of xwidget sliders that control a csound/supercollider song with osc.
1442 so, for that to work we need slider callbacks to work. when a slider
1443 changes send an osc message. use ocssend:
1444
1445 oscsend localhost 7777 /sample/address iTfs 1 3.14 hello
1446
1447 or better:
1448 http://delysid.org/emacs/osc.el
1449
1450 sliders could be defined in csound comments or something to illustrate
1451 the point. or if real fanciness is desired parse the csound source
1452 with Semantic and provide a control buffer corresponding to the
1453 defined controls.
1454
1455
1456
1457 Added: [2011-08-11 Thu 10:53]
1458
1459
1460 ** DONE SEB
1461 CLOSED: [2011-10-26 Wed 15:36]
1462 the SEB site does something funny so I can't insert text in
1463 fields. aparently document.activeElement.value doesn't work with framesets.
1464
1465 seems to work using the ugly javascript in
1466 xwidget-webkit-activeelement-js
1467
1468 ** support downstreams
1469 http://aur.archlinux.org/packages.php?ID=53902
1470 http://gpo.zugaina.org/app-editors/emacs-xwidget/ChangeLog
1471 ** DONE the proof of concept canvas code should be disabled by default.
1472 CLOSED: [2011-10-12 Wed 23:03]
1473 ** TODO advi
1474 active dvi viewer. investigate if it could be xwidgetified.
1475 advi supports embedding inside presentations.
1476 ** cairo configuration support
1477 gtk3 brings in cairo on Fedora, but apparently not on all plattforms.
1478 pkg-config --cflags cairo
1479 ** TODO splint
1480 splint -Demacs -DHAVE_CONFIG_H -I. -I/home/joakim/build_myprojs/emacsnew/emacs.bzr/xwidget.mint/src -I../lib -I/home/joakim/build_myprojs/emacsnew/emacs.bzr/xwidget.mint/src/../lib -DGSEAL_ENABLE -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/freetype2 -I/usr/include/alsa -I/usr/include/librsvg-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/cairo -I/usr/include/libpng12 -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/ImageMagick -I/usr/include/libxml2 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -DGSEAL_ENABLE -I/usr/include/webkit-3.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/libsoup-2.4 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -DORBIT2=1 -I/usr/include/gconf/2 -I/usr/include/orbit-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/freetype2 xwidget.c
1481
1482 ** TODO 32 bit bug
1483 user reports that xwidgets segfaults on the 32 bit Mint distribution
1484 but not the 64 bit. Mint is an Ubuntu derivative. I got some
1485 VirtualBox images to test with.
1486 ** DONE youtube
1487 CLOSED: [2011-11-01 Tue 11:19]
1488 http://www.youtube.com/watch?v=DZdUgjEx_dQ&html5=1
1489 html5 makes it work without stupid flash plugins!
1490 ** TODO clicking on an webkit xwidgets
1491 doesn't make the window active. this leads to problems.
1492 ** DONE "g" should default to current url
1493 CLOSED: [2011-11-03 Thu 22:25]
1494 "g" runs xwidget-webkit-browse-url which gets its interactive argument
1495 from browse-url-interactive-arg. this might need a new optional argument.
1496
1497 http://test
1498 ** TODO anything/helm support
1499 hook so anything/helm can filter browser history.
1500 ** TODO new relative url code sometimes fail
1501 http://www.dilbert.com
1502 ** TODO input field enhancements
1503 *** password field.
1504 was straightforward
1505
1506 *** textarea
1507 less straightforward. I would like it to work like emacs-w3m, where a
1508 new editing buffer is opened. on c-c, the buffer is closed and the
1509 browser field updated. however, it's not immediately obvious how to
1510 store the reference to the field reliably.
1511
1512 furthermore the current code doesn't seem to propagate linefeed
1513 properly to text areas.
1514
1515 ** DONE bug in current navigation handler
1516 CLOSED: [2011-11-09 Wed 10:04]
1517 on www.dn.se
1518 Debugger entered--Lisp error: (args-out-of-range "http://platform.twitter.com/widgets/hub.html" 54 357)
1519 match-string(1 "http://platform.twitter.com/widgets/hub.html")
1520 xwidget-webkit-callback(48890368 navigation-policy-decision-requested)
1521 xwidget-event-handler()
1522 call-interactively(xwidget-event-handler nil nil)
1523 ** TODO how to set the name of a webkit buffer?
1524 not obvious because, the buffer isn't created immediately and there is
1525 a callback that sets the buffer name automatically
1526 ** TODO how to find next field in tab order?
1527 ** TODO unique buffer names
1528 the webkit xwidgets renames the buffer after load but not uniquely so
1529 it sometimes fails.
1530 ** TODO kill the offscreen webkit xwidgets when last view killed
1531 The offscreen xwidgets is currently kept around even if the xwidgets
1532 views are all gone. this is a general problem and it requires actions
1533 on the behalf of the application to resolve.
1534
1535 In the case of webkit it is currently possible to get errors like these:
1536
1537 Debugger entered--Lisp error: (error "Selecting deleted buffer")
1538 xwidget-webkit-callback(60925380 navigation-policy-decision-requested)
1539 xwidget-event-handler()
1540 call-interactively(xwidget-event-handler nil nil)
1541
1542
1543 because the last view is gone and the offscreen widgets is still
1544 generating events.
1545
1546 In the case of webkit it is okay to kill the offscreen widgets
1547 completely when the user kills the last view window because it would
1548 be unexpected by the user to see it pop up again. This is not true in
1549 the general case.
1550
1551 ** DONE xwidgets debugging log
1552 CLOSED: [2012-01-23 Mon 14:32]
1553 currently theres a lot of debugging traces using "message" which is
1554 annoying. Instead put them in a separate trace buffer.
1555 (see xwidgetbuffer)
1556 ** TODO make garbage collect work for xwidgets
1557 when an xwidget is removed from xwidget-alist, and there are no other
1558 references(mostly views) the xwidget should be garbage collected.
1559
1560 special finalization would go into gc_sweep()
1561 <<<<<<< TREE
1562 ** TODO embedding evince
1563 http://developer.gnome.org/libevview/3.2/libevview-ev-view.html
1564 would be useful for reading PDF:s and other document types.
1565 it would work the same way webkit embedding works.
1566
1567 ** TODO support gobject introspection
1568 https://live.gnome.org/GObjectIntrospection/
1569 supporting gobject introspection would mean that more gtk widgets
1570 could be tried out with less effort, and also that the build process
1571 and runtime support would be easier. The drawbacks are small: somewhat
1572 slower execution, and difficulty in providing elisp bindings for
1573 introspection.
1574
1575 https://live.gnome.org/GObjectIntrospection/HowToWriteALanguageBinding
1576
1577 http://developer.gnome.org/gi/unstable/gi-girepository.html
1578 http://developer.gnome.org/gi/unstable/gi-overview.html
1579
1580
1581 In order for GIR to work, it needs the namespace and class of a
1582 widget. This is used to access the typelib file, which contains the
1583 introspection data. The namespace and class is stored as a property
1584 on the lisp symbol handle used by xwidgets to identify the widget
1585 class.
1586
1587 This snippet sets the needed :xwgir-class property, and calls the
1588 set_zoom_level method:
1589
1590 M-x xwidget-webkit-browse-url RET www.emacswiki.org RET
1591
1592 Then eval the following:
1593
1594 ;;load the webkit typelib
1595 (xwgir-require-namespace "WebKit" "2.0")
1596
1597 ;;provide the metadata needed so xwgir can work with the webkit-osr xwidget
1598 (put 'webkit-osr :xwgir-class '("WebKit" "WebView"))
1599 ;;call the method
1600 (xwgir-call-method (xwidget-at 1) "set_zoom_level" '(3.0))
1601
1602 It's also possible to create widgets dynamically, by using
1603 introspection to call a widget constructor(from xwidget-test.el):
1604
1605
1606 (defun xwgir-test ()
1607 (interactive)
1608 (xwgir-require-namespace "Gtk" "3.0")
1609 (put 'color-selection :xwgir-class '("Gtk" "ColorSelection"))
1610
1611 (xwgir-demo-a-xwgir-button)
1612 (xwgir-call-method (xwidget-at 1) "set_label" '( "xwgir set label!"))
1613 )
1614
1615 Current limitation:
1616 - Only 0 arg constructors are supported at the moment. Since xwidgets
1617 defer construction, the args needs to be stored with the xwidget.
1618
1619 - xwgir-call-method does indeed lisp to gobject conversion for the
1620 arguments, but only some primitive types are supported atm.
1621
1622 - next to no argument checking. If wrong type args are used with the
1623 xwgir methods, emacs crashes.
1624
1625