[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/pgtk cdc04b4 010/100: Implement menubar for pgtk emacs
From: |
Yuuki Harano |
Subject: |
feature/pgtk cdc04b4 010/100: Implement menubar for pgtk emacs |
Date: |
Tue, 24 Nov 2020 08:02:26 -0500 (EST) |
branch: feature/pgtk
commit cdc04b4509772f2324c4ca63732caed2858cedf3
Author: Jeff Walsh <fejfighter@gmail.com>
Commit: Jeff Walsh <fejfighter@gmail.com>
Implement menubar for pgtk emacs
* src/xdisp.c (display_menu_bar): add pgtk case
* ../src/pgtkterm.c (pgtk_create_terminal): update hooks
(pgtk_menu_show): delete
* src/pgtkterm.h: add decls
* src/pgtkmenu.c: new file
* ../src/pgtkfns.c (x_set_menu_bar_lines)
(x_change_tool_bar_height, x_set_tool_bar_lines)
(Fx_create_frame):
---
configure.ac | 2 +-
lisp/menu-bar.el | 1 +
src/emacs.c | 1 +
src/lisp.h | 2 +-
src/menu.h | 6 +
src/pgtkfns.c | 117 +++++---------
src/pgtkmenu.c | 476 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/pgtkterm.c | 11 +-
src/pgtkterm.h | 6 +
src/xdisp.c | 5 +
10 files changed, 543 insertions(+), 84 deletions(-)
diff --git a/configure.ac b/configure.ac
index b168131..ce9d016 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2827,7 +2827,7 @@ LIBS=$OLD_LIBS
PGTK_OBJ=
PGTK_LIBS=
if test "$window_system" = "pgtk"; then
- PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o xsettings.o"
+ PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o pgtkmenu.o xsettings.o"
PGTK_LIBS="$GTK_LIBS -ldl"
AC_DEFINE([HAVE_PGTK], 1, [Define to 1 if you have pure Gtk+-3.])
fi
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index c6ced68..e1dea88 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -2506,6 +2506,7 @@ See `menu-bar-mode' for more information."
(declare-function x-menu-bar-open "term/x-win" (&optional frame))
(declare-function w32-menu-bar-open "term/w32-win" (&optional frame))
+(declare-function pgtk-menu-bar-open "term/pgtk-win" (&optional frame))
(defun lookup-key-ignore-too-long (map key)
"Call `lookup-key' and convert numeric values to nil."
diff --git a/src/emacs.c b/src/emacs.c
index 769a852..42d9373 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1921,6 +1921,7 @@ Using an Emacs configured with --with-x-toolkit=lucid
does not have this problem
syms_of_pgtkterm();
syms_of_pgtkfns();
syms_of_pgtkselect ();
+ syms_of_pgtkmenu ();
syms_of_fontset ();
syms_of_xsettings ();
syms_of_xwidget ();
diff --git a/src/lisp.h b/src/lisp.h
index 718c0f1..76d7420 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3298,7 +3298,7 @@ struct frame;
#endif
/* Define if the windowing system provides a tool-bar. */
-#if (defined (USE_GTK) && !defined(HAVE_PGTK)) || defined (HAVE_NS)
+#if defined (USE_GTK) || defined (HAVE_NS)
#define HAVE_EXT_TOOL_BAR true
#endif
diff --git a/src/menu.h b/src/menu.h
index 44749ad..baad449 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -59,6 +59,12 @@ extern Lisp_Object ns_menu_show (struct frame *, int, int,
int,
Lisp_Object, const char **);
extern void ns_activate_menubar (struct frame *);
#endif
+#ifdef HAVE_PGTK
+extern Lisp_Object pgtk_menu_show (struct frame *, int, int, int,
+ Lisp_Object, const char **);
+extern void pgtk_activate_menubar (struct frame *);
+#endif
+
extern Lisp_Object tty_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern ptrdiff_t menu_item_width (const unsigned char *);
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index ce70202..140f29a 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -465,31 +465,63 @@ pgtk_set_doc_edited (void)
static void
x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
-#if 0
int nlines;
- if (FRAME_MINIBUF_ONLY_P (f))
+ /* Right now, menu bars don't work properly in minibuf-only frames;
+ most of the commands try to apply themselves to the minibuffer
+ frame itself, and get an error because you can't switch buffers
+ in or split the minibuffer window. */
+ if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f))
return;
- if (TYPE_RANGED_INTEGERP (int, value))
+ if (TYPE_RANGED_FIXNUMP (int, value))
nlines = XFIXNUM (value);
else
nlines = 0;
+ /* Make sure we redisplay all windows in this frame. */
+ fset_redisplay (f);
+
FRAME_MENU_BAR_LINES (f) = 0;
+ FRAME_MENU_BAR_HEIGHT (f) = 0;
if (nlines)
{
FRAME_EXTERNAL_MENU_BAR (f) = 1;
- /* does for all frames, whereas we just want for one frame
- [NSMenu setMenuBarVisible: YES]; */
+ if (FRAME_PGTK_P (f) && f->output_data.pgtk->menubar_widget == 0)
+ /* Make sure next redisplay shows the menu bar. */
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
}
else
{
if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
- free_frame_menubar (f);
- /* [NSMenu setMenuBarVisible: NO]; */
+ free_frame_menubar (f);
FRAME_EXTERNAL_MENU_BAR (f) = 0;
+ if (FRAME_X_P (f))
+ f->output_data.pgtk->menubar_widget = 0;
+ }
+
+ adjust_frame_glyphs (f);
+}
+
+/* Set the pixel height of the tool bar of frame F to HEIGHT. */
+static void
+x_change_tool_bar_height (struct frame *f, int height)
+{
+ FRAME_TOOL_BAR_LINES (f) = 0;
+ FRAME_TOOL_BAR_HEIGHT (f) = 0;
+ if (height)
+ {
+ FRAME_EXTERNAL_TOOL_BAR (f) = true;
+ if (FRAME_X_P (f) && f->output_data.pgtk->toolbar_widget == 0)
+ /* Make sure next redisplay shows the tool bar. */
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
+ update_frame_tool_bar (f);
+ }
+ else
+ {
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ free_frame_tool_bar (f);
+ FRAME_EXTERNAL_TOOL_BAR (f) = false;
}
-#endif
}
@@ -497,70 +529,20 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value,
Lisp_Object oldval)
static void
x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
-#if 0
- /* Currently, when the tool bar change state, the frame is resized.
-
- TODO: It would be better if this didn't occur when 1) the frame
- is full height or maximized or 2) when specified by
- `frame-inhibit-implied-resize'. */
int nlines;
- NSTRACE ("x_set_tool_bar_lines");
-
+ /* Treat tool bars like menu bars. */
if (FRAME_MINIBUF_ONLY_P (f))
return;
- if (RANGED_INTEGERP (0, value, INT_MAX))
+ /* Use VALUE only if an int >= 0. */
+ if (RANGED_FIXNUMP (0, value, INT_MAX))
nlines = XFIXNAT (value);
else
nlines = 0;
- if (nlines)
- {
- FRAME_EXTERNAL_TOOL_BAR (f) = 1;
- update_frame_tool_bar (f);
- }
- else
- {
- if (FRAME_EXTERNAL_TOOL_BAR (f))
- {
- free_frame_tool_bar (f);
- FRAME_EXTERNAL_TOOL_BAR (f) = 0;
-
- {
- EmacsView *view = FRAME_PGTK_VIEW (f);
- int fs_state = [view fullscreenState];
-
- if (fs_state == FULLSCREEN_MAXIMIZED)
- {
- [view setFSValue:FULLSCREEN_WIDTH];
- }
- else if (fs_state == FULLSCREEN_HEIGHT)
- {
- [view setFSValue:FULLSCREEN_NONE];
- }
- }
- }
- }
+ x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
- {
- int inhibit
- = ((f->after_make_frame
- && !f->tool_bar_resized
- && (EQ (frame_inhibit_implied_resize, Qt)
- || (CONSP (frame_inhibit_implied_resize)
- && !NILP (Fmemq (Qtool_bar_lines,
- frame_inhibit_implied_resize))))
- && NILP (get_frame_param (f, Qfullscreen)))
- ? 0
- : 2);
-
- NSTRACE_MSG ("inhibit:%d", inhibit);
-
- frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
- adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
- }
-#endif
}
@@ -1327,25 +1309,14 @@ This function is an internal primitive--use
`make-frame' instead. */)
gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
NULL, NULL, RES_TYPE_BOOLEAN);
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Create the menu bar. */
if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
{
-#if 0
/* If this signals an error, we haven't set size hints for the
frame and we didn't make it visible. */
initialize_frame_menubar (f);
-#endif
-#ifndef USE_GTK
- /* This is a no-op, except under Motif where it arranges the
- main window for the widgets on it. */
- lw_set_main_areas (FRAME_X_OUTPUT(f)->column_widget,
- FRAME_X_OUTPUT(f)->menubar_widget,
- FRAME_X_OUTPUT(f)->edit_widget);
-#endif /* not USE_GTK */
}
-#endif /* USE_X_TOOLKIT || USE_GTK */
/* Consider frame official, now. */
f->can_set_window_size = true;
diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c
new file mode 100644
index 0000000..bbe47dd
--- /dev/null
+++ b/src/pgtkmenu.c
@@ -0,0 +1,476 @@
+/* Pure GTK3 menu and toolbar module.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
+
+/*
+ */
+
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "window.h"
+#include "character.h"
+#include "buffer.h"
+#include "keymap.h"
+#include "coding.h"
+#include "commands.h"
+#include "blockinput.h"
+#include "termhooks.h"
+#include "keyboard.h"
+#include "menu.h"
+#include "pdumper.h"
+
+#include "gtkutil.h"
+#include <gtk/gtk.h>
+
+
+Lisp_Object
+pgtk_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
+{
+ return Qnil;
+}
+
+
+
+/* Gtk calls callbacks just because we tell it what item should be
+ selected in a radio group. If this variable is set to a non-zero
+ value, we are creating menus and don't want callbacks right now.
+*/
+static bool xg_crazy_callback_abort;
+
+/* This callback is called from the menu bar pulldown menu
+ when the user makes a selection.
+ Figure out what the user chose
+ and put the appropriate events into the keyboard buffer. */
+static void
+menubar_selection_callback (GtkWidget *widget, gpointer client_data)
+{
+ xg_menu_item_cb_data *cb_data = client_data;
+
+ if (xg_crazy_callback_abort)
+ return;
+
+ if (! cb_data || ! cb_data->cl_data || ! cb_data->cl_data->f)
+ return;
+
+ /* For a group of radio buttons, GTK calls the selection callback first
+ for the item that was active before the selection and then for the one
that
+ is active after the selection. For C-h k this means we get the help on
+ the deselected item and then the selected item is executed. Prevent that
+ by ignoring the non-active item. */
+ if (GTK_IS_RADIO_MENU_ITEM (widget)
+ && ! gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
+ return;
+
+ /* When a menu is popped down, X generates a focus event (i.e. focus
+ goes back to the frame below the menu). Since GTK buffers events,
+ we force it out here before the menu selection event. Otherwise
+ sit-for will exit at once if the focus event follows the menu selection
+ event. */
+
+ block_input ();
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+ unblock_input ();
+
+ find_and_call_menu_selection (cb_data->cl_data->f,
+ cb_data->cl_data->menu_bar_items_used,
+ cb_data->cl_data->menu_bar_vector,
+ cb_data->call_data);
+}
+
+static void
+menu_highlight_callback (GtkWidget *widget, gpointer call_data)
+{
+ xg_menu_item_cb_data *cb_data;
+ Lisp_Object help;
+
+ cb_data = g_object_get_data (G_OBJECT (widget), XG_ITEM_DATA);
+ if (! cb_data) return;
+
+ help = call_data ? cb_data->help : Qnil;
+}
+
+
+/* This callback is invoked when a dialog or menu is finished being
+ used and has been unposted. */
+
+static void
+popup_deactivate_callback (GtkWidget *widget, gpointer client_data)
+{
+}
+
+
+
+
+/* Set the contents of the menubar widgets of frame F.
+ The argument FIRST_TIME is currently ignored;
+ it is set the first time this is called, from initialize_frame_menubar. */
+
+void
+set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
+{
+ GtkWidget * menubar_widget;
+ Lisp_Object items;
+ widget_value *wv, *first_wv, *prev_wv = 0;
+ int i;
+ int *submenu_start, *submenu_end;
+ bool *submenu_top_level_items;
+ int *submenu_n_panes;
+
+
+ menubar_widget = f->output_data.pgtk->menubar_widget;
+
+ XSETFRAME(Vmenu_updating_frame, f);
+
+ if (! menubar_widget)
+ deep_p = true;
+
+ if (deep_p)
+ {
+ struct buffer *prev = current_buffer;
+ Lisp_Object buffer;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+ int previous_menu_items_used = f->menu_bar_items_used;
+ Lisp_Object *previous_items
+ = alloca (previous_menu_items_used * sizeof *previous_items);
+ int subitems;
+
+ /* If we are making a new widget, its contents are empty,
+ do always reinitialize them. */
+ if (! menubar_widget)
+ previous_menu_items_used = 0;
+
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
+ specbind (Qinhibit_quit, Qt);
+ /* Don't let the debugger step into this code
+ because it is not reentrant. */
+ specbind (Qdebug_on_next_call, Qnil);
+
+ record_unwind_save_match_data ();
+ if (NILP (Voverriding_local_map_menu_flag))
+ {
+ specbind (Qoverriding_terminal_local_map, Qnil);
+ specbind (Qoverriding_local_map, Qnil);
+ }
+
+ set_buffer_internal_1 (XBUFFER (buffer));
+
+ /* Run the Lucid hook. */
+ safe_run_hooks (Qactivate_menubar_hook);
+
+ /* If it has changed current-menubar from previous value,
+ really recompute the menubar from the value. */
+ if (! NILP (Vlucid_menu_bar_dirty_flag))
+ call0 (Qrecompute_lucid_menubar);
+ safe_run_hooks (Qmenu_bar_update_hook);
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
+
+ items = FRAME_MENU_BAR_ITEMS (f);
+
+ /* Save the frame's previous menu bar contents data. */
+ if (previous_menu_items_used)
+ memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
+ previous_menu_items_used * word_size);
+
+ /* Fill in menu_items with the current menu bar contents.
+ This can evaluate Lisp code. */
+ save_menu_items ();
+
+ menu_items = f->menu_bar_vector;
+ menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
+ subitems = ASIZE (items) / 4;
+ submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
+ submenu_end = alloca (subitems * sizeof *submenu_end);
+ submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
+ submenu_top_level_items = alloca (subitems
+ * sizeof *submenu_top_level_items);
+ init_menu_items ();
+ for (i = 0; i < subitems; i++)
+ {
+ Lisp_Object key, string, maps;
+
+ key = AREF (items, 4 * i);
+ string = AREF (items, 4 * i + 1);
+ maps = AREF (items, 4 * i + 2);
+ if (NILP (string))
+ break;
+
+ submenu_start[i] = menu_items_used;
+
+ menu_items_n_panes = 0;
+ submenu_top_level_items[i]
+ = parse_single_submenu (key, string, maps);
+ submenu_n_panes[i] = menu_items_n_panes;
+
+ submenu_end[i] = menu_items_used;
+ }
+
+ submenu_start[i] = -1;
+ finish_menu_items ();
+
+ /* Convert menu_items into widget_value trees
+ to display the menu. This cannot evaluate Lisp code. */
+
+ wv = make_widget_value ("menubar", NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ first_wv = wv;
+
+ for (i = 0; submenu_start[i] >= 0; i++)
+ {
+ menu_items_n_panes = submenu_n_panes[i];
+ wv = digest_single_submenu (submenu_start[i], submenu_end[i],
+ submenu_top_level_items[i]);
+ if (prev_wv)
+ prev_wv->next = wv;
+ else
+ first_wv->contents = wv;
+ /* Don't set wv->name here; GC during the loop might relocate it. */
+ wv->enabled = true;
+ wv->button_type = BUTTON_TYPE_NONE;
+ prev_wv = wv;
+ }
+
+ set_buffer_internal_1 (prev);
+
+ /* If there has been no change in the Lisp-level contents
+ of the menu bar, skip redisplaying it. Just exit. */
+
+ /* Compare the new menu items with the ones computed last time. */
+ for (i = 0; i < previous_menu_items_used; i++)
+ if (menu_items_used == i
+ || (!EQ (previous_items[i], AREF (menu_items, i))))
+ break;
+ if (i == menu_items_used && i == previous_menu_items_used && i != 0)
+ {
+ /* The menu items have not changed. Don't bother updating
+ the menus in any form, since it would be a no-op. */
+ free_menubar_widget_value_tree (first_wv);
+ discard_menu_items ();
+ unbind_to (specpdl_count, Qnil);
+ return;
+ }
+
+ /* The menu items are different, so store them in the frame. */
+ fset_menu_bar_vector (f, menu_items);
+ f->menu_bar_items_used = menu_items_used;
+
+ /* This undoes save_menu_items. */
+ unbind_to (specpdl_count, Qnil);
+
+ /* Now GC cannot happen during the lifetime of the widget_value,
+ so it's safe to store data from a Lisp_String. */
+ wv = first_wv->contents;
+ for (i = 0; i < ASIZE (items); i += 4)
+ {
+ Lisp_Object string;
+ string = AREF (items, i + 1);
+ if (NILP (string))
+ break;
+ wv->name = SSDATA (string);
+ update_submenu_strings (wv->contents);
+ wv = wv->next;
+ }
+
+ }
+ else
+ {
+ /* Make a widget-value tree containing
+ just the top level menu bar strings. */
+
+ wv = make_widget_value ("menubar", NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ first_wv = wv;
+
+ items = FRAME_MENU_BAR_ITEMS (f);
+ for (i = 0; i < ASIZE (items); i += 4)
+ {
+ Lisp_Object string;
+
+ string = AREF (items, i + 1);
+ if (NILP (string))
+ break;
+
+ wv = make_widget_value (SSDATA (string), NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ /* This prevents lwlib from assuming this
+ menu item is really supposed to be empty. */
+ /* The intptr_t cast avoids a warning.
+ This value just has to be different from small integers. */
+ wv->call_data = (void *) (intptr_t) (-1);
+
+ if (prev_wv)
+ prev_wv->next = wv;
+ else
+ first_wv->contents = wv;
+ prev_wv = wv;
+ }
+
+ /* Forget what we thought we knew about what is in the
+ detailed contents of the menu bar menus.
+ Changing the top level always destroys the contents. */
+ f->menu_bar_items_used = 0;
+ }
+
+ block_input();
+
+ xg_crazy_callback_abort = true;
+ if (menubar_widget)
+ {
+ /* The fourth arg is DEEP_P, which says to consider the entire
+ menu trees we supply, rather than just the menu bar item names. */
+ xg_modify_menubar_widgets (menubar_widget,
+ f,
+ first_wv,
+ deep_p,
+ G_CALLBACK (menubar_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+ }
+ else
+ {
+ menubar_widget
+ = xg_create_widget ("menubar", "menubar", f, first_wv,
+ G_CALLBACK (menubar_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+
+ f->output_data.pgtk->menubar_widget = menubar_widget;
+ }
+
+ free_menubar_widget_value_tree (first_wv);
+ xg_update_frame_menubar (f);
+
+ xg_crazy_callback_abort = false;
+
+ unblock_input ();
+}
+
+
+
+/* Called from Fx_create_frame to create the initial menubar of a frame
+ before it is mapped, so that the window is mapped with the menubar already
+ there instead of us tacking it on later and thrashing the window after it
+ is visible. */
+
+void
+initialize_frame_menubar (struct frame *f)
+{
+ /* This function is called before the first chance to redisplay
+ the frame. It has to be, so the frame will have the right size. */
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
+ set_frame_menubar (f, true, true);
+}
+
+
+void pgtk_activate_menubar (struct frame *f)
+{
+ set_frame_menubar(f, false, false);
+
+ /* f->output_data.pgtk->menubar_active = 1; */
+}
+
+
+Lisp_Object
+pgtk_menu_show (struct frame *f, int x, int y, int menuflags,
+ Lisp_Object title, const char **error_name)
+{
+ Lisp_Object tem;
+
+ block_input ();
+
+
+ unblock_input ();
+
+ // not implemented.
+ return Qnil;
+}
+
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal,
Sx_menu_bar_open_internal, 0, 1, "i",
+ doc: /* Start key navigation of the menu bar in FRAME.
+This initially opens the first menu bar item and you can then navigate with the
+arrow keys, select a menu entry with the return key or cancel with the
+escape key. If FRAME has no menu bar this function does nothing.
+
+If FRAME is nil or not given, use the selected frame. */)
+ (Lisp_Object frame)
+{
+ GtkWidget *menubar;
+ struct frame *f;
+
+ block_input ();
+ f = decode_window_system_frame (frame);
+
+ if (FRAME_EXTERNAL_MENU_BAR (f))
+ set_frame_menubar (f, false, true);
+
+ menubar = FRAME_X_OUTPUT (f)->menubar_widget;
+ if (menubar)
+ {
+ /* Activate the first menu. */
+ GList *children = gtk_container_get_children (GTK_CONTAINER (menubar));
+
+ if (children)
+ {
+ g_signal_emit_by_name (children->data, "activate_item");
+ g_list_free (children);
+ }
+ }
+ unblock_input ();
+
+ return Qnil;
+}
+
+
+static const char * button_names [] = {
+ "button1", "button2", "button3", "button4", "button5",
+ "button6", "button7", "button8", "button9", "button10" };
+
+extern Lisp_Object
+pgtk_dialog_show (struct frame *f, Lisp_Object title,
+ Lisp_Object header, char **error)
+{
+ return Qnil;
+}
+
+/* The following is used by delayed window autoselection. */
+
+DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p,
Smenu_or_popup_active_p, 0, 0, 0,
+ doc: /* SKIP: real doc in xmenu.c. */)
+ (void)
+{
+ struct frame *f;
+ f = SELECTED_FRAME ();
+ // return (f->output_data.pgtk->menubar_active > 0) ? Qt : Qnil;
+ return Qnil;
+}
+
+void
+syms_of_pgtkmenu (void)
+{
+ // current_popup_menu = NULL;
+ // PDUMPER_IGNORE (current_popup_menu);
+
+ DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
+ DEFSYM (Qunsupported__w32_dialog, "unsupported--w32-dialog");
+
+ defsubr (&Smenu_or_popup_active_p);
+}
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index a380c11..ed8d7e8 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -4253,14 +4253,6 @@ pgtk_fullscreen_hook (struct frame *f)
}
}
-static Lisp_Object
-pgtk_menu_show (struct frame *f, int x, int y, int menuflags,
- Lisp_Object title, const char **error_name)
-{
- // not implemented.
- return Qnil;
-}
-
/* This function is called when the last frame on a display is deleted. */
void
pgtk_delete_terminal (struct terminal *terminal)
@@ -4332,7 +4324,8 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
// terminal->frame_raise_lower_hook = pgtk_frame_raise_lower;
terminal->fullscreen_hook = pgtk_fullscreen_hook;
terminal->menu_show_hook = pgtk_menu_show;
- // terminal->popup_dialog_hook = pgtk_popup_dialog;
+ terminal->activate_menubar_hook = pgtk_activate_menubar;
+ terminal->popup_dialog_hook = pgtk_popup_dialog;
terminal->set_vertical_scroll_bar_hook = pgtk_set_vertical_scroll_bar;
terminal->set_horizontal_scroll_bar_hook = pgtk_set_horizontal_scroll_bar;
terminal->condemn_scroll_bars_hook = pgtk_condemn_scroll_bars;
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index d14525e..10dc9fc 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -548,6 +548,12 @@ extern void pgtk_set_cr_source_with_color (struct frame
*f, unsigned long color)
extern void pgtk_cr_draw_frame (cairo_t *cr, struct frame *f);
extern void pgtk_cr_destroy_surface(struct frame *f);
+/* Defined in pgtkmenu.c */
+extern Lisp_Object pgtk_popup_dialog (struct frame *f, Lisp_Object header,
Lisp_Object contents);
+extern Lisp_Object pgtk_dialog_show (struct frame *f, Lisp_Object title,
Lisp_Object header, char **error);
+extern void initialize_frame_menubar (struct frame *);
+
+
/* Symbol initializations implemented in each pgtk sources. */
extern void syms_of_pgtkterm (void);
extern void syms_of_pgtkfns (void);
diff --git a/src/xdisp.c b/src/xdisp.c
index e722a75..c523111 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25028,6 +25028,11 @@ display_menu_bar (struct window *w)
if (FRAME_W32_P (f))
return;
#endif
+#if defined (HAVE_PGTK)
+ if (FRAME_PGTK_P (f))
+ return;
+#endif
+
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (FRAME_X_P (f))
return;
- feature/pgtk f761a09 065/100: * src/pgtkim.c: Change coding style, (continued)
- feature/pgtk f761a09 065/100: * src/pgtkim.c: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk 27a92f7 072/100: Add font chooser functionality, Yuuki Harano, 2020/11/24
- feature/pgtk 9752896 042/100: Bring pgtk more inline with X11-cairo builds, Yuuki Harano, 2020/11/24
- feature/pgtk 164800d 013/100: Add Preferred geometry settings, Yuuki Harano, 2020/11/24
- feature/pgtk 383ced7 071/100: Fix migrating Child frames, Yuuki Harano, 2020/11/24
- feature/pgtk 3b161dd 066/100: * src/pgtkselect.h: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk 89cbe37 070/100: * src/keyboard.c (make_lispy_event): Fix coding style, Yuuki Harano, 2020/11/24
- feature/pgtk f6d8c59 001/100: Introduce Pure GTK3 port, Yuuki Harano, 2020/11/24
- feature/pgtk a9c8a56 006/100: Fix xdg-open handling, Yuuki Harano, 2020/11/24
- feature/pgtk ed1f7d1 008/100: Simplify compilaiton condtion, Yuuki Harano, 2020/11/24
- feature/pgtk cdc04b4 010/100: Implement menubar for pgtk emacs,
Yuuki Harano <=
- feature/pgtk 85441c9 016/100: Add Stipple support for PGTK, Yuuki Harano, 2020/11/24
- feature/pgtk bfbcb11 026/100: implement set-tool-bar-position and set-sticky, Yuuki Harano, 2020/11/24
- feature/pgtk af5b725 061/100: * src/pgtkmenu.c: change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk e649275 058/100: * src/pgtkterm.c: change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk de7b0da 049/100: use pgtk_menu_set_in_use., Yuuki Harano, 2020/11/24
- feature/pgtk af1e279 073/100: Restore support for terminal only emacs in PGTK (add --with-pgtk), Yuuki Harano, 2020/11/24
- feature/pgtk 8669feb 054/100: Make icons and titles work like on X, Yuuki Harano, 2020/11/24
- feature/pgtk 20dbd4e 069/100: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk 9e56fa9 034/100: Support focus on click event, Yuuki Harano, 2020/11/24
- feature/pgtk 385e85c 038/100: End Resize flickering by copying surface rather than just clearing, Yuuki Harano, 2020/11/24