Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/308a24e66171190d321df...
...commit
http://git.netsurf-browser.org/netsurf.git/commit/308a24e66171190d321dfed...
...tree
http://git.netsurf-browser.org/netsurf.git/tree/308a24e66171190d321dfed62...
The branch, master has been updated
via 308a24e66171190d321dfed622dc83e16bd64549 (commit)
via 97aceb5a681faf288e38b5db9e408931ff0d3e6b (commit)
via 10b422b16344f24bbb766f52dc3f0d6da7fde194 (commit)
from 704e5cc839b5baa02fba5e1ceba3d37aa2f37bb8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=308a24e66171190d321...
commit 308a24e66171190d321dfed622dc83e16bd64549
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Start implementing undo/redo. For now it just records changes, the actual undo/redo
handling is not yet done.
diff --git a/desktop/textarea.c b/desktop/textarea.c
index 65f0c53..8f53bf7 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -64,13 +64,19 @@ struct textarea_utf8 {
};
struct textarea_undo_detail {
- unsigned int offset; /**< Offset to detail's text in undo.text */
- unsigned int len; /**< Length of detail's text */
+ unsigned int b_start; /**< Offset to detail's text in undo buffer */
+ unsigned int b_end; /**< End of text (exclusive) */
+ unsigned int b_limit; /**< End of detail space (exclusive) */
+
+ unsigned int b_text_start; /**< Start of textarea text. */
+ unsigned int b_text_end; /**< End of textarea text (exclusive) */
};
struct textarea_undo {
- unsigned int next_detail;
- struct textarea_undo_detail *details;
+ unsigned int details_alloc; /**< Details allocated for */
+ unsigned int next_detail; /**< Next detail pos */
+ unsigned int last_detail; /**< Last detail used */
+ struct textarea_undo_detail *details; /**< Array of undo details */
struct textarea_utf8 text;
};
@@ -135,6 +141,8 @@ struct textarea {
int drag_start; /**< Byte offset of drag start (in ta->show) */
struct textarea_drag drag_info; /**< Drag information */
+
+ struct textarea_undo undo; /**< Undo/redo information */
};
@@ -1425,7 +1433,7 @@ static bool textarea_replace_text_internal(struct textarea *ta,
size_t b_start,
/* Ensure textarea's text buffer is large enough */
if (rep_len + ta->text.len - (b_end - b_start) >= ta->text.alloc) {
char *temp = realloc(ta->text.data,
- rep_len + ta->text.len - (b_end - b_start) +
+ rep_len + ta->text.len - (b_end - b_start) +
TA_ALLOC_STEP);
if (temp == NULL) {
LOG(("realloc failed"));
@@ -1474,6 +1482,74 @@ static bool textarea_replace_text_internal(struct textarea *ta,
size_t b_start,
/**
+ * Update undo buffer by adding any text to be replaced, and allocating
+ * space as appropriate.
+ *
+ * \param ta Textarea widget
+ * \param b_start Start byte index of replaced section (inclusive)
+ * \param b_end End byte index of replaced section (exclusive)
+ * \param rep_len Byte length of replacement UTF-8 text
+ * \return false on memory exhaustion, true otherwise
+ */
+static bool textarea_copy_to_undo_buffer(struct textarea *ta,
+ size_t b_start, size_t b_end, size_t rep_len)
+{
+ struct textarea_undo *undo;
+ size_t b_offset;
+ unsigned int len = b_end - b_start;
+
+ undo = &ta->undo;
+
+ if (undo->next_detail == 0)
+ b_offset = 0;
+ else
+ b_offset = undo->details[undo->next_detail - 1].b_limit;
+
+ len = len > rep_len ? len : rep_len;
+
+ if (b_offset + len >= undo->text.alloc) {
+ /* Need more memory for undo buffer */
+ char *temp = realloc(undo->text.data,
+ b_offset + len + TA_ALLOC_STEP);
+ if (temp == NULL) {
+ LOG(("realloc failed"));
+ return false;
+ }
+
+ undo->text.data = temp;
+ undo->text.alloc = b_offset + len + TA_ALLOC_STEP;
+ }
+
+ if (undo->next_detail >= undo->details_alloc) {
+ /* Need more memory for undo details */
+ struct textarea_undo_detail *temp = realloc(undo->details,
+ (undo->next_detail + 128) *
+ sizeof(struct textarea_undo_detail));
+ if (temp == NULL) {
+ LOG(("realloc failed"));
+ return false;
+ }
+
+ undo->details = temp;
+ undo->details_alloc = undo->next_detail + 128;
+ }
+
+ /* Put text into buffer */
+ memcpy(undo->text.data + b_offset, ta->text.data + b_start,
+ b_end - b_start);
+
+ /* Update next_detail */
+ undo->details[undo->next_detail].b_start = b_offset;
+ undo->details[undo->next_detail].b_end = b_offset + b_end - b_start;
+ undo->details[undo->next_detail].b_limit = len;
+
+ undo->details[undo->next_detail].b_text_start = b_start;
+
+ return true;
+}
+
+
+/**
* Replace text in a textarea, updating undo buffer.
*
* \param ta Textarea widget
@@ -1493,8 +1569,13 @@ static bool textarea_replace_text(struct textarea *ta, size_t
b_start,
size_t b_end, const char *rep, size_t rep_len,
bool add_to_clipboard, int *byte_delta, struct rect *r)
{
- /* TODO: Make copy of any replaced text */
- if (b_start != b_end) {
+ if (!(b_start != b_end && rep_len == 0 && add_to_clipboard) &&
+ !(ta->flags & TEXTAREA_PASSWORD)) {
+ /* Not just copying to clipboard, and not a password field;
+ * Sort out undo buffer. */
+ if (textarea_copy_to_undo_buffer(ta, b_start, b_end,
+ rep_len) == false)
+ return false;
}
/* Replace the text in the textarea, and reflow it */
@@ -1503,12 +1584,63 @@ static bool textarea_replace_text(struct textarea *ta, size_t
b_start,
return false;
}
- if (b_start == b_end && rep_len == 0) {
- /* Nothing changed at all */
- return true;
+ if (!(b_start != b_end && rep_len == 0 && add_to_clipboard) &&
+ !(ta->flags & TEXTAREA_PASSWORD)) {
+ /* Not just copying to clipboard, and not a password field;
+ * Update UNDO buffer */
+ ta->undo.details[ta->undo.next_detail].b_text_end =
+ b_end + *byte_delta;
+ ta->undo.last_detail = ta->undo.next_detail;
+ ta->undo.next_detail++;
}
- /* TODO: Update UNDO buffer */
+ return true;
+}
+
+
+/**
+ * Undo previous change.
+ *
+ * \param ta Textarea widget
+ * \param byte_delta Updated to change in byte count in textarea (ta->show)
+ * \param r Updated to area where redraw is required
+ * \return false if nothing to undo, true otherwise
+ */
+static bool textarea_undo(struct textarea *ta, int *byte_delta, struct rect *r)
+{
+ if (ta->flags & TEXTAREA_PASSWORD)
+ /* No undo for password fields */
+ return false;
+
+ if (ta->undo.next_detail == 0)
+ /* Nothing to undo */
+ return false;
+
+ /* TODO */
+
+ return true;
+}
+
+
+/**
+ * Redo previous undo.
+ *
+ * \param ta Textarea widget
+ * \param byte_delta Updated to change in byte count in textarea (ta->show)
+ * \param r Updated to area where redraw is required
+ * \return false if nothing to redo, true otherwise
+ */
+static bool textarea_redo(struct textarea *ta, int *byte_delta, struct rect *r)
+{
+ if (ta->flags & TEXTAREA_PASSWORD)
+ /* No REDO for password fields */
+ return false;
+
+ if (ta->undo.next_detail > ta->undo.last_detail)
+ /* Nothing to redo */
+ return false;
+
+ /* TODO */
return true;
}
@@ -1652,9 +1784,21 @@ struct textarea *textarea_create(const textarea_flags flags,
ret->scroll_y = 0;
ret->bar_x = NULL;
ret->bar_y = NULL;
+ ret->h_extent = setup->width;
+ ret->v_extent = setup->height;
ret->drag_start = 0;
ret->drag_info.type = TEXTAREA_DRAG_NONE;
+ ret->undo.details_alloc = 0;
+ ret->undo.next_detail = 0;
+ ret->undo.last_detail = 0;
+ ret->undo.details = NULL;
+
+ ret->undo.text.data = NULL;
+ ret->undo.text.alloc = 0;
+ ret->undo.text.len = 0;
+ ret->undo.text.utf8_len = 0;
+
ret->text.data = malloc(TA_ALLOC_STEP);
if (ret->text.data == NULL) {
@@ -1727,6 +1871,9 @@ void textarea_destroy(struct textarea *ta)
if (ta->flags & TEXTAREA_PASSWORD)
free(ta->password.data);
+ free(ta->undo.text.data);
+ free(ta->undo.details);
+
free(ta->text.data);
free(ta->lines);
free(ta);
@@ -2562,6 +2709,30 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
}
caret += byte_delta;
break;
+ case KEY_UNDO:
+ if (!textarea_undo(ta, &byte_delta, &r)) {
+ /* We consume the UNDO, even if we can't act
+ * on it. */
+ return true;
+ }
+ caret += byte_delta;
+ if (ta->sel_start != -1) {
+ textarea_clear_selection(ta);
+ }
+ redraw = true;
+ break;
+ case KEY_REDO:
+ if (!textarea_redo(ta, &byte_delta, &r)) {
+ /* We consume the REDO, even if we can't act
+ * on it. */
+ return true;
+ }
+ caret += byte_delta;
+ if (ta->sel_start != -1) {
+ textarea_clear_selection(ta);
+ }
+ redraw = true;
+ break;
default:
return false;
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=97aceb5a681faf288e3...
commit 97aceb5a681faf288e38b5db9e408931ff0d3e6b
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Pass KEY_UNDO and KEY_REDO to core. (Currently ignored.)
diff --git a/framebuffer/gui.c b/framebuffer/gui.c
index c9adf6c..6530c38 100644
--- a/framebuffer/gui.c
+++ b/framebuffer/gui.c
@@ -971,6 +971,34 @@ fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info
*cbi)
modifier |= FBTK_MOD_LCTRL;
break;
+ case NSFB_KEY_y:
+ case NSFB_KEY_z:
+ if (cbi->event->value.keycode == NSFB_KEY_z &&
+ (modifier & FBTK_MOD_RCTRL ||
+ modifier & FBTK_MOD_LCTRL) &&
+ (modifier & FBTK_MOD_RSHIFT ||
+ modifier & FBTK_MOD_LSHIFT)) {
+ /* Z pressed with CTRL and SHIFT held */
+ browser_window_key_press(gw->bw, KEY_REDO);
+ break;
+
+ } else if (cbi->event->value.keycode == NSFB_KEY_z &&
+ (modifier & FBTK_MOD_RCTRL ||
+ modifier & FBTK_MOD_LCTRL)) {
+ /* Z pressed with CTRL held */
+ browser_window_key_press(gw->bw, KEY_UNDO);
+ break;
+
+ } else if (cbi->event->value.keycode == NSFB_KEY_y &&
+ (modifier & FBTK_MOD_RCTRL ||
+ modifier & FBTK_MOD_LCTRL)) {
+ /* Y pressed with CTRL held */
+ browser_window_key_press(gw->bw, KEY_REDO);
+ break;
+ }
+ /* Z or Y pressed but not undo or redo;
+ * Fall through to default handling */
+
default:
ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode,
modifier);
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=10b422b16344f24bbb7...
commit 10b422b16344f24bbb766f52dc3f0d6da7fde194
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Pass KEY_UNDO and KEY_REDO to core. (Currently ignored.)
diff --git a/gtk/gui.c b/gtk/gui.c
index 226d718..d7598c3 100644
--- a/gtk/gui.c
+++ b/gtk/gui.c
@@ -1089,6 +1089,17 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
if (key->state & GDK_CONTROL_MASK)
return KEY_CUT_SELECTION;
return gdk_keyval_to_unicode(key->keyval);
+ case 'y':
+ if (key->state & GDK_CONTROL_MASK)
+ return KEY_REDO;
+ return gdk_keyval_to_unicode(key->keyval);
+ case 'z':
+ if (key->state & GDK_CONTROL_MASK &&
+ key->state & GDK_SHIFT_MASK)
+ return KEY_REDO;
+ if (key->state & GDK_CONTROL_MASK)
+ return KEY_UNDO;
+ return gdk_keyval_to_unicode(key->keyval);
case GDK_KEY(Escape):
return KEY_ESCAPE;
-----------------------------------------------------------------------
Summary of changes:
desktop/textarea.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++---
framebuffer/gui.c | 28 ++++++++
gtk/gui.c | 11 +++
3 files changed, 221 insertions(+), 11 deletions(-)
diff --git a/desktop/textarea.c b/desktop/textarea.c
index 65f0c53..8f53bf7 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -64,13 +64,19 @@ struct textarea_utf8 {
};
struct textarea_undo_detail {
- unsigned int offset; /**< Offset to detail's text in undo.text */
- unsigned int len; /**< Length of detail's text */
+ unsigned int b_start; /**< Offset to detail's text in undo buffer */
+ unsigned int b_end; /**< End of text (exclusive) */
+ unsigned int b_limit; /**< End of detail space (exclusive) */
+
+ unsigned int b_text_start; /**< Start of textarea text. */
+ unsigned int b_text_end; /**< End of textarea text (exclusive) */
};
struct textarea_undo {
- unsigned int next_detail;
- struct textarea_undo_detail *details;
+ unsigned int details_alloc; /**< Details allocated for */
+ unsigned int next_detail; /**< Next detail pos */
+ unsigned int last_detail; /**< Last detail used */
+ struct textarea_undo_detail *details; /**< Array of undo details */
struct textarea_utf8 text;
};
@@ -135,6 +141,8 @@ struct textarea {
int drag_start; /**< Byte offset of drag start (in ta->show) */
struct textarea_drag drag_info; /**< Drag information */
+
+ struct textarea_undo undo; /**< Undo/redo information */
};
@@ -1425,7 +1433,7 @@ static bool textarea_replace_text_internal(struct textarea *ta,
size_t b_start,
/* Ensure textarea's text buffer is large enough */
if (rep_len + ta->text.len - (b_end - b_start) >= ta->text.alloc) {
char *temp = realloc(ta->text.data,
- rep_len + ta->text.len - (b_end - b_start) +
+ rep_len + ta->text.len - (b_end - b_start) +
TA_ALLOC_STEP);
if (temp == NULL) {
LOG(("realloc failed"));
@@ -1474,6 +1482,74 @@ static bool textarea_replace_text_internal(struct textarea *ta,
size_t b_start,
/**
+ * Update undo buffer by adding any text to be replaced, and allocating
+ * space as appropriate.
+ *
+ * \param ta Textarea widget
+ * \param b_start Start byte index of replaced section (inclusive)
+ * \param b_end End byte index of replaced section (exclusive)
+ * \param rep_len Byte length of replacement UTF-8 text
+ * \return false on memory exhaustion, true otherwise
+ */
+static bool textarea_copy_to_undo_buffer(struct textarea *ta,
+ size_t b_start, size_t b_end, size_t rep_len)
+{
+ struct textarea_undo *undo;
+ size_t b_offset;
+ unsigned int len = b_end - b_start;
+
+ undo = &ta->undo;
+
+ if (undo->next_detail == 0)
+ b_offset = 0;
+ else
+ b_offset = undo->details[undo->next_detail - 1].b_limit;
+
+ len = len > rep_len ? len : rep_len;
+
+ if (b_offset + len >= undo->text.alloc) {
+ /* Need more memory for undo buffer */
+ char *temp = realloc(undo->text.data,
+ b_offset + len + TA_ALLOC_STEP);
+ if (temp == NULL) {
+ LOG(("realloc failed"));
+ return false;
+ }
+
+ undo->text.data = temp;
+ undo->text.alloc = b_offset + len + TA_ALLOC_STEP;
+ }
+
+ if (undo->next_detail >= undo->details_alloc) {
+ /* Need more memory for undo details */
+ struct textarea_undo_detail *temp = realloc(undo->details,
+ (undo->next_detail + 128) *
+ sizeof(struct textarea_undo_detail));
+ if (temp == NULL) {
+ LOG(("realloc failed"));
+ return false;
+ }
+
+ undo->details = temp;
+ undo->details_alloc = undo->next_detail + 128;
+ }
+
+ /* Put text into buffer */
+ memcpy(undo->text.data + b_offset, ta->text.data + b_start,
+ b_end - b_start);
+
+ /* Update next_detail */
+ undo->details[undo->next_detail].b_start = b_offset;
+ undo->details[undo->next_detail].b_end = b_offset + b_end - b_start;
+ undo->details[undo->next_detail].b_limit = len;
+
+ undo->details[undo->next_detail].b_text_start = b_start;
+
+ return true;
+}
+
+
+/**
* Replace text in a textarea, updating undo buffer.
*
* \param ta Textarea widget
@@ -1493,8 +1569,13 @@ static bool textarea_replace_text(struct textarea *ta, size_t
b_start,
size_t b_end, const char *rep, size_t rep_len,
bool add_to_clipboard, int *byte_delta, struct rect *r)
{
- /* TODO: Make copy of any replaced text */
- if (b_start != b_end) {
+ if (!(b_start != b_end && rep_len == 0 && add_to_clipboard) &&
+ !(ta->flags & TEXTAREA_PASSWORD)) {
+ /* Not just copying to clipboard, and not a password field;
+ * Sort out undo buffer. */
+ if (textarea_copy_to_undo_buffer(ta, b_start, b_end,
+ rep_len) == false)
+ return false;
}
/* Replace the text in the textarea, and reflow it */
@@ -1503,12 +1584,63 @@ static bool textarea_replace_text(struct textarea *ta, size_t
b_start,
return false;
}
- if (b_start == b_end && rep_len == 0) {
- /* Nothing changed at all */
- return true;
+ if (!(b_start != b_end && rep_len == 0 && add_to_clipboard) &&
+ !(ta->flags & TEXTAREA_PASSWORD)) {
+ /* Not just copying to clipboard, and not a password field;
+ * Update UNDO buffer */
+ ta->undo.details[ta->undo.next_detail].b_text_end =
+ b_end + *byte_delta;
+ ta->undo.last_detail = ta->undo.next_detail;
+ ta->undo.next_detail++;
}
- /* TODO: Update UNDO buffer */
+ return true;
+}
+
+
+/**
+ * Undo previous change.
+ *
+ * \param ta Textarea widget
+ * \param byte_delta Updated to change in byte count in textarea (ta->show)
+ * \param r Updated to area where redraw is required
+ * \return false if nothing to undo, true otherwise
+ */
+static bool textarea_undo(struct textarea *ta, int *byte_delta, struct rect *r)
+{
+ if (ta->flags & TEXTAREA_PASSWORD)
+ /* No undo for password fields */
+ return false;
+
+ if (ta->undo.next_detail == 0)
+ /* Nothing to undo */
+ return false;
+
+ /* TODO */
+
+ return true;
+}
+
+
+/**
+ * Redo previous undo.
+ *
+ * \param ta Textarea widget
+ * \param byte_delta Updated to change in byte count in textarea (ta->show)
+ * \param r Updated to area where redraw is required
+ * \return false if nothing to redo, true otherwise
+ */
+static bool textarea_redo(struct textarea *ta, int *byte_delta, struct rect *r)
+{
+ if (ta->flags & TEXTAREA_PASSWORD)
+ /* No REDO for password fields */
+ return false;
+
+ if (ta->undo.next_detail > ta->undo.last_detail)
+ /* Nothing to redo */
+ return false;
+
+ /* TODO */
return true;
}
@@ -1652,9 +1784,21 @@ struct textarea *textarea_create(const textarea_flags flags,
ret->scroll_y = 0;
ret->bar_x = NULL;
ret->bar_y = NULL;
+ ret->h_extent = setup->width;
+ ret->v_extent = setup->height;
ret->drag_start = 0;
ret->drag_info.type = TEXTAREA_DRAG_NONE;
+ ret->undo.details_alloc = 0;
+ ret->undo.next_detail = 0;
+ ret->undo.last_detail = 0;
+ ret->undo.details = NULL;
+
+ ret->undo.text.data = NULL;
+ ret->undo.text.alloc = 0;
+ ret->undo.text.len = 0;
+ ret->undo.text.utf8_len = 0;
+
ret->text.data = malloc(TA_ALLOC_STEP);
if (ret->text.data == NULL) {
@@ -1727,6 +1871,9 @@ void textarea_destroy(struct textarea *ta)
if (ta->flags & TEXTAREA_PASSWORD)
free(ta->password.data);
+ free(ta->undo.text.data);
+ free(ta->undo.details);
+
free(ta->text.data);
free(ta->lines);
free(ta);
@@ -2562,6 +2709,30 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
}
caret += byte_delta;
break;
+ case KEY_UNDO:
+ if (!textarea_undo(ta, &byte_delta, &r)) {
+ /* We consume the UNDO, even if we can't act
+ * on it. */
+ return true;
+ }
+ caret += byte_delta;
+ if (ta->sel_start != -1) {
+ textarea_clear_selection(ta);
+ }
+ redraw = true;
+ break;
+ case KEY_REDO:
+ if (!textarea_redo(ta, &byte_delta, &r)) {
+ /* We consume the REDO, even if we can't act
+ * on it. */
+ return true;
+ }
+ caret += byte_delta;
+ if (ta->sel_start != -1) {
+ textarea_clear_selection(ta);
+ }
+ redraw = true;
+ break;
default:
return false;
}
diff --git a/framebuffer/gui.c b/framebuffer/gui.c
index c9adf6c..6530c38 100644
--- a/framebuffer/gui.c
+++ b/framebuffer/gui.c
@@ -971,6 +971,34 @@ fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info
*cbi)
modifier |= FBTK_MOD_LCTRL;
break;
+ case NSFB_KEY_y:
+ case NSFB_KEY_z:
+ if (cbi->event->value.keycode == NSFB_KEY_z &&
+ (modifier & FBTK_MOD_RCTRL ||
+ modifier & FBTK_MOD_LCTRL) &&
+ (modifier & FBTK_MOD_RSHIFT ||
+ modifier & FBTK_MOD_LSHIFT)) {
+ /* Z pressed with CTRL and SHIFT held */
+ browser_window_key_press(gw->bw, KEY_REDO);
+ break;
+
+ } else if (cbi->event->value.keycode == NSFB_KEY_z &&
+ (modifier & FBTK_MOD_RCTRL ||
+ modifier & FBTK_MOD_LCTRL)) {
+ /* Z pressed with CTRL held */
+ browser_window_key_press(gw->bw, KEY_UNDO);
+ break;
+
+ } else if (cbi->event->value.keycode == NSFB_KEY_y &&
+ (modifier & FBTK_MOD_RCTRL ||
+ modifier & FBTK_MOD_LCTRL)) {
+ /* Y pressed with CTRL held */
+ browser_window_key_press(gw->bw, KEY_REDO);
+ break;
+ }
+ /* Z or Y pressed but not undo or redo;
+ * Fall through to default handling */
+
default:
ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode,
modifier);
diff --git a/gtk/gui.c b/gtk/gui.c
index 226d718..d7598c3 100644
--- a/gtk/gui.c
+++ b/gtk/gui.c
@@ -1089,6 +1089,17 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
if (key->state & GDK_CONTROL_MASK)
return KEY_CUT_SELECTION;
return gdk_keyval_to_unicode(key->keyval);
+ case 'y':
+ if (key->state & GDK_CONTROL_MASK)
+ return KEY_REDO;
+ return gdk_keyval_to_unicode(key->keyval);
+ case 'z':
+ if (key->state & GDK_CONTROL_MASK &&
+ key->state & GDK_SHIFT_MASK)
+ return KEY_REDO;
+ if (key->state & GDK_CONTROL_MASK)
+ return KEY_UNDO;
+ return gdk_keyval_to_unicode(key->keyval);
case GDK_KEY(Escape):
return KEY_ESCAPE;
--
NetSurf Browser