commit 1146213bf1660a36ffc9269f938602905847d554
parent 7ce0fd78813ad0ebd4292b7dd471528f09417d35
Author: lumidify <nobody@lumidify.org>
Date: Thu, 2 Dec 2021 22:56:26 +0100
Add documentation for window
Diffstat:
M | ledit.c | | | 1 | + |
M | window.c | | | 40 | +++++++++++++++++++++++++++++++++------- |
M | window.h | | | 242 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
3 files changed, 256 insertions(+), 27 deletions(-)
diff --git a/ledit.c b/ledit.c
@@ -1,3 +1,4 @@
+/* FIXME: Add special assert that dumps currently edited file to backup on error */
/* FIXME: On large files, expose event takes a long time for some reason
-> but somehow only sometimes... */
/* FIXME: generally optimize redrawing */
diff --git a/window.c b/window.c
@@ -25,33 +25,59 @@
/* FIXME: Everything to do with the bottom bar is extremely hacky */
struct bottom_bar {
/* FIXME: encapsulate layout, width, draw a bit */
+ /* text display of mode and possible some further text */
PangoLayout *mode;
ledit_draw *mode_draw;
int mode_w, mode_h;
- PangoLayout *ruler; /* not implemented yet */
+
+ /* line and position display (not implemented yet - FIXME) */
+ PangoLayout *ruler;
ledit_draw *ruler_draw;
int ruler_w, ruler_h;
+
+ /* message or editable text display */
PangoLayout *line;
ledit_draw *line_draw;
int line_w, line_h;
char *line_text;
int line_alloc, line_len;
- int line_cur_pos;
- int min_pos; /* minimum position cursor can be at */
+ int line_cur_pos; /* current position of cursor */
+ int min_pos; /* minimum position cursor can be at */
};
/* clipboard handling largely stolen from st (simple terminal) */
#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
+/* FIXME: maybe move this to the window struct just in case any
+ conflicts happen */
+/* FIXME: the paste handling is a bit weird because the text can come
+ in several chunks - can this cause issues in certain cases? */
struct {
txtbuf *primary;
char *clipboard;
} xsel = {NULL, NULL};
+/*
+ * Recalculate the size of the actual text area (which is managed by the view).
+ */
static void recalc_text_size(ledit_window *window);
+
+/*
+ * Get the position and height for the scrollbar handle.
+ * 'height_ret' is set to the height (in pixels) of the scrollbar handle.
+ * 'pos_ret' is set to the y position (in pixels) of the top of the scrollbar handle.
+ */
static void get_scroll_pos_height(ledit_window *windown, double *pos, double *height);
+
+/*
+ * Set the scroll offset.
+ * 'pos' is the pixel position of the top of the scrollbar handle.
+ * This performs sanity checks and calls the scroll callback if set.
+ */
static void set_scroll_pos(ledit_window *window, double pos);
+
+/* event handling for clipboard events */
static void clipboard_propnotify(ledit_window *window, XEvent *e);
static void clipboard_selnotify(ledit_window *window, XEvent *e);
static void clipboard_selrequest(ledit_window *window, XEvent *e);
@@ -291,10 +317,10 @@ window_set_mode_extra_text(ledit_window *window, char *text) {
/* FIXME: give these functions more sensible names */
static void
-get_scroll_pos_height(ledit_window *window, double *pos, double *height) {
- *height = ((double)window->text_h / window->scroll_max) * window->text_h;
- *pos = (window->scroll_offset /
- (window->scroll_max - window->text_h)) * (window->text_h - *height);
+get_scroll_pos_height(ledit_window *window, double *pos_ret, double *height_ret) {
+ *height_ret = ((double)window->text_h / window->scroll_max) * window->text_h;
+ *pos_ret = (window->scroll_offset /
+ (window->scroll_max - window->text_h)) * (window->text_h - *height_ret);
}
static void
diff --git a/window.h b/window.h
@@ -1,33 +1,45 @@
+/*
+ * A window is associated with exactly one view and is responsible everything
+ * other than the actual text handling (of the text in the buffer).
+ * It's a bit ugly right now because the line editor for commands is implemented
+ * partially here and partially in keys_command, but that's the way it is for now.
+ */
+
typedef struct bottom_bar bottom_bar;
typedef struct {
+ /* Pango stuff */
/* FIXME: maybe move to common? */
PangoFontMap *fontmap;
PangoContext *context;
PangoFontDescription *font;
+
+ /* X stuff */
GC gc;
Window xwin;
- XdbeBackBuffer back_buf;
- Drawable drawable;
- int w;
- int h;
- int text_w;
- int text_h;
- int scroll_dragging;
- int scroll_grab_handle;
- long scroll_max;
- double scroll_offset; /* double for smoother scrolling */
- int bottom_text_shown;
- int message_shown;
+ XdbeBackBuffer back_buf; /* the back buffer for double buffering */
+ Drawable drawable; /* the actual drawable to draw to */
+ /* this is currently always the same as back_buf,
+ but that might be changed at some point */
XSetWindowAttributes wattrs;
- Atom wm_delete_msg;
- Atom xtarget;
- bottom_bar *bb;
- int bb_msg_shown;
- int redraw;
- enum ledit_mode mode; /* a bit ugly to duplicate this here... */
-
- /* filtered events */
+ Atom wm_delete_msg; /* used to check when window is closed */
+ Atom xtarget; /* used for clipboard handling */
+
+ int w; /* width of window */
+ int h; /* height of window */
+ int text_w; /* width of the text part of the window */
+ int text_h; /* height of the text part of the window */
+ int scroll_dragging; /* whether scrollbar is being dragged with mouse */
+ int scroll_grab_handle; /* the y position where the mouse was was while dragging the scrollbar */
+ long scroll_max; /* total pixel height of displayed text */
+ double scroll_offset; /* double for smoother scrolling */
+ int bottom_text_shown; /* whether editable text is shown at the bottom */
+ int message_shown; /* whether a readonly message is shown at the bottom */
+ bottom_bar *bb; /* encapsulates the text at the bottom */
+ int redraw; /* whether something has changed and the window has to be redrawn */
+ enum ledit_mode mode; /* mode of the view - a bit ugly to duplicate this here... */
+
+ /* stuff for filtering events so not too many have to be handled */
struct timespec last_scroll;
struct timespec last_motion;
struct timespec last_resize;
@@ -48,6 +60,8 @@ typedef struct {
ledit_common *common;
ledit_theme *theme;
+
+ /* various callbacks */
void (*paste_callback)(void *, char *, size_t);
void (*scroll_callback)(void *, long);
void (*button_callback)(void *, XEvent *);
@@ -56,56 +70,244 @@ typedef struct {
void *scroll_cb_data;
void *button_cb_data;
void *resize_cb_data;
+
+ /* extra text shown beside the mode display at the bottom */
char *mode_extra_text;
} ledit_window;
+/*
+ * Create a window with initial mode 'mode'.
+ */
ledit_window *window_create(ledit_common *common, ledit_theme *theme, enum ledit_mode mode);
+
+/*
+ * Destroy a window.
+ */
void window_destroy(ledit_window *window);
+
+/*
+ * Clean up global data.
+ */
void window_cleanup(void);
/* FIXME: this is a bit confusing because there's a difference between editable
text shown and non-editable message shown */
+
+/*
+ * Move the cursor of the editable text at the bottom movement cursor positions.
+ * Negative movement means to the left, positive movement to the right.
+ */
void window_move_bottom_bar_cursor(ledit_window *window, int movement);
+
+/*
+ * Delete a unicode character from he editable text.
+ * Negative dir means to the left of the cursor, positive to the right.
+ */
void window_delete_bottom_bar_char(ledit_window *window, int dir);
+
+/*
+ * Move the cursor of the editable text to position 0.
+ */
void window_bottom_bar_cursor_to_beginning(ledit_window *window);
+
+/*
+ * Move the cursor of the editable text to the end of the line.
+ */
void window_bottom_bar_cursor_to_end(ledit_window *window);
+
+/*
+ * Set the minimum byte position of the cursor of the editable text to 'pos'.
+ * This means that the cursor will not be allowed to go further left
+ * than that position (used e.g. for the ':' in commands).
+ */
void window_set_bottom_bar_min_pos(ledit_window *window, int pos);
+
+/*
+ * Set whether the editable text is shown.
+ */
void window_set_bottom_bar_text_shown(ledit_window *window, int shown);
+
+/*
+ * get whether the editable text is shown.
+ */
int ledit_window_bottom_bar_text_shown(ledit_window *window);
+
+/*
+ * Set the byte position of the editable text cursor to 'byte_pos'.
+ */
void window_set_bottom_bar_cursor(ledit_window *window, int byte_pos);
+
+/*
+ * Get the byte position of the editable text cursor.
+ */
int ledit_window_get_bottom_bar_cursor(ledit_window *window);
+
+/*
+ * Insert 'len' bytes of text into the editable line at the cursor position.
+ */
void window_insert_bottom_bar_text(ledit_window *window, char *text, int len);
+
+/*
+ * Set the text of the editable line.
+ */
void window_set_bottom_bar_text(ledit_window *window, char *text, int len);
+
+/*
+ * Get the text of the editable line.
+ */
char *window_get_bottom_bar_text(ledit_window *window);
+
+/*
+ * Show a non-editable message at the bottom.
+ */
void window_show_message(ledit_window *window, char *text, int len);
+
+/*
+ * Hide the non-editable message.
+ */
void window_hide_message(ledit_window *window);
+
+/*
+ * Get whether a non-editable message is shown.
+ */
int window_message_shown(ledit_window *window);
+
+/*
+ * Set the displayed mode of the window.
+ */
void window_set_mode(ledit_window *window, enum ledit_mode mode);
+
+/*
+ * Set extra text that is shown to the right of the mode.
+ */
void window_set_mode_extra_text(ledit_window *window, char *text);
+/*
+ * Set the total pixel height of the text.
+ */
void window_set_scroll_max(ledit_window *window, long max);
+
+/*
+ * Set the scroll position of the window.
+ * This is in absolute pixels from the top of the text.
+ */
void window_set_scroll_pos(ledit_window *window, long pos);
+
+/*
+ * Set a callback that will be called when the user scrolls.
+ * The callback is called with 'data' as the first argument and
+ * the scroll offset as the second argument.
+ */
void window_set_scroll_callback(ledit_window *window, void (*cb)(void *, long), void *data);
+
+/*
+ * Set a callback that is called with text from the clipboard/primary
+ * selection when it becomes available after 'clipboard_paste_clipboard'
+ * or 'clipboard_paste_primary' is called.
+ * The callback is called with 'data', the text, and the length of the text.
+ */
void window_set_paste_callback(ledit_window *window, void (*cb)(void *, char *, size_t), void *data);
+
+/*
+ * Set a callback that is called when Button1 is clicked or released
+ * in the text area.
+ */
void window_set_button_callback(ledit_window *window, void (*cb)(void *, XEvent *), void *data);
+
+/*
+ * Set a callback that is called when the window is resized.
+ */
void window_set_resize_callback(ledit_window *window, void (*cb)(void *), void *data);
+
+/*
+ * The following three functions are used to register events that
+ * need to be filtered in order to avoid processing too many events
+ * (which leads to lagging).
+ */
void window_register_resize(ledit_window *window, XEvent *event);
void window_register_button_press(ledit_window *window, XEvent *event);
void window_register_motion(ledit_window *window, XEvent *event);
+
+/*
+ * Check if any of the previously registered events should be handled
+ * now. This should be called every frame to check if processin is
+ * necessary.
+ */
void window_handle_filtered_events(ledit_window *window);
+/*
+ * Clear the window.
+ */
void window_clear(ledit_window *window);
+
+/*
+ * Redraw the window.
+ * This only redraws the parts mANAGED BY THE window.
+ * The text area needs to be redrawn separately.
+ */
void window_redraw(ledit_window *window);
+
+/*
+ * Resize the window and call the resize callback if set.
+ */
void window_resize(ledit_window *window, int w, int h);
+
+/*
+ * Get the size of the actual text area (everything other than the
+ * scrollbar and the line at the bottom).
+ */
void window_get_textview_size(ledit_window *window, int *w_ret, int *h_ret);
+/*
+ * Move the X primary selection the the clipboard.
+ */
void clipboard_primary_to_clipboard(ledit_window *window);
+
+/*
+ * Paste the X clipboard. The text is handed to the paste callback
+ * when it becomes available.
+ */
void clipboard_paste_clipboard(ledit_window *window);
+
+/*
+ * Paste the X primary selection. The text is handed to the paste
+ * callback when it becomes available.
+ */
void clipboard_paste_primary(ledit_window *window);
+
+/*
+ * Get the buffer used to store the text of the primary selection.
+ * This is sort of hacky because the view uses it to write the
+ * selection directly to this buffer and then set the selection
+ * owner. That should probably be changed at some point.
+ */
txtbuf *window_get_primary_clipboard_buffer(void);
+/*
+ * Handle a button press.
+ * This does not filter events like the register function!
+ */
void window_button_press(ledit_window *window, XEvent *event, int scroll_num);
+
+/*
+ * Handle a button release.
+ */
void window_button_release(ledit_window *window, XEvent *event);
+
+/*
+ * Handle a button motion event.
+ * This does not filter events like the register function!
+ */
void window_drag_motion(ledit_window *window, XEvent *event);
+
+/*
+ * Handle a clipboard event (SelectionRequest, {Selection,Property}Notify).
+ */
void window_clipboard_event(ledit_window *window, XEvent *event);
+
+/*
+ * Set the pixel position of the input method context.
+ * This is used by some input method editors to show an editor at
+ * the position that text is being inserted at.
+ */
void xximspot(ledit_window *window, int x, int y);