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