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