]> code.delx.au - gnu-emacs/blob - lisp/xwidget.el
Merge branch 'master' into xwidget
[gnu-emacs] / lisp / xwidget.el
1 ;;; xwidget.el --- api functions for xwidgets -*- lexical-binding: t -*-
2 ;; see xwidget.c for more api functions
3
4
5 ;;; Commentary:
6 ;;
7
8 ;;TODO this breaks compilation when we dont have xwidgets
9 ;;(require 'xwidget-internal)
10
11 ;;TODO model after make-text-button instead!
12 ;;; Code:
13
14 (eval-when-compile (require 'cl))
15 (require 'reporter)
16 (require 'bookmark)
17
18 (defcustom xwidget-webkit-scroll-behaviour 'native
19 "Scroll behaviour of the webkit instance.
20 'native or 'image."
21 :group 'xwidgets)
22
23 (defun xwidget-insert (pos type title width height)
24 "Insert an xwidget at POS.
25 given ID, TYPE, TITLE WIDTH and
26 HEIGHT in the current buffer.
27
28 Return ID
29
30 see `make-xwidget' for types suitable for TYPE."
31 (goto-char pos)
32 (let ((id (make-xwidget (point) (point)
33 type title width height nil)))
34 (put-text-property (point) (+ 1 (point))
35 'display (list 'xwidget ':xwidget id))
36 id))
37
38 (defun xwidget-at (pos)
39 "Return xwidget at POS."
40 ;;TODO this function is a bit tedious because the C layer isnt well protected yet and
41 ;;xwidgetp aparently doesnt work yet
42 (let* ((disp (get-text-property pos 'display))
43 (xw (car (cdr (cdr disp)))))
44 ;;(if ( xwidgetp xw) xw nil)
45 (if (equal 'xwidget (car disp)) xw)))
46
47
48 ;; (defun xwidget-socket-handler ()
49 ;; "Create plug for socket. TODO."
50 ;; (interactive)
51 ;; (message "socket handler xwidget %S" last-input-event)
52 ;; (let*
53 ;; ((xwidget-event-type (nth 2 last-input-event))
54 ;; (xwidget-id (nth 1 last-input-event)))
55 ;; (cond ( (eq xwidget-event-type 'xembed-ready)
56 ;; (let*
57 ;; ((xembed-id (nth 3 last-input-event)))
58 ;; (message "xembed ready event: %S xw-id:%s" xembed-id xwidget-id)
59 ;; ;;TODO fetch process data from the xwidget. create it, store process info
60 ;; ;;will start emacs/uzbl in a xembed socket when its ready
61 ;; ;; (cond
62 ;; ;; ((eq 3 xwidget-id)
63 ;; ;; (start-process "xembed" "*xembed*" (format "%ssrc/emacs" default-directory) "-q" "--parent-id" (number-to-string xembed-id) ) )
64 ;; ;; ((eq 5 xwidget-id)
65 ;; ;; (start-process "xembed2" "*xembed2*" "uzbl-core" "-s" (number-to-string xembed-id) "http://www.fsf.org" ) )
66 ;; )))))
67
68 (defun xwidget-display (xwidget)
69 "Force XWIDGET to be displayed to create a xwidget_view.
70 Return the window displaying XWIDGET."
71 (let* ((buffer (xwidget-buffer xwidget))
72 (window (display-buffer buffer))
73 (frame (window-frame window)))
74 (set-frame-visible frame t)
75 (redisplay t)
76 window))
77
78
79 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
80 ;;; webkit support
81 (require 'browse-url)
82 (require 'image-mode);;for some image-mode alike functionality
83 (require 'cl-macs);;for flet
84
85 ;;;###autoload
86 (defun xwidget-webkit-browse-url (url &optional new-session)
87 "Ask xwidget-webkit to browse URL.
88 NEW-SESSION specifies whether to create a new xwidget-webkit session. URL
89 defaults to the string looking like a url around the cursor position."
90 (interactive (progn
91 (require 'browse-url)
92 (browse-url-interactive-arg "xwidget-webkit URL: "
93 ;;( xwidget-webkit-current-url)
94 )))
95 (when (stringp url)
96 (setq url (url-tidy url))
97 (if new-session
98 (xwidget-webkit-new-session url)
99 (xwidget-webkit-goto-url url))))
100
101
102 ;;shims for adapting image mode code to the webkit browser window
103 (defun xwidget-image-display-size (spec &optional pixels frame)
104 "Image code adaptor. SPEC PIXELS FRAME like the corresponding `image-mode' fn."
105 (let ((xwi (xwidget-info (xwidget-at 1))))
106 (cons (aref xwi 2)
107 (aref xwi 3))))
108
109 (defadvice image-display-size (around image-display-size-for-xwidget
110 (spec &optional pixels frame)
111 activate)
112 "Advice for re-using image mode for xwidget."
113 (if (eq (car spec) 'xwidget)
114 (setq ad-return-value (xwidget-image-display-size spec pixels frame))
115 ad-do-it))
116
117 ;;todo.
118 ;; - check that the webkit support is compiled in
119 (defvar xwidget-webkit-mode-map
120 (let ((map (make-sparse-keymap)))
121 (define-key map "g" 'xwidget-webkit-browse-url)
122 (define-key map "a" 'xwidget-webkit-adjust-size-dispatch)
123 (define-key map "b" 'xwidget-webkit-back )
124 (define-key map "r" 'xwidget-webkit-reload )
125 (define-key map "t" (lambda () (interactive) (message "o")) )
126 (define-key map "\C-m" 'xwidget-webkit-insert-string)
127 (define-key map "w" 'xwidget-webkit-current-url)
128
129 ;;similar to image mode bindings
130 (define-key map (kbd "SPC") 'xwidget-webkit-scroll-up)
131 (define-key map (kbd "DEL") 'xwidget-webkit-scroll-down)
132
133 (define-key map [remap scroll-up] 'xwidget-webkit-scroll-up)
134 (define-key map [remap scroll-up-command] 'xwidget-webkit-scroll-up)
135
136 (define-key map [remap scroll-down] 'xwidget-webkit-scroll-down)
137 (define-key map [remap scroll-down-command] 'xwidget-webkit-scroll-down)
138
139 (define-key map [remap forward-char] 'xwidget-webkit-scroll-forward)
140 (define-key map [remap backward-char] 'xwidget-webkit-scroll-backward)
141 (define-key map [remap right-char] 'xwidget-webkit-scroll-forward)
142 (define-key map [remap left-char] 'xwidget-webkit-scroll-backward)
143 ;; (define-key map [remap previous-line] 'image-previous-line)
144 ;; (define-key map [remap next-line] 'image-next-line)
145
146 ;; (define-key map [remap move-beginning-of-line] 'image-bol)
147 ;; (define-key map [remap move-end-of-line] 'image-eol)
148 ;; (define-key map [remap beginning-of-buffer] 'image-bob)
149 ;; (define-key map [remap end-of-buffer] 'image-eob)
150 map)
151 "Keymap for `xwidget-webkit-mode'.")
152
153 (defun xwidget-webkit-scroll-up ()
154 "Scroll webkit up,either native or like image mode."
155 (interactive)
156 (if (eq xwidget-webkit-scroll-behaviour 'native)
157 (xwidget-set-adjustment (xwidget-webkit-last-session) 'vertical t 50)
158 (image-scroll-up)))
159
160 (defun xwidget-webkit-scroll-down ()
161 "Scroll webkit down,either native or like image mode."
162 (interactive)
163 (if (eq xwidget-webkit-scroll-behaviour 'native)
164 (xwidget-set-adjustment (xwidget-webkit-last-session) 'vertical t -50)
165 (image-scroll-down)))
166
167 (defun xwidget-webkit-scroll-forward ()
168 "Scroll webkit forward,either native or like image mode."
169 (interactive)
170 (if (eq xwidget-webkit-scroll-behaviour 'native)
171 (xwidget-set-adjustment (xwidget-webkit-last-session) 'horizontal t 50)
172 (xwidget-webkit-scroll-forward)))
173
174 (defun xwidget-webkit-scroll-backward ()
175 "Scroll webkit backward,either native or like image mode."
176 (interactive)
177 (if (eq xwidget-webkit-scroll-behaviour 'native)
178 (xwidget-set-adjustment (xwidget-webkit-last-session) 'horizontal t -50)
179 (xwidget-webkit-scroll-backward)))
180
181
182 ;;the xwidget event needs to go into a higher level handler
183 ;;since the xwidget can generate an event even if its offscreen
184 ;;TODO this needs to use callbacks and consider different xw ev types
185 (define-key (current-global-map) [xwidget-event] 'xwidget-event-handler)
186 (defun xwidget-log ( &rest msg)
187 "Log MSG to a buffer."
188 (let ( (buf (get-buffer-create "*xwidget-log*")))
189 (save-excursion
190 (buffer-disable-undo buf)
191 (set-buffer buf)
192 (insert (apply 'format msg))
193 (insert "\n"))))
194
195 (defun xwidget-event-handler ()
196 "Receive xwidget event."
197 (interactive)
198 (xwidget-log "stuff happened to xwidget %S" last-input-event)
199 (let*
200 ((xwidget-event-type (nth 1 last-input-event))
201 (xwidget (nth 2 last-input-event))
202 ;(xwidget-callback (xwidget-get xwidget 'callback));;TODO stopped working for some reason
203 )
204 ;(funcall xwidget-callback xwidget xwidget-event-type)
205 (message "xw callback %s" xwidget)
206 (funcall 'xwidget-webkit-callback xwidget xwidget-event-type)))
207
208 (defun xwidget-webkit-callback (xwidget xwidget-event-type)
209 "Callback for xwidgets.
210 XWIDGET instance, XWIDGET-EVENT-TYPE depends on the originating xwidget."
211 (save-excursion
212 (cond ((buffer-live-p (xwidget-buffer xwidget))
213 (set-buffer (xwidget-buffer xwidget))
214 (let* ((strarg (nth 3 last-input-event)))
215 (cond ((eq xwidget-event-type 'document-load-finished)
216 (xwidget-log "webkit finished loading: '%s'" (xwidget-webkit-get-title xwidget))
217 ;;TODO - check the native/internal scroll
218 ;;(xwidget-adjust-size-to-content xwidget)
219 (xwidget-webkit-adjust-size-dispatch) ;;TODO send xwidget here
220 (rename-buffer (format "*xwidget webkit: %s *" (xwidget-webkit-get-title xwidget)))
221 (pop-to-buffer (current-buffer)))
222 ((eq xwidget-event-type 'navigation-policy-decision-requested)
223 (if (string-match ".*#\\(.*\\)" strarg)
224 (xwidget-webkit-show-id-or-named-element xwidget (match-string 1 strarg))))
225 (t (xwidget-log "unhandled event:%s" xwidget-event-type)))))
226 (t (xwidget-log "error: callback called for xwidget with dead buffer")))))
227
228 (defvar bookmark-make-record-function)
229 (define-derived-mode xwidget-webkit-mode
230 special-mode "xwidget-webkit" "xwidget webkit view mode"
231 (setq buffer-read-only t)
232 (setq-local bookmark-make-record-function
233 #'xwidget-webkit-bookmark-make-record)
234 ;; Keep track of [vh]scroll when switching buffers
235 (image-mode-setup-winprops))
236
237 (defun xwidget-webkit-bookmark-make-record ()
238 (nconc (bookmark-make-record-default t t)
239 `((page . ,(xwidget-webkit-current-url))
240 (handler . (lambda (bmk) (browse-url (bookmark-prop-get bmk 'page)))))))
241
242
243 (defvar xwidget-webkit-last-session-buffer nil)
244
245 (defun xwidget-webkit-last-session ()
246 "Last active webkit, or nil."
247 (if (buffer-live-p xwidget-webkit-last-session-buffer)
248 (with-current-buffer xwidget-webkit-last-session-buffer
249 (xwidget-at 1))
250 nil))
251
252 (defun xwidget-webkit-current-session ()
253 "Either the webkit in the current buffer, or the last one used, which might be nil."
254 (if (xwidget-at 1)
255 (xwidget-at 1)
256 (xwidget-webkit-last-session)))
257
258 (defun xwidget-adjust-size-to-content (xw)
259 "Resize XW to content."
260 ;;xwidgets doesnt support widgets that have their own opinions about size well yet
261 ;;this reads the desired size and resizes the emacs allocated area accordingly
262 (let ((size (xwidget-size-request xw)))
263 (xwidget-resize xw (car size) (cadr size))))
264
265
266 (defvar xwidget-webkit-activeelement-js"
267 function findactiveelement(doc){
268 //alert(doc.activeElement.value);
269 if(doc.activeElement.value != undefined){
270 return doc.activeElement;
271 }else{
272 // recurse over the child documents:
273 var frames = doc.getElementsByTagName('frame');
274 for (var i = 0; i < frames.length; i++)
275 {
276 var d = frames[i].contentDocument;
277 var rv = findactiveelement(d);
278 if(rv != undefined){
279 return rv;
280 }
281 }
282 }
283 return undefined;
284 };
285
286
287 "
288
289 "javascript that finds the active element."
290 ;;yes its ugly. because:
291 ;; - there is aparently no way to find the active frame other than recursion
292 ;; - the js "for each" construct missbehaved on the "frames" collection
293 ;; - a window with no frameset still has frames.length == 1, but frames[0].document.activeElement != document.activeElement
294 ;;TODO the activeelement type needs to be examined, for iframe, etc. sucks.
295 )
296
297 (defun xwidget-webkit-insert-string (xw str)
298 "Insert string in the active field in the webkit.
299 Argument XW webkit.
300 Argument STR string."
301 ;;read out the string in the field first and provide for edit
302 (interactive
303 (let* ((xww (xwidget-webkit-current-session))
304
305 (field-value
306 (progn
307 (xwidget-webkit-execute-script xww xwidget-webkit-activeelement-js)
308 (xwidget-webkit-execute-script-rv xww "findactiveelement(document).value;" )))
309 (field-type (xwidget-webkit-execute-script-rv xww "findactiveelement(document).type;" )))
310 (list xww
311 (cond ((equal "text" field-type)
312 (read-string "text:" field-value))
313 ((equal "password" field-type)
314 (read-passwd "password:" nil field-value))
315 ((equal "textarea" field-type)
316 (xwidget-webkit-begin-edit-textarea xww field-value))))))
317 (xwidget-webkit-execute-script xw (format "findactiveelement(document).value='%s'" str)))
318
319 (defvar xwidget-xwbl)
320 (defun xwidget-webkit-begin-edit-textarea (xw text)
321 "Start editing of a webkit text area.
322 XW is the xwidget identifier, TEXT is retrieved from the webkit."
323 (switch-to-buffer
324 (generate-new-buffer "textarea"))
325
326 (set (make-local-variable 'xwidget-xwbl) xw)
327 (insert text))
328
329 (defun xwidget-webkit-end-edit-textarea ()
330 "End editing of a webkit text area."
331 (interactive)
332 (goto-char (point-min))
333 (while (search-forward "\n" nil t)
334 (replace-match "\\n" nil t))
335 (xwidget-webkit-execute-script xwidget-xwbl (format "findactiveelement(document).value='%s'"
336 (buffer-substring (point-min) (point-max))))
337 ;;TODO convert linefeed to \n
338 )
339
340 (defun xwidget-webkit-show-named-element (xw element-name)
341 "Make named-element show. for instance an anchor."
342 (interactive (list (xwidget-webkit-current-session) (read-string "element name:")))
343 ;;TODO
344 ;; since an xwidget is an Emacs object, it is not trivial to do some things that are taken for granted in a normal browser.
345 ;; scrolling an anchor/named-element into view is one such thing.
346 ;; this function implements a proof-of-concept for this.
347 ;; problems remaining:
348 ;; - the selected window is scrolled but this is not always correct
349 ;; - this needs to be interfaced into browse-url somehow. the tricky part is that we need to do this in two steps:
350 ;; A: load the base url, wait for load signal to arrive B: navigate to the anchor when the base url is finished rendering
351
352 ;;this part figures out the Y coordinate of the element
353 (let ((y (string-to-number
354 (xwidget-webkit-execute-script-rv xw
355 (format "document.getElementsByName('%s')[0].getBoundingClientRect().top" element-name)
356 0))))
357 ;;now we need to tell emacs to scroll the element into view.
358 (xwidget-log "scroll: %d" y)
359 (set-window-vscroll (selected-window) y t)))
360
361 (defun xwidget-webkit-show-id-element (xw element-id)
362 "make id-element show. for instance an anchor."
363 (interactive (list (xwidget-webkit-current-session)
364 (read-string "element id:")))
365 (let ((y (string-to-number
366 (xwidget-webkit-execute-script-rv xw
367 (format "document.getElementById('%s').getBoundingClientRect().top" element-id)
368 0))))
369 ;;now we need to tell emacs to scroll the element into view.
370 (xwidget-log "scroll: %d" y)
371 (set-window-vscroll (selected-window) y t)))
372
373 (defun xwidget-webkit-show-id-or-named-element (xw element-id)
374 "make id-element show. for instance an anchor."
375 (interactive (list (xwidget-webkit-current-session)
376 (read-string "element id:")))
377 (let* ((y1 (string-to-number
378 (xwidget-webkit-execute-script-rv xw
379 (format "document.getElementsByName('%s')[0].getBoundingClientRect().top" element-id)
380 "0")))
381 (y2 (string-to-number
382 (xwidget-webkit-execute-script-rv xw
383 (format "document.getElementById('%s').getBoundingClientRect().top" element-id)
384 "0")))
385 (y3 (max y1 y2)))
386 ;;now we need to tell emacs to scroll the element into view.
387 (xwidget-log "scroll: %d" y3)
388 (set-window-vscroll (selected-window) y3 t)))
389
390 (defun xwidget-webkit-adjust-size-to-content ()
391 "Adjust webkit to content size."
392 (interactive)
393 (xwidget-adjust-size-to-content (xwidget-webkit-current-session)))
394
395 (defun xwidget-webkit-adjust-size-dispatch ()
396 "Adjust size according to mode."
397 (interactive)
398 (if (eq xwidget-webkit-scroll-behaviour 'native)
399 (xwidget-webkit-adjust-size-to-window)
400 (xwidget-webkit-adjust-size-to-content))
401 ;;the recenter is intended to correct a visual glitch
402 ;;it errors out if the buffer isnt visible, but then we dont get the glitch,
403 ;;so silence errors
404 (ignore-errors
405 (recenter-top-bottom))
406 )
407
408 (defun xwidget-webkit-adjust-size-to-window ()
409 "Adjust webkit to window."
410 (interactive)
411 (xwidget-resize ( xwidget-webkit-current-session) (window-pixel-width) (window-pixel-height)))
412
413 (defun xwidget-webkit-adjust-size (w h)
414 "Manualy set webkit size.
415 Argument W width.
416 Argument H height."
417 ;;TODO shouldnt be tied to the webkit xwidget
418 (interactive "nWidth:\nnHeight:\n")
419 (xwidget-resize ( xwidget-webkit-current-session) w h))
420
421 (defun xwidget-webkit-fit-width ()
422 "Adjust width of webkit to window width."
423 (interactive)
424 (xwidget-webkit-adjust-size (- (caddr (window-inside-pixel-edges))
425 (car (window-inside-pixel-edges)))
426 1000))
427
428 (defun xwidget-webkit-new-session (url)
429 "Create a new webkit session buffer with URL."
430 (let*
431 ((bufname (generate-new-buffer-name "*xwidget-webkit*"))
432 xw)
433 (setq xwidget-webkit-last-session-buffer (switch-to-buffer (get-buffer-create bufname)))
434 (insert " 'a' adjusts the xwidget size.")
435 (setq xw (xwidget-insert 1 'webkit-osr bufname 1000 1000))
436 (xwidget-put xw 'callback 'xwidget-webkit-callback)
437 (xwidget-webkit-mode)
438 (xwidget-webkit-goto-uri (xwidget-webkit-last-session) url )))
439
440
441 (defun xwidget-webkit-goto-url (url)
442 "Goto URL."
443 (if (xwidget-webkit-current-session)
444 (progn
445 (xwidget-webkit-goto-uri (xwidget-webkit-current-session) url))
446 (xwidget-webkit-new-session url)))
447
448 (defun xwidget-webkit-back ()
449 "Back in history."
450 (interactive)
451 (xwidget-webkit-execute-script (xwidget-webkit-current-session) "history.go(-1);"))
452
453 (defun xwidget-webkit-reload ()
454 "Reload current url."
455 (interactive)
456 (xwidget-webkit-execute-script (xwidget-webkit-current-session) "history.go(0);"))
457
458 (defun xwidget-webkit-current-url ()
459 "Get the webkit url. place it on kill ring."
460 (interactive)
461 (let* ((rv (xwidget-webkit-execute-script-rv (xwidget-webkit-current-session)
462 "document.URL"))
463 (url (kill-new (or rv ""))))
464 (message "url: %s" url )
465 url))
466
467 (defun xwidget-webkit-execute-script-rv (xw script &optional default)
468 "Same as 'xwidget-webkit-execute-script' but but with return value.
469 XW is the webkit instance. SCRIPT is the script to execut.
470 DEFAULT is the defaultreturn value."
471 ;;notice the fugly "title" hack. it is needed because the webkit api
472 ;;doesnt support returning values. this is a wrapper for the title
473 ;;hack so its easy to remove should webkit someday support JS return
474 ;;values or we find some other way to access the DOM
475
476 ;;reset webkit title. fugly.
477 (let* ((emptytag "titlecantbewhitespaceohthehorror")
478 title)
479 (xwidget-webkit-execute-script xw (format "document.title=\"%s\";" (or default emptytag)))
480 (xwidget-webkit-execute-script xw (format "document.title=%s;" script))
481 (setq title (xwidget-webkit-get-title xw))
482 (if (equal emptytag title)
483 (setq title ""))
484 (unless title
485 (setq title default))
486 title))
487
488
489 ;; use declare here?
490 ;; (declare-function xwidget-resize-internal "xwidget.c" )
491 ;; check-declare-function?
492
493 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
494 (defun xwidget-webkit-get-selection ()
495 "Get the webkit selection."
496 (xwidget-webkit-execute-script-rv (xwidget-webkit-current-session)
497 "window.getSelection().toString();"))
498
499 (defun xwidget-webkit-copy-selection-as-kill ()
500 "Get the webkit selection and put it on the kill ring."
501 (interactive)
502 (kill-new (xwidget-webkit-get-selection)))
503
504
505 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
506 ;; xwidget plist management(similar to the process plist functions)
507
508 (defun xwidget-get (xwidget propname)
509 "Return the value of XWIDGET' PROPNAME property.
510 This is the last value stored with `(xwidget-put XWIDGET PROPNAME VALUE)'."
511 (plist-get (xwidget-plist xwidget) propname))
512
513 (defun xwidget-put (xwidget propname value)
514 "Change XWIDGET' PROPNAME property to VALUE.
515 It can be retrieved with `(xwidget-get XWIDGET PROPNAME)'."
516 (set-xwidget-plist xwidget
517 (plist-put (xwidget-plist xwidget) propname value)))
518
519
520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
521
522 (defun xwidget-delete-zombies ()
523 "Helper for xwidget-cleanup."
524 (dolist (xwidget-view xwidget-view-list)
525 (when (or (not (window-live-p (xwidget-view-window xwidget-view)))
526 (not (memq (xwidget-view-model xwidget-view)
527 xwidget-list)))
528 (delete-xwidget-view xwidget-view))))
529
530 (defun xwidget-cleanup ()
531 "Delete zombie xwidgets."
532 ;;its still pretty easy to trigger bugs with xwidgets.
533 ;;this function tries to implement a workaround
534 (interactive)
535 ;; kill xviews who should have been deleted but stull linger
536 (xwidget-delete-zombies)
537 ;; redraw display otherwise ghost of zombies will remain to haunt the screen
538 (redraw-display))
539
540 ;;this is a workaround because I cant find the right place to put it in C
541 ;;seems to work well in practice though
542 ;;(add-hook 'window-configuration-change-hook 'xwidget-cleanup)
543 (add-hook 'window-configuration-change-hook 'xwidget-delete-zombies)
544
545 (defun xwidget-kill-buffer-query-function ()
546 "Ask beforek illing a buffer that has xwidgets."
547 (let ((xwidgets (get-buffer-xwidgets (current-buffer))))
548 (or (not xwidgets)
549 (not (memq t (mapcar 'xwidget-query-on-exit-flag xwidgets)))
550 (yes-or-no-p
551 (format "Buffer %S has xwidgets; kill it? "
552 (buffer-name (current-buffer)))))))
553
554 (add-hook 'kill-buffer-query-functions 'xwidget-kill-buffer-query-function)
555
556 ;;killflash is sadly not reliable yet.
557 (defvar xwidget-webkit-kill-flash-oneshot t)
558 (defun xwidget-webkit-kill-flash ()
559 "Disable the flash plugin in webkit.
560 This is needed because Flash is non-free and doesnt work reliably
561 on 64 bit systems and offscreen rendering. Sadly not reliable
562 yet, so deinstall Flash instead for now."
563 ;;you can only call this once or webkit crashes and takes emacs with it. odd.
564 (unless xwidget-webkit-kill-flash-oneshot
565 (xwidget-disable-plugin-for-mime "application/x-shockwave-flash")
566 (setq xwidget-webkit-kill-flash-oneshot t)))
567
568 (xwidget-webkit-kill-flash)
569
570 (defun report-xwidget-bug ()
571 "Report a bug in GNU Emacs about the XWidget branch.
572 Prompts for bug subject. Leaves you in a mail buffer."
573 (interactive)
574 (let ((reporter-prompt-for-summary-p t))
575 (reporter-submit-bug-report "submit@debbugs.gnu.org" nil nil nil nil
576 (format "Package: emacs-xwidgets
577
578 Please describee xactly whata ctions triggered the bug, and the
579 precise symptoms of the bug. If you can, give a recipe starting
580 from `emacs -Q'.
581
582 If Emacs crashed, and you have the Emacs process in the gdb
583 deubbger, please include the output from the following gdb
584 commands:
585 `bt full' and `xbacktrace'.
586
587 For information about debugging Emacs, please read the file
588 %s" (expand-file-name "DEBUG" data-directory)))))
589
590 (provide 'xwidget)
591
592 ;;; xwidget.el ends here