Enable editing a link by clicking on it.

* src/client/composer/composer-widget.vala
  (ComposerWidget::on_button_press): Show a link popover on button
  release.

* src/client/composer/composer-web-view.vala (ComposerWebView): Add
  button_release_event_done signal to work around WK eating mouse events,
  fire it after default processing has occurred.

* ui/composer-web-view.js: Don't bother selecting a link on click, we
  are handling insertion and deletion without it fine now. Just cancel
  the event's default so link clicks are not activated.
This commit is contained in:
Michael James Gratton 2017-01-19 13:16:13 +11:00
parent e4f50e1c36
commit ab4fec91be
3 changed files with 37 additions and 4 deletions

View file

@ -158,6 +158,9 @@ public class ComposerWebView : ClientWebView {
/** Emitted when the cursor's edit context has changed. */
public signal void cursor_context_changed(EditContext cursor_context);
/** Workaround for WebView eating the button event */
internal signal bool button_release_event_done(Gdk.Event event);
public ComposerWebView(Configuration config) {
base(config);
@ -447,6 +450,15 @@ public class ComposerWebView : ClientWebView {
return ""; // XXX
}
public override bool button_release_event(Gdk.EventButton event) {
// WebView seems to unconditionally consume button events, so
// to show a link popopver after the view has processed one,
// we need to emit our own.
bool ret = base.button_press_event(event);
button_release_event_done(event);
return ret;
}
private void on_command_stack_changed(WebKit.JavascriptResult result) {
try {
string[] values = WebKitUtil.to_string(result).split(",");

View file

@ -508,6 +508,7 @@ public class ComposerWidget : Gtk.EventBox {
this.reply_to_entry.changed.connect(validate_send_button);
this.editor.command_stack_changed.connect(on_command_state_changed);
this.editor.button_release_event_done.connect(on_button_release);
this.editor.context_menu.connect(on_context_menu);
this.editor.cursor_context_changed.connect(on_cursor_context_changed);
this.editor.document_modified.connect(() => { draft_changed(); });
@ -2213,6 +2214,29 @@ public class ComposerWidget : Gtk.EventBox {
}
}
private bool on_button_release(Gdk.Event event) {
// Show the link popover on mouse release (instead of press)
// so the user can still select text with a link in it,
// without the popover immediately appearing and raining on
// their text selection parade.
if (this.pointer_url != null &&
this.actions.get_action_state(ACTION_COMPOSE_AS_HTML).get_boolean()) {
Gdk.EventButton? button = (Gdk.EventButton) event;
Gdk.Rectangle location = new Gdk.Rectangle();
location.x = (int) button.x;
location.y = (int) button.y;
ComposerLinkPopover popover = new_link_popover(
ComposerLinkPopover.Type.EXISTING_LINK,
this.pointer_url
);
popover.set_relative_to(this.editor);
popover.set_pointing_to(location);
popover.show();
}
return Gdk.EVENT_PROPAGATE;
}
private void on_cursor_context_changed(ComposerWebView.EditContext context) {
this.cursor_url = context.is_link ? context.link_url : null;
update_cursor_actions();

View file

@ -33,7 +33,7 @@ ComposerPageState.prototype = {
document.addEventListener("click", function(e) {
if (e.target.tagName == "A") {
state.linkClicked(e.target);
e.preventDefault();
}
}, true);
@ -204,9 +204,6 @@ ComposerPageState.prototype = {
documentModified: function(element) {
window.webkit.messageHandlers.documentModified.postMessage(null);
},
linkClicked: function(element) {
window.getSelection().selectAllChildren(element);
},
selectionChanged: function() {
PageState.prototype.selectionChanged.apply(this, []);