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