From d62646466f616b992029c92a3f6dd1ebac61d116 Mon Sep 17 00:00:00 2001 From: mitchell <70453897+667e-11@users.noreply.github.com> Date: Thu, 7 Nov 2019 12:44:46 -0500 Subject: Changed `events.TAB_CLICKED` to emit button clicked as well as modifier keys. This allows users to close buffers on middle-click for example. --- core/events.lua | 8 ++++++ core/ui.lua | 2 +- src/textadept.c | 84 +++++++++++++++++++++++++++++---------------------------- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/core/events.lua b/core/events.lua index edd7258b..768f41e0 100644 --- a/core/events.lua +++ b/core/events.lua @@ -243,9 +243,17 @@ local M = {} -- Emitted when the user clicks on a buffer tab. -- When connecting to this event, connect with an index of 1 if the handler -- needs to run before Textadept switches between buffers. +-- Note that Textadept always displays a context menu on right-click. -- Arguments: -- +-- * _`button`_: The mouse button number that was clicked, either `1` (left +-- button), `2` (middle button), `3` (right button), `4` (wheel up), or `5` +-- (wheel down). -- * _`index`_: The numeric index of the clicked tab. +-- * _`shift`_: The "Shift" modifier key is held down. +-- * _`ctrl`_: The "Control" modifier key is held down. +-- * _`alt`_: The "Alt"/"Option" modifier key is held down. +-- * _`meta`_: The "Command" modifier key on Mac OSX is held down. -- @field UPDATE_UI (string) -- Emitted after the view is visually updated. -- Arguments: diff --git a/core/ui.lua b/core/ui.lua index ae01d69f..b0cce5d7 100644 --- a/core/ui.lua +++ b/core/ui.lua @@ -278,7 +278,7 @@ events_connect(events.VIEW_NEW, function() events.emit(events.UPDATE_UI) end) -- Switches between buffers when a tab is clicked. events_connect(events.TAB_CLICKED, - function(index) view:goto_buffer(_BUFFERS[index]) end) + function(button, index) view:goto_buffer(_BUFFERS[index]) end) -- Sets the title of the Textadept window to the buffer's filename. local function set_title() diff --git a/src/textadept.c b/src/textadept.c index c7a0c1ee..7f41693a 100644 --- a/src/textadept.c +++ b/src/textadept.c @@ -1201,6 +1201,41 @@ static int lbuf_closure(lua_State *L) { lua_istable(L, 1) ? 2 : 1); } +#if GTK +/** + * Shows the context menu for a widget based on a mouse event. + * @param L The Lua state. + * @param event An optional GTK mouse button event. + * @param k The ui table field that contains the context menu. + */ +static void lL_showcontextmenu(lua_State *L, GdkEventButton *event, char *k) { + if (lua_getglobal(L, "ui") == LUA_TTABLE) { + if (lua_getfield(L, -1, k) == LUA_TLIGHTUSERDATA) { + GtkWidget *menu = (GtkWidget *)lua_touserdata(L, -1); + gtk_widget_show_all(menu); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, + event ? event->button : 0, + gdk_event_get_time((GdkEvent *)event)); + } + lua_pop(L, 1); // ui context menu field + } else lua_pop(L, 1); // non-table +} + +/** Signal for a tab label mouse click. */ +static int t_tabbuttonpress(GtkWidget *label, GdkEventButton *event, void*__) { + GtkNotebook *tabs = GTK_NOTEBOOK(tabbar); + for (int i = 0; i < gtk_notebook_get_n_pages(tabs); i++) { + GtkWidget *page = gtk_notebook_get_nth_page(tabs, i); + if (label != gtk_notebook_get_tab_label(tabs, page)) continue; + lL_event(lua, "tab_clicked", LUA_TNUMBER, event->button, LUA_TNUMBER, i + 1, + event_mod(SHIFT), event_mod(CONTROL), event_mod(MOD1), + event_mod(META), -1); + if (event->button == 3) lL_showcontextmenu(lua, event, "tab_context_menu"); + } + return TRUE; +} +#endif + /** `buffer.__index` and `buffer.__newindex` Lua metamethods. */ static int lbuf_property(lua_State *L) { int newindex = (lua_gettop(L) == 3); @@ -1259,8 +1294,13 @@ static int lbuf_property(lua_State *L) { GtkNotebook *tabs = GTK_NOTEBOOK(tabbar); GtkWidget *tab = (GtkWidget *)lua_touserdata(L, -1); lua_pushstring(L, gtk_notebook_get_tab_label_text(tabs, tab)); - if (newindex) - gtk_notebook_set_tab_label_text(tabs, tab, luaL_checkstring(L, 3)); + if (newindex) { + GtkWidget *box = gtk_event_box_new(); + GtkWidget *label = gtk_label_new(luaL_checkstring(L, 3)); + gtk_container_add(GTK_CONTAINER(box), label), gtk_widget_show(label); + gtk_notebook_set_tab_label(tabs, tab, box); + signal(box, "button-press-event", t_tabbuttonpress); + } //#elif CURSES // TODO: tabs #endif @@ -1815,44 +1855,7 @@ static void w_quit_osx(GtkosxApplication*_, void*__) { */ static void t_tabchange(GtkNotebook*_, GtkWidget*__, int page_num, void*___) { if (tab_sync) return; - lL_event(lua, "tab_clicked", LUA_TNUMBER, page_num + 1, -1); -} - -/** - * Shows the context menu for a widget based on a mouse event. - * @param L The Lua state. - * @param event An optional GTK mouse button event. - * @param k The ui table field that contains the context menu. - */ -static void lL_showcontextmenu(lua_State *L, GdkEventButton *event, char *k) { - if (lua_getglobal(L, "ui") == LUA_TTABLE) { - if (lua_getfield(L, -1, k) == LUA_TLIGHTUSERDATA) { - GtkWidget *menu = (GtkWidget *)lua_touserdata(L, -1); - gtk_widget_show_all(menu); - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, - event ? event->button : 0, - gdk_event_get_time((GdkEvent *)event)); - } - lua_pop(L, 1); // ui context menu field - } else lua_pop(L, 1); // non-table -} - -/** Signal for a tabbar mouse click. */ -static int t_tabbuttonpress(GtkWidget*_, GdkEventButton *event, void*__) { - if (event->type != GDK_BUTTON_PRESS || event->button != 3) return FALSE; - GtkNotebook *tabs = GTK_NOTEBOOK(tabbar); - for (int i = 0; i < gtk_notebook_get_n_pages(tabs); i++) { - GtkWidget *page = gtk_notebook_get_nth_page(tabs, i); - GtkWidget *label = gtk_notebook_get_tab_label(tabs, page); - int x0, y0; - gdk_window_get_origin(gtk_widget_get_window(label), &x0, &y0); - GtkAllocation allocation; - gtk_widget_get_allocation(label, &allocation); - if (event->x_root > x0 + allocation.x + allocation.width) continue; - gtk_notebook_set_current_page(tabs, i); - return (lL_showcontextmenu(lua, event, "tab_context_menu"), TRUE); - } - return FALSE; + lL_event(lua, "tab_clicked", LUA_TNUMBER, 1, LUA_TNUMBER, page_num + 1, -1); } #endif // if GTK @@ -2273,7 +2276,6 @@ static void new_window() { tabbar = gtk_notebook_new(); signal(tabbar, "switch-page", t_tabchange); - signal(tabbar, "button-press-event", t_tabbuttonpress); gtk_notebook_set_scrollable(GTK_NOTEBOOK(tabbar), TRUE); gtk_box_pack_start(GTK_BOX(vbox), tabbar, FALSE, FALSE, 0); gtk_widget_set_can_focus(tabbar, FALSE); -- cgit v1.2.3