aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Verona2011-06-27 14:22:45 +0200
committerJoakim Verona2011-06-27 14:22:45 +0200
commit78309a2cbf04a9fb4b82a35d3c912dc8baedd1e6 (patch)
tree16b1312bb80ec983d35e5b23aa1973288c341b90
parent2f69e75a614ffbe94da2c81022d8313ab5c43a72 (diff)
downloademacs-78309a2cbf04a9fb4b82a35d3c912dc8baedd1e6.tar.gz
emacs-78309a2cbf04a9fb4b82a35d3c912dc8baedd1e6.zip
doc update for mvc. resize support for mvc
-rw-r--r--README.xwidget130
-rw-r--r--src/xwidget.c14
2 files changed, 87 insertions, 57 deletions
diff --git a/README.xwidget b/README.xwidget
index 35b8d1c5232..77b98d5fd83 100644
--- a/README.xwidget
+++ b/README.xwidget
@@ -14,18 +14,42 @@ will require adapter code for each type.
14 14
15A difference from images is that xwidgets live their own life. You 15A difference from images is that xwidgets live their own life. You
16create them with an api, get a reference, and tie them to a particular 16create them with an api, get a reference, and tie them to a particular
17buffer with a display spec. Also, xwidgets exists in only one copy, 17buffer with a display spec.
18where a plain image can be shown in several windows. The xwidget code 18
19tries to handle this by essentialy making a screen capture of the 19Each xwidget can have several views. In MVC terms, an xwidget is the
20widget and displaying those in the non-active windows, and the live 20model, and an xwidget-view is a view of the xwidget in a particular
21widget in the active window. The current snapshot code doesnt work if 21Emacs window.
22the live xwidget is off-screen. This seems to be solveable by using 22
23the XComposite interface, but that doesnt currently work. 23The xwidget code attempts to keep the visual appearance of the views
24 24in sync with through an Observer pattern implementation.
25The current state is that one window, one frame, showing many xwidgets 25
26is a nice demo. One frame, many windows, will have lots of display 26** MVC and Xembedd
27glitches. Many frames, many windows, will work even worse. 27The MVC approach appears to be at least in principle robust for plain gtk
28 28widgets. For the interesting case of gtk sockets which implements an
29xembed host widget that allows for embedding other applications inside
30an Emacs window, the story gets more complex.
31
32The problem is that xembed is designed to plug an application window
33inside a a secket and thats it. You can't move a plug between
34sockets. I tried numerous hacks to get around this but there is
35nothing that works realy well.
36
37Therefore the Emacs part of the code will only expose well-defined
38interfaces. cooperating applications will be able to use the interface
39in a well defined manner. The problem is that there is no known xembeddable
40application that implement the needed type of functionality, which is
41allowing for creating new windows on the fly that plug into new
42sockets.
43
44Therefore I will attempt to provide an external application that wraps
45another application and through hacks attempts to provide the needed
46multi view xembed function. That way Emacs is sane and the insanity
47contained.
48
49This app will work by providing a socket that an app plugs into. The
50socket window is copied efficientlp by means of composition to a
51number of other windows, that then are plugged into the different
52Emacs sockets.
29 53
30* Brief overview of how xwidgets work 54* Brief overview of how xwidgets work
31Xwidgets work in one way like images in Emacs. You bind a display spec very 55Xwidgets work in one way like images in Emacs. You bind a display spec very
@@ -45,28 +69,10 @@ synchonous with Emacs display changes. Ok, so why is that difficult then?
45 xwidget is encountered during display, the flag is set. After redisplay, 69 xwidget is encountered during display, the flag is set. After redisplay,
46 iterate all xwidgets and hide those which hasnt been displayed. 70 iterate all xwidgets and hide those which hasnt been displayed.
47 71
48- In the general case, there can only be one xwidget, and several views of
49 it. There is one live view, and several phantom views. The live view is defined
50 to be in the currently selected window. All other views are phantom views.
51
52 Even this simple rule is difficult to implement in practice because Emacs
53 display is clever and optimized. It is often difficult to know that a xwdiget
54 hasnt actually been displayed after a redisplay.
55
56- phantom views of xwidgets are thankfully not so hard because gtk
57 supports snapshoting of many widget types. Snapshoting doesnt seem
58 to work if the live widget is offscreen. This might be solvable with
59 xcomposite, but attempts have so far failed.
60
61- The gtk socket type for embedding external applications is desirable 72- The gtk socket type for embedding external applications is desirable
62 but presents a lot of difficulties of its own. One difficulty is 73 but presents a lot of difficulties of its own. One difficulty is
63 deciding which input events to forward, and when and how to do it. 74 deciding which input events to forward, and when and how to do it.
64 75
65- The case of showing an xwidget in several frames is not solved at all
66 currently. This would mean moving the live xwidget between frames when the
67 selected window moves. The gtk widget will need to be reparented between
68 windows, which seems fragile.
69
70** placement and clipping 76** placement and clipping
71the entire emacs frame is a gtk window. we use the fixed layout 77the entire emacs frame is a gtk window. we use the fixed layout
72manager to place xwidgets on the frame. coordinates are supplied by 78manager to place xwidgets on the frame. coordinates are supplied by
@@ -77,32 +83,14 @@ emacs frame.
77this way was chosen to simplify clipping of the widgets against emacs 83this way was chosen to simplify clipping of the widgets against emacs
78window borders. 84window borders.
79 85
80** xwidget phantom views in particular
81The general aproach so far has been to have a "live" xwidget moved
82around in the emacs window. when the selected window changes, the live
83xwidget is moved there. the possibly other views of the xwidget are
84called "phantoms" and are snapshoted from the live xwidget.
85
86This turned out to be difficult and a lot of different aproaches has
87been tried. The current, somewhat promising, aproach is to enable
88composition for the xwidgets gtk widget peer. This enables renedering
89of the widget to offscreen backing store. snapshoting then becomes
90more robus, because otherwise snapshoting is dependent on the live
91xwidget being on-screen, which isnt necesarily the case.
92
93on the other hand, compositing introduces other issues. the live
94xwidget isnt drawn automatically at all any more, so we need our own
95expose handler to deal with drawing. this in turn enables us to toy
96with transparency and such.
97 86
98** different strategies 87** different strategies
99Integrating toolkit widgets(gtk in this case) and the emacs display 88Integrating toolkit widgets(gtk in this case) and the emacs display
100engine is more difficult than your plain average gui application, and 89engine is more difficult than your plain average gui application, and
101different strategies has been tested and will continue to be tested. 90different strategies has been tested and will continue to be tested.
102 91
103There will probably always be a distinction between live xwidgets and 92There was a distinction between live xwidgets and
104phantom xwidgets. how this distinction is realized has and will 93phantom xwidgets, previous to the change to MVC.
105change.
106 94
107- the first aproach was to have the live xwidget on-screen, and move 95- the first aproach was to have the live xwidget on-screen, and move
108 them about. the phantoms were generated by snapshoting the live 96 them about. the phantoms were generated by snapshoting the live
@@ -123,15 +111,13 @@ live and phantom widgets in different colors.
123the drawback is that its our own responsibility to handle drawing, 111the drawback is that its our own responsibility to handle drawing,
124which puts more of the display optimization burden on us. 112which puts more of the display optimization burden on us.
125 113
126this is the currently tried aproach and it works so-so at the moment. 114this is aproach worked so-so.
127 115
128- another aproach is to have both live and phantom widgets drawn 116- another aproach is to have both live and phantom widgets drawn
129 on-screen by proxy gtk objects. the live xwidget will be entirely 117 on-screen by proxy gtk objects. the live xwidget will be entirely
130 handled in an off-screen window, and the proxy objects will redirect 118 handled in an off-screen window, and the proxy objects will redirect
131 events there. 119 events there.
132 120
133This aproach seems promising, but complicated.
134
135- combine on-screen and off-screen aproaches. maybe composition is the 121- combine on-screen and off-screen aproaches. maybe composition is the
136 way to go for most cases, but on-screen xembeding is the way to go 122 way to go for most cases, but on-screen xembeding is the way to go
137 for particular special cases, like showing video in a 123 for particular special cases, like showing video in a
@@ -139,6 +125,8 @@ This aproach seems promising, but complicated.
139 particular case, and the user will simply have to accept that the 125 particular case, and the user will simply have to accept that the
140 phantom of a video widget isnt particularily beautiful. 126 phantom of a video widget isnt particularily beautiful.
141 127
128- The current and seemingly sanest aproach implements a MVC pattern.
129
142** Testing 130** Testing
143;;test like: 131;;test like:
144;; cd /path/to/xwidgets-emacs-dir 132;; cd /path/to/xwidgets-emacs-dir
@@ -176,11 +164,33 @@ work very well.
176spent any time on it, since getting the visuals right is much 164spent any time on it, since getting the visuals right is much
177harder. Anyway, I sort of think the interface should be somewhat like 165harder. Anyway, I sort of think the interface should be somewhat like
178it is, except symbols is used instead of integers. 166it is, except symbols is used instead of integers.
167*** DONE use symbols for xwidget types rather than ints
168 CLOSED: [2011-06-27 Mon 12:52]
169
170
171*** TODO better lisp based structure for xwidgets
172something like this:
173- a "process" like aproach to create the xwidgets. xwidgets are
174 coupled to buffers, somewhat like processes, except a buffer can
175 hold several xwidgets
176- an xwidget has a plist to hold the model, like a process
177- an xwidget has an assoc list of xwidget views
178
179there are some things that arent clear:
180- an xwidget doesnt necessarily need to be coupled to a buffer but it
181 seems to be the clearest model. xwidgets would be buffer local
182- xwidget-views are by necessity coupled to a emacs window so it might
183 be better to store them window locally rather than in an assoc
184 coupled to the xwidget model
185
186
179 187
180** TODO more documentation 188** TODO more documentation
181There should be user docs, and xwidget contributor docs. The current README 189There should be user docs, and xwidget contributor docs. The current README
182is all contributor docs there is now, apart from the code. 190is all contributor docs there is now, apart from the code.
183 191
192
193
184** TODO look into more ways of displaying xwidgets, like binding them to a 194** TODO look into more ways of displaying xwidgets, like binding them to a
185window rather than a point in a buffer. This was suggested by Chidong. 195window rather than a point in a buffer. This was suggested by Chidong.
186This would be a useful addition to Emacs in itself, and would avoid nearly all 196This would be a useful addition to Emacs in itself, and would avoid nearly all
@@ -190,7 +200,8 @@ replace the view of a particular window, and it would only show in
190that window. 200that window.
191 201
192 202
193** TODO MVC mode for xwidgets 203** DONE MVC mode for xwidgets
204 CLOSED: [2011-06-27 Mon 12:53]
194It appears unfruitful to chase using the same display mode for all 205It appears unfruitful to chase using the same display mode for all
195types of xwidgets. Composition is fun but not robust the way I'm 206types of xwidgets. Composition is fun but not robust the way I'm
196tried to do it. 207tried to do it.
@@ -208,5 +219,14 @@ themselves. Inkscape supports multiple views to the same document,
208other programs don't. In practice it might not be a big drawback. 219other programs don't. In practice it might not be a big drawback.
209 220
210 221
211*** TODO figure out what to do with the multiple frames case. 222*** DONE figure out what to do with the multiple frames case.
223 CLOSED: [2011-06-27 Mon 12:52]
212This should be easier to solve with MVC. 224This should be easier to solve with MVC.
225Surprisingly, this just worked!
226*** DONE how to propagate changes in views to other views?
227 CLOSED: [2011-06-27 Mon 12:53]
228I used gtk signals, the implementation for sliders works well!
229
230** TODO canvas support
231goocanvas is a gtk canvas implemented with cairo. investigate.
232http://developer.gnome.org/goocanvas/unstable/goocanvas-model-view-canvas.html
diff --git a/src/xwidget.c b/src/xwidget.c
index 1a0c23f5d9c..427004029d4 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -362,7 +362,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
362 int box_line_vwidth = max (s->face->box_line_width, 0); 362 int box_line_vwidth = max (s->face->box_line_width, 0);
363 int height = s->height; 363 int height = s->height;
364 364
365 int drawing_in_selected_window = (XWINDOW (FRAME_SELECTED_WINDOW (s->f))) == (s->w); 365 //int drawing_in_selected_window = (XWINDOW (FRAME_SELECTED_WINDOW (s->f))) == (s->w);
366 //TODO drawing_in_selected_window can be true for several windows if we have several frames. 366 //TODO drawing_in_selected_window can be true for several windows if we have several frames.
367 //we also need to check that the xwidget is to be drawn inside a window on a frame where it originaly lives. 367 //we also need to check that the xwidget is to be drawn inside a window on a frame where it originaly lives.
368 //otherwise draw a phantom, or maybe reparent the xwidget. 368 //otherwise draw a phantom, or maybe reparent the xwidget.
@@ -468,10 +468,11 @@ DEFUN ("xwidget-embed-steal-window", Fxwidget_embed_steal_window, Sxwidget_embed
468 468
469 469
470DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_internal, 3, 3, 0, doc: 470DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_internal, 3, 3, 0, doc:
471 ) 471 /* resize xwidgets */)
472 (Lisp_Object xwidget_id, Lisp_Object new_width, Lisp_Object new_height) 472 (Lisp_Object xwidget_id, Lisp_Object new_width, Lisp_Object new_height)
473{ 473{
474 struct xwidget *xw; 474 struct xwidget *xw;
475 struct xwidget_view *xv;
475 int xid, w, h; 476 int xid, w, h;
476 477
477 CHECK_NUMBER (xwidget_id); 478 CHECK_NUMBER (xwidget_id);
@@ -491,6 +492,15 @@ DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_inte
491 gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, 492 gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width,
492 xw->height); 493 xw->height);
493 */ 494 */
495 for (int i = 0; i < MAX_XWIDGETS; i++) //TODO MVC refactor lazy linear search
496 {
497 xv = &xwidget_views[i];
498 if(xv->model == xw){
499 gtk_layout_set_size (GTK_LAYOUT (xv->widgetwindow), xw->width, xw->height);
500 gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xw->width, xw->height);
501 }
502 }
503
494 return Qnil; 504 return Qnil;
495} 505}
496 506